authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-03-10 22:06:05+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-03-10 22:06:05+01:00
log3edaef9e011ac500f66c9ee0ba3ea24be905bcde
treecc2ececf026f2098b375267bb07a342d4b83212f
parentb80abf0296de5034ddaf149074fe7de18347bc20
parent502cab9ae30b001a8da2f724711330a73e7e2e4f

Merge pull request 'compiler: rework type resolution' (#31403) from lets-get-typing into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31403

272 files changed, 26992 insertions(+), 33526 deletions(-)

CMakeLists.txt+12-4
......@@ -330,7 +330,6 @@ set(ZIG_STAGE2_SOURCES
330330 src/Air/Liveness.zig
331331 src/Air/Liveness/Verify.zig
332332 src/Air/print.zig
333 src/Air/types_resolved.zig
334333 src/Builtin.zig
335334 src/Compilation.zig
336335 src/Compilation/Config.zig
......@@ -344,6 +343,7 @@ set(ZIG_STAGE2_SOURCES
344343 src/Sema.zig
345344 src/Sema/bitcast.zig
346345 src/Sema/comptime_ptr_access.zig
346 src/Sema/type_resolution.zig
347347 src/Type.zig
348348 src/Value.zig
349349 src/Zcu.zig
......@@ -360,7 +360,8 @@ set(ZIG_STAGE2_SOURCES
360360 src/codegen/aarch64/Mir.zig
361361 src/codegen/aarch64/Select.zig
362362 src/codegen/c.zig
363 src/codegen/c/Type.zig
363 src/codegen/c/type.zig
364 src/codegen/c/type/render_defs.zig
364365 src/codegen/llvm.zig
365366 src/codegen/llvm/bindings.zig
366367 src/crash_report.zig
......@@ -375,6 +376,7 @@ set(ZIG_STAGE2_SOURCES
375376 src/libs/libunwind.zig
376377 src/link.zig
377378 src/link/C.zig
379 src/link/ConstPool.zig
378380 src/link/Coff.zig
379381 src/link/Dwarf.zig
380382 src/link/Elf.zig
......@@ -606,8 +608,8 @@ if(MSVC)
606608 set(ZIG2_LINK_FLAGS "/STACK:16777216 /FORCE:MULTIPLE")
607609else()
608610 set(ZIG_WASM2C_COMPILE_FLAGS "-std=c99 -O2")
609 set(ZIG1_COMPILE_FLAGS "-std=c99 -Os")
610 set(ZIG2_COMPILE_FLAGS "-std=c99 -O0 -fno-sanitize=undefined -fno-stack-protector")
611 set(ZIG1_COMPILE_FLAGS "-std=c99 -Os -fno-strict-aliasing")
612 set(ZIG2_COMPILE_FLAGS "-std=c99 -O0 -fno-sanitize=undefined -fno-stack-protector -fno-strict-aliasing")
611613 # Must match the condition in build.zig.
612614 if(ZIG_HOST_TARGET_ARCH MATCHES "^(arm|thumb)(eb)?$" OR ZIG_HOST_TARGET_ARCH MATCHES "^powerpc(64)?(le)?$")
613615 set(ZIG1_COMPILE_FLAGS "${ZIG1_COMPILE_FLAGS} -ffunction-sections -fdata-sections")
......@@ -623,6 +625,12 @@ else()
623625 else()
624626 set(ZIG2_LINK_FLAGS "-Wl,-z,stack-size=0x10000000")
625627 endif()
628 # Prevent GCC from miscompiling 'zig2.c'. See also 'workaround_gcc_sra_miscomp' in 'bootstrap.c'.
629 if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND
630 CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "13.0" AND
631 CMAKE_C_COMPILER_VERSION VERSION_LESS_EQUAL "15.2")
632 set(ZIG2_COMPILE_FLAGS "${ZIG2_COMPILE_FLAGS} -fno-tree-sra")
633 endif()
626634endif()
627635
628636set(ZIG1_WASM_MODULE "${PROJECT_SOURCE_DIR}/stage1/zig1.wasm")
bootstrap.c+23-1
......@@ -102,6 +102,26 @@ int main(int argc, char **argv) {
102102 const char *cc = get_c_compiler();
103103 const char *host_triple = get_host_triple();
104104
105 // GCC versions 13.0--14.1 have a miscompilation where some bytes of a union may get clobbered
106 // depending on the union layout and the order in which types are defined. This miscompilation
107 // affects the output of the C backend, and thus can affect the bootstrap process. Specifically,
108 // we observe that using the self-hosted x86_64 backend in 'zig2' will cause all function calls
109 // to be relocated incorrectly, causing immediate crashes on any binary produced by it.
110 //
111 // The only reliable workaround for this bug is to disable the optimization pass containing it,
112 // so here we check for a CLI flag requesting that workaround.
113 //
114 // The upstream bug is fixed in GCC version 15.2 onwards (and was also backported to the 13 and
115 // 14 branches). Once this bug is no longer widespread, we can remove this CLI flag.
116 //
117 // Upstream bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119085
118 bool workaround_gcc_sra_miscomp = false;
119 for (int i = 1; i < argc; ++i) {
120 if (!strcmp(argv[i], "--workaround-gcc-sra-miscomp")) {
121 workaround_gcc_sra_miscomp = true;
122 }
123 }
124
105125 {
106126 const char *child_argv[] = {
107127 cc, "-o", "zig-wasm2c", "stage1/wasm2c.c", "-O2", "-std=c99", NULL,
......@@ -116,7 +136,7 @@ int main(int argc, char **argv) {
116136 }
117137 {
118138 const char *child_argv[] = {
119 cc, "-o", "zig1", "zig1.c", "stage1/wasi.c", "-std=c99", "-Os", "-lm", NULL,
139 cc, "-o", "zig1", "zig1.c", "stage1/wasi.c", "-std=c99", "-Os", "-fno-strict-aliasing", "-lm", NULL,
120140 };
121141 print_and_run(child_argv);
122142 }
......@@ -193,6 +213,8 @@ int main(int argc, char **argv) {
193213#if defined(__GNUC__)
194214 "-pthread",
195215#endif
216 "-fno-strict-aliasing",
217 workaround_gcc_sra_miscomp ? "-fno-tree-sra" : NULL,
196218 NULL,
197219 };
198220 print_and_run(child_argv);
build.zig+4-4
......@@ -568,7 +568,7 @@ pub fn build(b: *std.Build) !void {
568568 .skip_linux = skip_linux,
569569 .skip_llvm = skip_llvm,
570570 .skip_libc = skip_libc,
571 .max_rss = 8_500_000_000,
571 .max_rss = 9_300_000_000,
572572 }));
573573
574574 const unit_tests_step = b.step("test-unit", "Run the compiler source unit tests");
......@@ -584,7 +584,7 @@ pub fn build(b: *std.Build) !void {
584584 .use_llvm = use_llvm,
585585 .use_lld = use_llvm,
586586 .zig_lib_dir = b.path("lib"),
587 .max_rss = 2_500_000_000,
587 .max_rss = 2_700_000_000,
588588 });
589589 if (link_libc) {
590590 unit_tests.root_module.link_libc = true;
......@@ -611,7 +611,7 @@ pub fn build(b: *std.Build) !void {
611611 .skip_linux = skip_linux,
612612 .skip_llvm = skip_llvm,
613613 .skip_release = skip_release,
614 .max_rss = 3_000_000_000,
614 .max_rss = 3_300_000_000,
615615 }));
616616 test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, enable_ios_sdk, enable_symlinks_windows));
617617 test_step.dependOn(tests.addStackTraceTests(b, test_filters, skip_non_native));
......@@ -767,7 +767,7 @@ fn addCompilerMod(b: *std.Build, options: AddCompilerModOptions) *std.Build.Modu
767767fn addCompilerStep(b: *std.Build, options: AddCompilerModOptions) *std.Build.Step.Compile {
768768 const exe = b.addExecutable(.{
769769 .name = "zig",
770 .max_rss = 7_900_000_000,
770 .max_rss = 8_700_000_000,
771771 .root_module = addCompilerMod(b, options),
772772 });
773773 exe.stack_size = stack_size;
ci/aarch64-freebsd-debug.sh-1
......@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \
4747 --maxrss ${ZSF_MAX_RSS:-0} \
4848 -Dstatic-llvm \
4949 -Dskip-non-native \
50 -Dskip-test-incremental \
5150 --search-prefix "$PREFIX" \
5251 --zig-lib-dir "$PWD/../lib" \
5352 --test-timeout 2m
ci/aarch64-freebsd-release.sh-1
......@@ -47,7 +47,6 @@ stage3-release/bin/zig build test docs \
4747 --maxrss ${ZSF_MAX_RSS:-0} \
4848 -Dstatic-llvm \
4949 -Dskip-non-native \
50 -Dskip-test-incremental \
5150 --search-prefix "$PREFIX" \
5251 --zig-lib-dir "$PWD/../lib" \
5352 --test-timeout 2m
ci/aarch64-linux-debug.sh-1
......@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \
4747 --maxrss ${ZSF_MAX_RSS:-0} \
4848 -Dstatic-llvm \
4949 -Dskip-non-native \
50 -Dskip-test-incremental \
5150 -Dtarget=native-native-musl \
5251 --search-prefix "$PREFIX" \
5352 --zig-lib-dir "$PWD/../lib" \
ci/aarch64-linux-release.sh-1
......@@ -47,7 +47,6 @@ stage3-release/bin/zig build test docs \
4747 --maxrss ${ZSF_MAX_RSS:-0} \
4848 -Dstatic-llvm \
4949 -Dskip-non-native \
50 -Dskip-test-incremental \
5150 -Dtarget=native-native-musl \
5251 --search-prefix "$PREFIX" \
5352 --zig-lib-dir "$PWD/../lib" \
ci/aarch64-macos-debug.sh-1
......@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \
4747 -Denable-macos-sdk \
4848 -Dstatic-llvm \
4949 -Dskip-non-native \
50 -Dskip-test-incremental \
5150 --search-prefix "$PREFIX" \
5251 --test-timeout 2m
5352
ci/aarch64-macos-release.sh-1
......@@ -46,7 +46,6 @@ stage3-release/bin/zig build test docs \
4646 -Denable-macos-sdk \
4747 -Dstatic-llvm \
4848 -Dskip-non-native \
49 -Dskip-test-incremental \
5049 --search-prefix "$PREFIX" \
5150 --test-timeout 2m
5251
ci/aarch64-netbsd-debug.sh-1
......@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \
4747 --maxrss ${ZSF_MAX_RSS:-0} \
4848 -Dstatic-llvm \
4949 -Dskip-non-native \
50 -Dskip-test-incremental \
5150 --search-prefix "$PREFIX" \
5251 --zig-lib-dir "$PWD/../lib" \
5352 --test-timeout 4m
ci/aarch64-netbsd-release.sh-1
......@@ -47,7 +47,6 @@ stage3-release/bin/zig build test docs \
4747 --maxrss ${ZSF_MAX_RSS:-0} \
4848 -Dstatic-llvm \
4949 -Dskip-non-native \
50 -Dskip-test-incremental \
5150 --search-prefix "$PREFIX" \
5251 --zig-lib-dir "$PWD/../lib" \
5352 --test-timeout 4m
ci/aarch64-windows.ps1-1
......@@ -60,7 +60,6 @@ Write-Output "Main test suite..."
6060 --search-prefix "$PREFIX_PATH" `
6161 -Dstatic-llvm `
6262 -Dskip-non-native `
63 -Dskip-test-incremental `
6463 -Denable-symlinks-windows `
6564 --test-timeout 30m
6665CheckLastExitCode
ci/loongarch64-linux-debug.sh-1
......@@ -48,7 +48,6 @@ stage3-debug/bin/zig build test docs \
4848 --maxrss ${ZSF_MAX_RSS:-0} \
4949 -Dstatic-llvm \
5050 -Dskip-non-native \
51 -Dskip-test-incremental \
5251 -Dtarget=native-native-musl \
5352 --search-prefix "$PREFIX" \
5453 --zig-lib-dir "$PWD/../lib" \
ci/loongarch64-linux-release.sh-1
......@@ -48,7 +48,6 @@ stage3-release/bin/zig build test docs \
4848 --maxrss ${ZSF_MAX_RSS:-0} \
4949 -Dstatic-llvm \
5050 -Dskip-non-native \
51 -Dskip-test-incremental \
5251 -Dtarget=native-native-musl \
5352 --search-prefix "$PREFIX" \
5453 --zig-lib-dir "$PWD/../lib" \
ci/powerpc64le-linux-debug.sh-1
......@@ -48,7 +48,6 @@ stage3-debug/bin/zig build test docs \
4848 --maxrss ${ZSF_MAX_RSS:-0} \
4949 -Dstatic-llvm \
5050 -Dskip-non-native \
51 -Dskip-test-incremental \
5251 -Dtarget=native-native-musl \
5352 -Dcpu=native+longcall \
5453 --search-prefix "$PREFIX" \
ci/powerpc64le-linux-release.sh-1
......@@ -48,7 +48,6 @@ stage3-release/bin/zig build test docs \
4848 --maxrss ${ZSF_MAX_RSS:-0} \
4949 -Dstatic-llvm \
5050 -Dskip-non-native \
51 -Dskip-test-incremental \
5251 -Dtarget=native-native-musl \
5352 -Dcpu=native+longcall \
5453 --search-prefix "$PREFIX" \
ci/s390x-linux-debug.sh-1
......@@ -48,7 +48,6 @@ stage3-debug/bin/zig build test docs \
4848 --maxrss ${ZSF_MAX_RSS:-0} \
4949 -Dstatic-llvm \
5050 -Dskip-non-native \
51 -Dskip-test-incremental \
5251 -Dtarget=native-native-musl \
5352 --search-prefix "$PREFIX" \
5453 --zig-lib-dir "$PWD/../lib" \
ci/s390x-linux-release.sh-1
......@@ -48,7 +48,6 @@ stage3-release/bin/zig build test docs \
4848 --maxrss ${ZSF_MAX_RSS:-0} \
4949 -Dstatic-llvm \
5050 -Dskip-non-native \
51 -Dskip-test-incremental \
5251 -Dtarget=native-native-musl \
5352 --search-prefix "$PREFIX" \
5453 --zig-lib-dir "$PWD/../lib" \
ci/x86_64-freebsd-debug.sh-1
......@@ -53,7 +53,6 @@ stage3-debug/bin/zig build test docs \
5353 -Dskip-openbsd \
5454 -Dskip-windows \
5555 -Dskip-darwin \
56 -Dskip-test-incremental \
5756 --search-prefix "$PREFIX" \
5857 --zig-lib-dir "$PWD/../lib" \
5958 --test-timeout 2m
ci/x86_64-freebsd-release.sh-1
......@@ -53,7 +53,6 @@ stage3-release/bin/zig build test docs \
5353 -Dskip-openbsd \
5454 -Dskip-windows \
5555 -Dskip-darwin \
56 -Dskip-test-incremental \
5756 --search-prefix "$PREFIX" \
5857 --zig-lib-dir "$PWD/../lib" \
5958 --test-timeout 2m
ci/x86_64-linux-debug-llvm.sh-1
......@@ -64,7 +64,6 @@ stage3-debug/bin/zig build test docs \
6464 -Dskip-openbsd \
6565 -Dskip-windows \
6666 -Dskip-darwin \
67 -Dskip-test-incremental \
6867 -Dtarget=native-native-musl \
6968 --search-prefix "$PREFIX" \
7069 --zig-lib-dir "$PWD/../lib" \
ci/x86_64-linux-debug.sh-1
......@@ -63,7 +63,6 @@ stage3-debug/bin/zig build test docs \
6363 -Dskip-windows \
6464 -Dskip-darwin \
6565 -Dskip-llvm \
66 -Dskip-test-incremental \
6766 -Dtarget=native-native-musl \
6867 --search-prefix "$PREFIX" \
6968 --zig-lib-dir "$PWD/../lib" \
ci/x86_64-linux-release.sh+2-2
......@@ -21,7 +21,8 @@ export ZIG_LOCAL_CACHE_DIR="$PWD/zig-local-cache"
2121
2222# Test building from source without LLVM.
2323cc -o bootstrap bootstrap.c
24./bootstrap
24# See comments in bootstrap.c for an explanation of the flag given here.
25./bootstrap --workaround-gcc-sra-miscomp
2526./zig2 build -Dno-lib
2627./zig-out/bin/zig test test/behavior.zig
2728
......@@ -64,7 +65,6 @@ stage3-release/bin/zig build test docs \
6465 --libc-runtimes $HOME/deps/glibc-2.43-musl-1.2.5 \
6566 -fwasmtime \
6667 -Dstatic-llvm \
67 -Dskip-test-incremental \
6868 -Dtarget=native-native-musl \
6969 --search-prefix "$PREFIX" \
7070 --zig-lib-dir "$PWD/../lib" \
ci/x86_64-netbsd-debug.sh-1
......@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \
4747 --maxrss ${ZSF_MAX_RSS:-0} \
4848 -Dstatic-llvm \
4949 -Dskip-non-native \
50 -Dskip-test-incremental \
5150 --search-prefix "$PREFIX" \
5251 --zig-lib-dir "$PWD/../lib" \
5352 --test-timeout 2m
ci/x86_64-netbsd-release.sh-1
......@@ -47,7 +47,6 @@ stage3-release/bin/zig build test docs \
4747 --maxrss ${ZSF_MAX_RSS:-0} \
4848 -Dstatic-llvm \
4949 -Dskip-non-native \
50 -Dskip-test-incremental \
5150 --search-prefix "$PREFIX" \
5251 --zig-lib-dir "$PWD/../lib" \
5352 --test-timeout 2m
ci/x86_64-openbsd-debug.sh-1
......@@ -47,7 +47,6 @@ stage3-debug/bin/zig build test docs \
4747 --maxrss ${ZSF_MAX_RSS:-0} \
4848 -Dstatic-llvm \
4949 -Dskip-non-native \
50 -Dskip-test-incremental \
5150 --search-prefix "$PREFIX" \
5251 --zig-lib-dir "$PWD/../lib" \
5352 --test-timeout 2m
ci/x86_64-openbsd-release.sh-1
......@@ -47,7 +47,6 @@ stage3-release/bin/zig build test docs \
4747 --maxrss ${ZSF_MAX_RSS:-0} \
4848 -Dstatic-llvm \
4949 -Dskip-non-native \
50 -Dskip-test-incremental \
5150 --search-prefix "$PREFIX" \
5251 --zig-lib-dir "$PWD/../lib" \
5352 --test-timeout 2m
doc/langref.html.in+3-2
......@@ -2103,8 +2103,9 @@ or
21032103 less than {#syntax#}1 << 29{#endsyntax#}.
21042104 </p>
21052105 <p>
2106 In Zig, a pointer type has an alignment value. If the value is equal to the
2107 alignment of the underlying type, it can be omitted from the type:
2106 Pointer types may explicitly specify an alignment in bytes. If it is not
2107 specified, the alignment is assumed to be equal to the alignment of the
2108 underlying type.
21082109 </p>
21092110 {#code|test_variable_alignment.zig#}
21102111
doc/langref/test_comptime_invalid_error_code.zig+2-5
......@@ -1,8 +1,5 @@
11comptime {
2 const err = error.AnError;
3 const number = @intFromError(err) + 10;
4 const invalid_err = @errorFromInt(number);
5 _ = invalid_err;
2 _ = @errorFromInt(12345);
63}
74
8// test_error=integer value '11' represents no error
5// test_error=integer value '12345' represents no error
doc/langref/test_missized_packed_struct.zig+1-1
......@@ -3,4 +3,4 @@ test "missized packed struct" {
33 _ = S{ .a = 4, .b = 2 };
44}
55
6// test_error=backing integer type 'u32' has bit size 32 but the struct fields have a total bit size of 24
6// test_error=backing integer bit width does not match total bit width of fields
doc/langref/test_variable_alignment.zig+10-5
......@@ -1,15 +1,20 @@
11const std = @import("std");
22const builtin = @import("builtin");
3const expect = std.testing.expect;
34const expectEqual = std.testing.expectEqual;
45
56test "variable alignment" {
67 var x: i32 = 1234;
7 const align_of_i32 = @alignOf(@TypeOf(x));
8
89 try expectEqual(*i32, @TypeOf(&x));
9 try expectEqual(*align(align_of_i32) i32, *i32);
10 if (builtin.target.cpu.arch == .x86_64) {
11 try expectEqual(4, @typeInfo(*i32).pointer.alignment);
12 }
10
11 try expect(@intFromPtr(&x) % @alignOf(i32) == 0);
12
13 // The implicitly-aligned pointer can be coerced to be explicitly-aligned to
14 // the alignment of the underlying type `i32`:
15 const ptr: *align(@alignOf(i32)) i32 = &x;
16
17 try expectEqual(1234, ptr.*);
1318}
1419
1520// test
lib/compiler/aro/aro/InitList.zig+13-7
......@@ -22,9 +22,15 @@ const Item = struct {
2222
2323const InitList = @This();
2424
25list: std.ArrayList(Item) = .empty,
26node: Node.OptIndex = .null,
27tok: TokenIndex = 0,
25list: std.ArrayList(Item),
26node: Node.OptIndex,
27tok: TokenIndex,
28
29pub const empty: InitList = .{
30 .list = .empty,
31 .node = .null,
32 .tok = 0,
33};
2834
2935/// Deinitialize freeing all memory.
3036pub fn deinit(il: *InitList, gpa: Allocator) void {
......@@ -43,7 +49,7 @@ pub fn find(il: *InitList, gpa: Allocator, index: u64) !*InitList {
4349 if (il.list.items.len == 0) {
4450 const item = try il.list.addOne(gpa);
4551 item.* = .{
46 .list = .{},
52 .list = .empty,
4753 .index = index,
4854 };
4955 return &item.list;
......@@ -51,7 +57,7 @@ pub fn find(il: *InitList, gpa: Allocator, index: u64) !*InitList {
5157 // Append a new value to the end of the list.
5258 const new = try il.list.addOne(gpa);
5359 new.* = .{
54 .list = .{},
60 .list = .empty,
5561 .index = index,
5662 };
5763 return &new.list;
......@@ -70,7 +76,7 @@ pub fn find(il: *InitList, gpa: Allocator, index: u64) !*InitList {
7076
7177 // Insert a new value into a sorted position.
7278 try il.list.insert(gpa, left, .{
73 .list = .{},
79 .list = .empty,
7480 .index = index,
7581 });
7682 return &il.list.items[left].list;
......@@ -78,7 +84,7 @@ pub fn find(il: *InitList, gpa: Allocator, index: u64) !*InitList {
7884
7985test "basic usage" {
8086 const gpa = testing.allocator;
81 var il: InitList = .{};
87 var il: InitList = .empty;
8288 defer il.deinit(gpa);
8389
8490 {
lib/compiler/aro/aro/Parser.zig+3-3
......@@ -3977,7 +3977,7 @@ fn initializer(p: *Parser, init_qt: QualType) Error!Result {
39773977 final_init_qt = .invalid;
39783978 }
39793979
3980 var il: InitList = .{};
3980 var il: InitList = .empty;
39813981 defer il.deinit(p.comp.gpa);
39823982
39833983 try p.initializerItem(&il, final_init_qt, l_brace);
......@@ -4028,12 +4028,12 @@ fn initializerItem(p: *Parser, il: *InitList, init_qt: QualType, l_brace: TokenI
40284028 try p.err(first_tok, .initializer_overrides, .{});
40294029 try p.err(item.il.tok, .previous_initializer, .{});
40304030 item.il.deinit(gpa);
4031 item.il.* = .{};
4031 item.il.* = .empty;
40324032 }
40334033 try p.initializerItem(item.il, item.qt, inner_l_brace);
40344034 } else {
40354035 // discard further values
4036 var tmp_il: InitList = .{};
4036 var tmp_il: InitList = .empty;
40374037 defer tmp_il.deinit(gpa);
40384038 try p.initializerItem(&tmp_il, .invalid, inner_l_brace);
40394039 if (!warned_excess) try p.err(first_tok, switch (init_qt.base(p.comp).type) {
lib/compiler/aro/aro/Toolchain.zig+3-3
......@@ -43,13 +43,13 @@ const Toolchain = @This();
4343driver: *Driver,
4444
4545/// The list of toolchain specific path prefixes to search for libraries.
46library_paths: PathList = .{},
46library_paths: PathList = .empty,
4747
4848/// The list of toolchain specific path prefixes to search for files.
49file_paths: PathList = .{},
49file_paths: PathList = .empty,
5050
5151/// The list of toolchain specific path prefixes to search for programs.
52program_paths: PathList = .{},
52program_paths: PathList = .empty,
5353
5454selected_multilib: Multilib = .{},
5555
lib/compiler/objcopy.zig+2-2
......@@ -388,8 +388,8 @@ const BinaryElfOutput = struct {
388388
389389 pub fn parse(allocator: Allocator, in: *File.Reader, elf_hdr: elf.Header) !Self {
390390 var self: Self = .{
391 .segments = .{},
392 .sections = .{},
391 .segments = .empty,
392 .sections = .empty,
393393 .allocator = allocator,
394394 .shstrtab = null,
395395 };
lib/compiler/resinator/cvtres.zig+1-1
......@@ -410,7 +410,7 @@ pub const ResourceDirectoryTable = extern struct {
410410};
411411
412412pub const ResourceDirectoryEntry = extern struct {
413 entry: packed union {
413 entry: packed union(u32) {
414414 name_offset: packed struct(u32) {
415415 address: u31,
416416 /// This is undocumented in the PE/COFF spec, but the high bit
lib/compiler/test_runner.zig+4-4
......@@ -38,10 +38,10 @@ pub fn main(init: std.process.Init.Minimal) void {
3838 }
3939
4040 if (need_simple) {
41 return mainSimple() catch @panic("test failure");
41 return mainSimple() catch |err| std.debug.panic("test failure: {t}", .{err});
4242 }
4343
44 const args = init.args.toSlice(fba.allocator()) catch @panic("unable to parse command line args");
44 const args = init.args.toSlice(fba.allocator()) catch |err| std.debug.panic("unable to parse command line args: {t}", .{err});
4545
4646 var listen = false;
4747 var opt_cache_dir: ?[]const u8 = null;
......@@ -55,7 +55,7 @@ pub fn main(init: std.process.Init.Minimal) void {
5555 } else if (std.mem.startsWith(u8, arg, "--cache-dir")) {
5656 opt_cache_dir = arg["--cache-dir=".len..];
5757 } else {
58 @panic("unrecognized command line argument");
58 std.debug.panic("unrecognized command line argument: {s}", .{arg});
5959 }
6060 }
6161
......@@ -65,7 +65,7 @@ pub fn main(init: std.process.Init.Minimal) void {
6565 }
6666
6767 if (listen) {
68 return mainServer(init) catch @panic("internal test runner failure");
68 return mainServer(init) catch |err| std.debug.panic("internal test runner failure: {t}", .{err});
6969 } else {
7070 return mainTerminal(init);
7171 }
lib/std/Build/Fuzz.zig+2-2
......@@ -390,7 +390,7 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO
390390 .coverage = std.debug.Coverage.init,
391391 .mapped_memory = undefined, // populated below
392392 .source_locations = undefined, // populated below
393 .entry_points = .{},
393 .entry_points = .empty,
394394 .start_timestamp = ws.now(),
395395 .start_n_runs = undefined, // populated below
396396 };
......@@ -450,7 +450,7 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO
450450
451451 // Unfortunately the PCs array that LLVM gives us from the 8-bit PC
452452 // counters feature is not sorted.
453 var sorted_pcs: std.MultiArrayList(struct { pc: u64, index: u32, sl: Coverage.SourceLocation }) = .{};
453 var sorted_pcs: std.MultiArrayList(struct { pc: u64, index: u32, sl: Coverage.SourceLocation }) = .empty;
454454 defer sorted_pcs.deinit(gpa);
455455 try sorted_pcs.resize(gpa, pcs.len);
456456 @memcpy(sorted_pcs.items(.pc), pcs);
lib/std/Build/Module.zig+7-7
......@@ -275,18 +275,18 @@ pub fn init(
275275 m.* = .{
276276 .owner = owner,
277277 .root_source_file = if (options.root_source_file) |lp| lp.dupe(owner) else null,
278 .import_table = .{},
278 .import_table = .empty,
279279 .resolved_target = options.target,
280280 .optimize = options.optimize,
281281 .link_libc = options.link_libc,
282282 .link_libcpp = options.link_libcpp,
283283 .dwarf_format = options.dwarf_format,
284 .c_macros = .{},
285 .include_dirs = .{},
286 .lib_paths = .{},
287 .rpaths = .{},
288 .frameworks = .{},
289 .link_objects = .{},
284 .c_macros = .empty,
285 .include_dirs = .empty,
286 .lib_paths = .empty,
287 .rpaths = .empty,
288 .frameworks = .empty,
289 .link_objects = .empty,
290290 .strip = options.strip,
291291 .unwind_tables = options.unwind_tables,
292292 .single_threaded = options.single_threaded,
lib/std/Build/Step.zig+1-1
......@@ -250,7 +250,7 @@ pub fn init(options: StepOptions) Step {
250250 const first_ret_addr = options.first_ret_addr orelse @returnAddress();
251251 break :blk std.debug.captureCurrentStackTrace(.{ .first_address = first_ret_addr }, addr_buf);
252252 },
253 .result_error_msgs = .{},
253 .result_error_msgs = .empty,
254254 .result_error_bundle = std.zig.ErrorBundle.empty,
255255 .result_stderr = "",
256256 .result_cached = false,
lib/std/Build/Step/Run.zig+4-4
......@@ -213,13 +213,13 @@ pub fn create(owner: *std.Build, name: []const u8) *Run {
213213 .owner = owner,
214214 .makeFn = make,
215215 }),
216 .argv = .{},
216 .argv = .empty,
217217 .cwd = null,
218218 .environ_map = null,
219219 .disable_zig_progress = false,
220220 .stdio = .infer_from_args,
221221 .stdin = .none,
222 .file_inputs = .{},
222 .file_inputs = .empty,
223223 .rename_step_with_output_arg = true,
224224 .skip_foreign_checks = false,
225225 .failing_to_execute_foreign_is_an_error = true,
......@@ -228,7 +228,7 @@ pub fn create(owner: *std.Build, name: []const u8) *Run {
228228 .captured_stderr = null,
229229 .dep_output_file = null,
230230 .has_side_effects = false,
231 .fuzz_tests = .{},
231 .fuzz_tests = .empty,
232232 .rebuilt_executable = null,
233233 .producer = null,
234234 };
......@@ -642,7 +642,7 @@ pub fn addCheck(run: *Run, new_check: StdIo.Check) void {
642642
643643 switch (run.stdio) {
644644 .infer_from_args => {
645 run.stdio = .{ .check = .{} };
645 run.stdio = .{ .check = .empty };
646646 run.stdio.check.append(b.allocator, new_check) catch @panic("OOM");
647647 },
648648 .check => |*checks| checks.append(b.allocator, new_check) catch @panic("OOM"),
lib/std/Build/Step/UpdateSourceFiles.zig+1-1
......@@ -35,7 +35,7 @@ pub fn create(owner: *std.Build) *UpdateSourceFiles {
3535 .owner = owner,
3636 .makeFn = make,
3737 }),
38 .output_source_files = .{},
38 .output_source_files = .empty,
3939 };
4040 return usf;
4141}
lib/std/Build/Step/WriteFile.zig+2-2
......@@ -94,8 +94,8 @@ pub fn create(owner: *std.Build) *WriteFile {
9494 .owner = owner,
9595 .makeFn = make,
9696 }),
97 .files = .{},
98 .directories = .{},
97 .files = .empty,
98 .directories = .empty,
9999 .generated_directory = .{ .step = &write_file.step },
100100 };
101101 return write_file;
lib/std/Io/Dir.zig+1-1
......@@ -334,7 +334,7 @@ pub fn walkSelectively(dir: Dir, allocator: Allocator) !SelectiveWalker {
334334
335335 return .{
336336 .stack = stack,
337 .name_buffer = .{},
337 .name_buffer = .empty,
338338 .allocator = allocator,
339339 };
340340}
lib/std/array_list.zig+2-2
......@@ -582,10 +582,10 @@ pub fn Aligned(comptime T: type, comptime alignment: ?mem.Alignment) type {
582582 /// functions of this ArrayList in accordance with the respective
583583 /// documentation. In all cases, "invalidated" means that the memory
584584 /// has been passed to an allocator's resize or free function.
585 items: Slice = &[_]T{},
585 items: Slice,
586586 /// How many T values this list can hold without allocating
587587 /// additional memory.
588 capacity: usize = 0,
588 capacity: usize,
589589
590590 /// An ArrayList containing no elements.
591591 pub const empty: Self = .{
lib/std/builtin.zig+8-4
......@@ -592,8 +592,8 @@ pub const Type = union(enum) {
592592 size: Size,
593593 is_const: bool,
594594 is_volatile: bool,
595 /// TODO make this u16 instead of comptime_int
596 alignment: comptime_int,
595 /// `null` means implicit alignment, which is equivalent to `@alignOf(child)`.
596 alignment: ?usize,
597597 address_space: AddressSpace,
598598 child: type,
599599 is_allowzero: bool,
......@@ -670,7 +670,9 @@ pub const Type = union(enum) {
670670 /// See also: `defaultValue`.
671671 default_value_ptr: ?*const anyopaque,
672672 is_comptime: bool,
673 alignment: comptime_int,
673 /// `null` means the field alignment was not explicitly specified. The
674 /// field will still be aligned to at least `@alignOf` its `type`.
675 alignment: ?usize,
674676
675677 /// Loads the field's default value from `default_value_ptr`.
676678 /// Returns `null` if the field has no default value.
......@@ -747,7 +749,9 @@ pub const Type = union(enum) {
747749 pub const UnionField = struct {
748750 name: [:0]const u8,
749751 type: type,
750 alignment: comptime_int,
752 /// `null` means the field alignment was not explicitly specified. The
753 /// field will still be aligned to at least `@alignOf` its `type`.
754 alignment: ?usize,
751755
752756 /// This data structure is used by the Zig language code generation and
753757 /// therefore must be kept in sync with the compiler implementation.
lib/std/c/darwin.zig+1-1
......@@ -436,7 +436,7 @@ pub const thread_state_flavor_t = c_int;
436436pub const ipc_space_t = mach_port_t;
437437pub const ipc_space_port_t = ipc_space_t;
438438
439pub const mach_msg_option_t = packed union {
439pub const mach_msg_option_t = packed union(integer_t) {
440440 RCV: MACH.RCV,
441441 SEND: MACH.SEND,
442442
lib/std/c/darwin/dispatch.zig+1-1
......@@ -210,7 +210,7 @@ pub const source_timer_flags_t = packed struct(usize) {
210210 STRICT: bool = false,
211211 unused1: @Int(.unsigned, @bitSizeOf(usize) - 1) = 0,
212212};
213pub const source_flags_t = packed union {
213pub const source_flags_t = packed union(usize) {
214214 raw: usize,
215215 MACH_SEND: source_mach_send_flags_t,
216216 MACH_RECV: source_mach_recv_flags_t,
lib/std/compress/lzma.zig+1-1
......@@ -349,7 +349,7 @@ pub const Decode = struct {
349349
350350 pub fn init(dict_size: usize, mem_limit: usize) CircularBuffer {
351351 return .{
352 .buf = .{},
352 .buf = .empty,
353353 .dict_size = dict_size,
354354 .mem_limit = mem_limit,
355355 .cursor = 0,
lib/std/compress/lzma2.zig+1-1
......@@ -16,7 +16,7 @@ pub const AccumBuffer = struct {
1616
1717 pub fn init(memlimit: usize) AccumBuffer {
1818 return .{
19 .buf = .{},
19 .buf = .empty,
2020 .memlimit = memlimit,
2121 .len = 0,
2222 };
lib/std/debug/Coverage.zig+3-3
......@@ -27,10 +27,10 @@ string_bytes: std.ArrayList(u8),
2727mutex: Io.Mutex,
2828
2929pub const init: Coverage = .{
30 .directories = .{},
31 .files = .{},
30 .directories = .empty,
31 .files = .empty,
3232 .mutex = .init,
33 .string_bytes = .{},
33 .string_bytes = .empty,
3434};
3535
3636pub const String = enum(u32) {
lib/std/elf.zig+2-2
......@@ -1071,7 +1071,7 @@ pub const Elf32 = struct {
10711071 pub const Shdr = extern struct {
10721072 name: Word,
10731073 type: SHT,
1074 flags: packed struct { shf: SHF },
1074 flags: packed struct(Word) { shf: SHF },
10751075 addr: Elf32.Addr,
10761076 offset: Elf32.Off,
10771077 size: Word,
......@@ -1161,7 +1161,7 @@ pub const Elf64 = struct {
11611161 pub const Shdr = extern struct {
11621162 name: Word,
11631163 type: SHT,
1164 flags: packed struct { shf: SHF, unused: Word = 0 },
1164 flags: packed struct(Xword) { shf: SHF, unused: Word = 0 },
11651165 addr: Elf64.Addr,
11661166 offset: Elf64.Off,
11671167 size: Xword,
lib/std/hash_map.zig+3-3
......@@ -1526,9 +1526,9 @@ pub fn HashMapUnmanaged(
15261526 }
15271527
15281528 comptime {
1529 if (!builtin.strip_debug_info) _ = switch (builtin.zig_backend) {
1530 .stage2_llvm => &dbHelper,
1531 .stage2_x86_64 => KV,
1529 if (!builtin.strip_debug_info) switch (builtin.zig_backend) {
1530 .stage2_llvm => _ = &dbHelper,
1531 .stage2_x86_64 => _ = @as(KV, undefined),
15321532 else => {},
15331533 };
15341534 }
lib/std/macho.zig+1-1
......@@ -851,7 +851,7 @@ pub const nlist = extern struct {
851851
852852pub const nlist_64 = extern struct {
853853 n_strx: u32,
854 n_type: packed union {
854 n_type: packed union(u8) {
855855 bits: packed struct(u8) {
856856 ext: bool,
857857 type: enum(u3) {
lib/std/math/big/int.zig+12-2
......@@ -924,7 +924,12 @@ pub const Mutable = struct {
924924 /// Asserts the result fits in `r`. Upper bound on the number of limbs needed by
925925 /// r is `calcTwosCompLimbCount(bit_count)`.
926926 pub fn bitReverse(r: *Mutable, a: Const, signedness: Signedness, bit_count: usize) void {
927 if (bit_count == 0) return;
927 if (bit_count == 0) {
928 r.limbs[0] = 0;
929 r.len = 1;
930 r.positive = true;
931 return;
932 }
928933
929934 r.copy(a);
930935
......@@ -986,7 +991,12 @@ pub const Mutable = struct {
986991 /// Asserts the result fits in `r`. Upper bound on the number of limbs needed by
987992 /// r is `calcTwosCompLimbCount(8*byte_count)`.
988993 pub fn byteSwap(r: *Mutable, a: Const, signedness: Signedness, byte_count: usize) void {
989 if (byte_count == 0) return;
994 if (byte_count == 0) {
995 r.limbs[0] = 0;
996 r.len = 1;
997 r.positive = true;
998 return;
999 }
9901000
9911001 r.copy(a);
9921002 const limbs_required = calcTwosCompLimbCount(8 * byte_count);
lib/std/mem.zig+12-4
......@@ -38,6 +38,10 @@ pub const Alignment = enum(math.Log2Int(usize)) {
3838 return @enumFromInt(@ctz(n));
3939 }
4040
41 pub fn fromByteUnitsOptional(maybe_n: ?usize) ?Alignment {
42 return if (maybe_n) |n| .fromByteUnits(n) else null;
43 }
44
4145 pub inline fn of(comptime T: type) Alignment {
4246 return comptime fromByteUnits(@alignOf(T));
4347 }
......@@ -2287,8 +2291,8 @@ pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *a
22872291 ptr.* = @bitCast(@byteSwap(@as(Int, @bitCast(ptr.*))));
22882292 } else inline for (std.meta.fields(S)) |f| {
22892293 switch (@typeInfo(f.type)) {
2290 .@"struct" => byteSwapAllFieldsAligned(f.type, .fromByteUnits(f.alignment), &@field(ptr, f.name)),
2291 .@"union", .array => byteSwapAllFieldsAligned(f.type, .fromByteUnits(f.alignment), &@field(ptr, f.name)),
2294 .@"struct" => byteSwapAllFieldsAligned(f.type, .fromByteUnits(f.alignment orelse @alignOf(f.type)), &@field(ptr, f.name)),
2295 .@"union", .array => byteSwapAllFieldsAligned(f.type, .fromByteUnits(f.alignment orelse @alignOf(f.type)), &@field(ptr, f.name)),
22922296 .@"enum" => {
22932297 @field(ptr, f.name) = @enumFromInt(@byteSwap(@intFromEnum(@field(ptr, f.name))));
22942298 },
......@@ -4330,7 +4334,7 @@ pub fn alignPointerOffset(ptr: anytype, align_to: usize) ?usize {
43304334 @compileError("expected many item pointer, got " ++ @typeName(T));
43314335
43324336 // Do nothing if the pointer is already well-aligned.
4333 if (align_to <= info.pointer.alignment)
4337 if (align_to <= info.pointer.alignment orelse @alignOf(info.pointer.child))
43344338 return 0;
43354339
43364340 // Calculate the aligned base address with an eye out for overflow.
......@@ -4388,7 +4392,11 @@ fn CopyPtrAttrs(
43884392 .@"const" = ptr.is_const,
43894393 .@"volatile" = ptr.is_volatile,
43904394 .@"allowzero" = ptr.is_allowzero,
4391 .@"align" = ptr.alignment,
4395 .@"align" = ptr.alignment orelse a: {
4396 // If the new child is aligned differently than the old one, explicitly align the type.
4397 const want = @alignOf(ptr.child);
4398 break :a if (@alignOf(child) == want) null else want;
4399 },
43924400 .@"addrspace" = ptr.address_space,
43934401 }, child, null);
43944402}
lib/std/mem/Allocator.zig+52-47
......@@ -179,7 +179,11 @@ pub fn destroy(self: Allocator, ptr: anytype) void {
179179 const T = info.child;
180180 if (@sizeOf(T) == 0) return;
181181 const non_const_ptr = @as([*]u8, @ptrCast(@constCast(ptr)));
182 self.rawFree(non_const_ptr[0..@sizeOf(T)], .fromByteUnits(info.alignment), @returnAddress());
182 self.rawFree(
183 non_const_ptr[0..@sizeOf(T)],
184 .fromByteUnits(info.alignment orelse @alignOf(T)),
185 @returnAddress(),
186 );
183187}
184188
185189/// Allocates an array of `n` items of type `T` and sets all the
......@@ -266,7 +270,7 @@ pub inline fn allocAdvancedWithRetAddr(
266270 n: usize,
267271 return_address: usize,
268272) Error![]align(if (alignment) |a| a.toByteUnits() else @alignOf(T)) T {
269 const a = comptime (alignment orelse Alignment.of(T));
273 const a: Alignment = alignment orelse comptime .of(T);
270274 const ptr: [*]align(a.toByteUnits()) T = @ptrCast(try self.allocWithSizeAndAlignment(@sizeOf(T), a, n, return_address));
271275 return ptr[0..n];
272276}
......@@ -278,7 +282,7 @@ fn allocWithSizeAndAlignment(
278282 n: usize,
279283 return_address: usize,
280284) Error![*]align(alignment.toByteUnits()) u8 {
281 const byte_count = math.mul(usize, size, n) catch return Error.OutOfMemory;
285 const byte_count = math.mul(usize, size, n) catch return error.OutOfMemory;
282286 return self.allocBytesWithAlignment(alignment, byte_count, return_address);
283287}
284288
......@@ -293,7 +297,7 @@ fn allocBytesWithAlignment(
293297 return @as([*]align(alignment.toByteUnits()) u8, @ptrFromInt(ptr));
294298 }
295299
296 const byte_ptr = self.rawAlloc(byte_count, alignment, return_address) orelse return Error.OutOfMemory;
300 const byte_ptr = self.rawAlloc(byte_count, alignment, return_address) orelse return error.OutOfMemory;
297301 @memset(byte_ptr[0..byte_count], undefined);
298302 return @alignCast(byte_ptr);
299303}
......@@ -308,9 +312,9 @@ fn allocBytesWithAlignment(
308312///
309313/// `new_len` may be zero, in which case the allocation is freed.
310314pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {
311 const Slice = @typeInfo(@TypeOf(allocation)).pointer;
312 const T = Slice.child;
313 const alignment = Slice.alignment;
315 const slice_info = @typeInfo(@TypeOf(allocation)).pointer;
316 comptime assert(slice_info.size == .slice);
317 const T = slice_info.child;
314318 if (new_len == 0) {
315319 self.free(allocation);
316320 return true;
......@@ -323,7 +327,12 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {
323327 // on WebAssembly: https://github.com/ziglang/zig/issues/9660
324328 //const new_len_bytes = new_len *| @sizeOf(T);
325329 const new_len_bytes = math.mul(usize, @sizeOf(T), new_len) catch return false;
326 return self.rawResize(old_memory, .fromByteUnits(alignment), new_len_bytes, @returnAddress());
330 return self.rawResize(
331 old_memory,
332 .fromByteUnits(slice_info.alignment orelse @alignOf(T)),
333 new_len_bytes,
334 @returnAddress(),
335 );
327336}
328337
329338/// Request to modify the size of an allocation, allowing relocation.
......@@ -342,14 +351,11 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {
342351/// `new_len` may be zero, in which case the allocation is freed.
343352///
344353/// If the allocation's elements' type is zero bytes sized, `allocation.len` is set to `new_len`.
345pub fn remap(self: Allocator, allocation: anytype, new_len: usize) t: {
346 const Slice = @typeInfo(@TypeOf(allocation)).pointer;
347 break :t ?[]align(Slice.alignment) Slice.child;
348} {
349 const Slice = @typeInfo(@TypeOf(allocation)).pointer;
350 const T = Slice.child;
351
352 const alignment = Slice.alignment;
354pub fn remap(self: Allocator, allocation: anytype, new_len: usize) ?@TypeOf(allocation) {
355 const slice_info = @typeInfo(@TypeOf(allocation)).pointer;
356 comptime assert(slice_info.size == .slice);
357 const T = slice_info.child;
358
353359 if (new_len == 0) {
354360 self.free(allocation);
355361 return allocation[0..0];
......@@ -367,9 +373,13 @@ pub fn remap(self: Allocator, allocation: anytype, new_len: usize) t: {
367373 // on WebAssembly: https://github.com/ziglang/zig/issues/9660
368374 //const new_len_bytes = new_len *| @sizeOf(T);
369375 const new_len_bytes = math.mul(usize, @sizeOf(T), new_len) catch return null;
370 const new_ptr = self.rawRemap(old_memory, .fromByteUnits(alignment), new_len_bytes, @returnAddress()) orelse return null;
371 const new_memory: []align(alignment) u8 = @alignCast(new_ptr[0..new_len_bytes]);
372 return mem.bytesAsSlice(T, new_memory);
376 const new_ptr = self.rawRemap(
377 old_memory,
378 .fromByteUnits(slice_info.alignment orelse @alignOf(T)),
379 new_len_bytes,
380 @returnAddress(),
381 ) orelse return null;
382 return @ptrCast(@alignCast(new_ptr[0..new_len_bytes]));
373383}
374384
375385/// This function requests a new size for an existing allocation, which
......@@ -386,10 +396,7 @@ pub fn remap(self: Allocator, allocation: anytype, new_len: usize) t: {
386396/// do the realloc more efficiently than the caller
387397/// * `resize` which returns `false` when the `Allocator` implementation cannot
388398/// change the size without relocating the allocation.
389pub fn realloc(self: Allocator, old_mem: anytype, new_n: usize) t: {
390 const Slice = @typeInfo(@TypeOf(old_mem)).pointer;
391 break :t Error![]align(Slice.alignment) Slice.child;
392} {
399pub fn realloc(self: Allocator, old_mem: anytype, new_n: usize) Error!@TypeOf(old_mem) {
393400 return self.reallocAdvanced(old_mem, new_n, @returnAddress());
394401}
395402
......@@ -398,51 +405,49 @@ pub fn reallocAdvanced(
398405 old_mem: anytype,
399406 new_n: usize,
400407 return_address: usize,
401) t: {
402 const Slice = @typeInfo(@TypeOf(old_mem)).pointer;
403 break :t Error![]align(Slice.alignment) Slice.child;
404} {
405 const Slice = @typeInfo(@TypeOf(old_mem)).pointer;
406 const T = Slice.child;
408) Error!@TypeOf(old_mem) {
409 const slice_info = @typeInfo(@TypeOf(old_mem)).pointer;
410 comptime assert(slice_info.size == .slice);
411 const T = slice_info.child;
407412 if (old_mem.len == 0) {
408 return self.allocAdvancedWithRetAddr(T, .fromByteUnits(Slice.alignment), new_n, return_address);
413 return self.allocAdvancedWithRetAddr(T, .fromByteUnitsOptional(slice_info.alignment), new_n, return_address);
409414 }
410415 if (new_n == 0) {
411416 self.free(old_mem);
412 const ptr = comptime std.mem.alignBackward(usize, math.maxInt(usize), Slice.alignment);
413 return @as([*]align(Slice.alignment) T, @ptrFromInt(ptr))[0..0];
417 const alignment = slice_info.alignment orelse @alignOf(T);
418 const addr = comptime std.mem.alignBackward(usize, math.maxInt(usize), alignment);
419 const ptr: *align(alignment) [0]T = @ptrFromInt(addr);
420 return ptr;
414421 }
415422
416423 const old_byte_slice = mem.sliceAsBytes(old_mem);
417 const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return Error.OutOfMemory;
424 const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return error.OutOfMemory;
418425 // Note: can't set shrunk memory to undefined as memory shouldn't be modified on realloc failure
419 if (self.rawRemap(old_byte_slice, .fromByteUnits(Slice.alignment), byte_count, return_address)) |p| {
420 const new_bytes: []align(Slice.alignment) u8 = @alignCast(p[0..byte_count]);
421 return mem.bytesAsSlice(T, new_bytes);
426 if (self.rawRemap(old_byte_slice, .fromByteUnits(slice_info.alignment orelse @alignOf(T)), byte_count, return_address)) |p| {
427 return @ptrCast(@alignCast(p[0..byte_count]));
422428 }
423429
424 const new_mem = self.rawAlloc(byte_count, .fromByteUnits(Slice.alignment), return_address) orelse
430 const new_mem = self.rawAlloc(byte_count, .fromByteUnits(slice_info.alignment orelse @alignOf(T)), return_address) orelse
425431 return error.OutOfMemory;
426432 const copy_len = @min(byte_count, old_byte_slice.len);
427433 @memcpy(new_mem[0..copy_len], old_byte_slice[0..copy_len]);
428434 @memset(old_byte_slice, undefined);
429 self.rawFree(old_byte_slice, .fromByteUnits(Slice.alignment), return_address);
435 self.rawFree(old_byte_slice, .fromByteUnits(slice_info.alignment orelse @alignOf(T)), return_address);
430436
431 const new_bytes: []align(Slice.alignment) u8 = @alignCast(new_mem[0..byte_count]);
432 return mem.bytesAsSlice(T, new_bytes);
437 return @ptrCast(@alignCast(new_mem[0..byte_count]));
433438}
434439
435440/// Free an array allocated with `alloc`.
436441/// If memory has length 0, free is a no-op.
437442/// To free a single item, see `destroy`.
438443pub fn free(self: Allocator, memory: anytype) void {
439 const Slice = @typeInfo(@TypeOf(memory)).pointer;
440 const bytes = mem.sliceAsBytes(memory);
441 const bytes_len = bytes.len + if (Slice.sentinel() != null) @sizeOf(Slice.child) else 0;
442 if (bytes_len == 0) return;
443 const non_const_ptr = @constCast(bytes.ptr);
444 @memset(non_const_ptr[0..bytes_len], undefined);
445 self.rawFree(non_const_ptr[0..bytes_len], .fromByteUnits(Slice.alignment), @returnAddress());
444 const slice_info = @typeInfo(@TypeOf(memory)).pointer;
445 comptime assert(slice_info.size == .slice);
446 const mem_with_sent = memory[0 .. memory.len + @intFromBool(slice_info.sentinel() != null)];
447 const bytes: []u8 = @ptrCast(@constCast(mem_with_sent));
448 if (bytes.len == 0) return;
449 @memset(bytes, undefined);
450 self.rawFree(bytes, .fromByteUnits(slice_info.alignment orelse @alignOf(slice_info.child)), @returnAddress());
446451}
447452
448453/// Copies `m` to newly allocated memory. Caller owns the memory.
lib/std/meta.zig+2-2
......@@ -63,7 +63,7 @@ pub fn alignment(comptime T: type) comptime_int {
6363 .pointer, .@"fn" => alignment(info.child),
6464 else => @alignOf(T),
6565 },
66 .pointer => |info| info.alignment,
66 .pointer => |info| info.alignment orelse @alignOf(info.child),
6767 else => @alignOf(T),
6868 };
6969}
......@@ -315,7 +315,7 @@ test declarationInfo {
315315 try testing.expect(comptime mem.eql(u8, info.name, "a"));
316316 }
317317}
318pub fn fields(comptime T: type) switch (@typeInfo(T)) {
318pub inline fn fields(comptime T: type) switch (@typeInfo(T)) {
319319 .@"struct" => []const Type.StructField,
320320 .@"union" => []const Type.UnionField,
321321 .@"enum" => []const Type.EnumField,
lib/std/multi_array_list.zig+15-9
......@@ -19,7 +19,11 @@ const testing = std.testing;
1919/// For unions you can call `.items(.tags)` or `.items(.data)`.
2020pub fn MultiArrayList(comptime T: type) type {
2121 return struct {
22 bytes: [*]align(@alignOf(T)) u8 = undefined,
22 /// This pointer is always aligned to the boundary `sizes.big_align`; this is not specified
23 /// in the type to avoid `MultiArrayList(T)` depending on the alignment of `T` because this
24 /// can lead to dependency loops. See `allocatedBytes` which `@alignCast`s this pointer to
25 /// the correct type.
26 bytes: [*]u8 = undefined,
2327 len: usize = 0,
2428 capacity: usize = 0,
2529
......@@ -133,10 +137,8 @@ pub fn MultiArrayList(comptime T: type) type {
133137 if (self.ptrs.len == 0 or self.capacity == 0) {
134138 return .{};
135139 }
136 const unaligned_ptr = self.ptrs[sizes.fields[0]];
137 const aligned_ptr: [*]align(@alignOf(Elem)) u8 = @alignCast(unaligned_ptr);
138140 return .{
139 .bytes = aligned_ptr,
141 .bytes = self.ptrs[sizes.fields[0]],
140142 .len = self.len,
141143 .capacity = self.capacity,
142144 };
......@@ -179,6 +181,7 @@ pub fn MultiArrayList(comptime T: type) type {
179181 const fields = meta.fields(Elem);
180182 /// `sizes.bytes` is an array of @sizeOf each T field. Sorted by alignment, descending.
181183 /// `sizes.fields` is an array mapping from `sizes.bytes` array index to field index.
184 /// `sizes.big_align` is the overall alignment of the allocation, which equals the maximum field alignment.
182185 const sizes = blk: {
183186 const Data = struct {
184187 size: usize,
......@@ -186,12 +189,14 @@ pub fn MultiArrayList(comptime T: type) type {
186189 alignment: usize,
187190 };
188191 var data: [fields.len]Data = undefined;
192 var big_align: usize = 1;
189193 for (fields, 0..) |field_info, i| {
190194 data[i] = .{
191195 .size = @sizeOf(field_info.type),
192196 .size_index = i,
193 .alignment = if (@sizeOf(field_info.type) == 0) 1 else field_info.alignment,
197 .alignment = field_info.alignment orelse @alignOf(field_info.type),
194198 };
199 big_align = @max(big_align, data[i].alignment);
195200 }
196201 const Sort = struct {
197202 fn lessThan(context: void, lhs: Data, rhs: Data) bool {
......@@ -210,6 +215,7 @@ pub fn MultiArrayList(comptime T: type) type {
210215 break :blk .{
211216 .bytes = sizes_bytes,
212217 .fields = field_indexes,
218 .big_align = mem.Alignment.fromByteUnits(big_align),
213219 };
214220 };
215221
......@@ -452,7 +458,7 @@ pub fn MultiArrayList(comptime T: type) type {
452458 assert(new_len <= self.capacity);
453459 assert(new_len <= self.len);
454460
455 const other_bytes = gpa.alignedAlloc(u8, .of(Elem), capacityInBytes(new_len)) catch {
461 const other_bytes = gpa.alignedAlloc(u8, sizes.big_align, capacityInBytes(new_len)) catch {
456462 const self_slice = self.slice();
457463 inline for (fields, 0..) |field_info, i| {
458464 if (@sizeOf(field_info.type) != 0) {
......@@ -533,7 +539,7 @@ pub fn MultiArrayList(comptime T: type) type {
533539 /// `new_capacity` must be greater or equal to `len`.
534540 pub fn setCapacity(self: *Self, gpa: Allocator, new_capacity: usize) Allocator.Error!void {
535541 assert(new_capacity >= self.len);
536 const new_bytes = try gpa.alignedAlloc(u8, .of(Elem), capacityInBytes(new_capacity));
542 const new_bytes = try gpa.alignedAlloc(u8, sizes.big_align, capacityInBytes(new_capacity));
537543 if (self.len == 0) {
538544 gpa.free(self.allocatedBytes());
539545 self.bytes = new_bytes.ptr;
......@@ -650,8 +656,8 @@ pub fn MultiArrayList(comptime T: type) type {
650656 return elem_bytes * capacity;
651657 }
652658
653 fn allocatedBytes(self: Self) []align(@alignOf(Elem)) u8 {
654 return self.bytes[0..capacityInBytes(self.capacity)];
659 fn allocatedBytes(self: Self) []align(sizes.big_align.toByteUnits()) u8 {
660 return @alignCast(self.bytes[0..capacityInBytes(self.capacity)]);
655661 }
656662
657663 fn FieldType(comptime field: Field) type {
lib/std/os/linux.zig+1-1
......@@ -7113,7 +7113,7 @@ pub const io_uring_buf_reg = extern struct {
71137113 flags: Flags,
71147114 resv: [3]u64,
71157115
7116 pub const Flags = packed struct {
7116 pub const Flags = packed struct(u16) {
71177117 _0: u1 = 0,
71187118 /// Incremental buffer consumption.
71197119 inc: bool,
lib/std/os/windows.zig+5-5
......@@ -4160,7 +4160,7 @@ pub const RUNTIME_FUNCTION = switch (native_arch) {
41604160 BeginAddress: DWORD,
41614161 DUMMYUNIONNAME: extern union {
41624162 UnwindData: DWORD,
4163 DUMMYSTRUCTNAME: packed struct {
4163 DUMMYSTRUCTNAME: packed struct(u32) {
41644164 Flag: u2,
41654165 FunctionLength: u11,
41664166 Ret: u2,
......@@ -4177,7 +4177,7 @@ pub const RUNTIME_FUNCTION = switch (native_arch) {
41774177 BeginAddress: DWORD,
41784178 DUMMYUNIONNAME: extern union {
41794179 UnwindData: DWORD,
4180 DUMMYSTRUCTNAME: packed struct {
4180 DUMMYSTRUCTNAME: packed struct(u32) {
41814181 Flag: u2,
41824182 FunctionLength: u11,
41834183 RegF: u3,
......@@ -5013,7 +5013,7 @@ pub const KUSER_SHARED_DATA = extern struct {
50135013 KdDebuggerEnabled: BOOLEAN,
50145014 DummyUnion1: extern union {
50155015 MitigationPolicies: UCHAR,
5016 Alt: packed struct {
5016 Alt: packed struct(u8) {
50175017 NXSupportPolicy: u2,
50185018 SEHValidationPolicy: u2,
50195019 CurDirDevicesSkippedForDlls: u2,
......@@ -5029,7 +5029,7 @@ pub const KUSER_SHARED_DATA = extern struct {
50295029 SafeBootMode: BOOLEAN,
50305030 DummyUnion2: extern union {
50315031 VirtualizationFlags: UCHAR,
5032 Alt: packed struct {
5032 Alt: packed struct(u8) {
50335033 ArchStartedInEl2: u1,
50345034 QcSlIsSupported: u1,
50355035 SpareBits: u6,
......@@ -5038,7 +5038,7 @@ pub const KUSER_SHARED_DATA = extern struct {
50385038 Reserved12: [2]UCHAR,
50395039 DummyUnion3: extern union {
50405040 SharedDataFlags: ULONG,
5041 Alt: packed struct {
5041 Alt: packed struct(u32) {
50425042 DbgErrorPortPresent: u1,
50435043 DbgElevationEnabled: u1,
50445044 DbgVirtEnabled: u1,
lib/std/pdb.zig+2-2
......@@ -332,7 +332,7 @@ pub const ProcSym = extern struct {
332332 name: [1]u8, // null-terminated
333333};
334334
335pub const ProcSymFlags = packed struct {
335pub const ProcSymFlags = packed struct(u8) {
336336 has_fp: bool,
337337 has_iret: bool,
338338 has_fret: bool,
......@@ -373,7 +373,7 @@ pub const LineFragmentHeader = extern struct {
373373 code_size: u32,
374374};
375375
376pub const LineFlags = packed struct {
376pub const LineFlags = packed struct(u16) {
377377 /// CV_LINES_HAVE_COLUMNS
378378 have_columns: bool,
379379 unused: u15,
lib/std/testing.zig+2-3
......@@ -950,9 +950,8 @@ test "expectEqualDeep primitive type" {
950950}
951951
952952test "expectEqualDeep pointer" {
953 const a = 1;
954 const b = 1;
955 try expectEqualDeep(&a, &b);
953 try comptime expectEqualDeep(&1, &1);
954 try expectEqualDeep(&@as(u32, 1), &@as(u32, 1));
956955}
957956
958957test "expectEqualDeep composite type" {
lib/std/zig.zig+11-2
......@@ -837,6 +837,10 @@ pub const SimpleComptimeReason = enum(u32) {
837837 tuple_field_types,
838838 enum_field_names,
839839 enum_field_values,
840 union_enum_tag_type,
841 enum_int_tag_type,
842 packed_struct_backing_int_type,
843 packed_union_backing_int_type,
840844
841845 // Evaluating at comptime because decl/field name must be comptime-known.
842846 decl_name,
......@@ -864,7 +868,7 @@ pub const SimpleComptimeReason = enum(u32) {
864868 casted_to_comptime_enum,
865869 casted_to_comptime_int,
866870 casted_to_comptime_float,
867 panic_handler,
871 std_builtin_decl,
868872
869873 pub fn message(r: SimpleComptimeReason) []const u8 {
870874 return switch (r) {
......@@ -925,6 +929,11 @@ pub const SimpleComptimeReason = enum(u32) {
925929 .enum_field_names => "enum field names must be comptime-known",
926930 .enum_field_values => "enum field values must be comptime-known",
927931
932 .union_enum_tag_type => "enum tag type of union must be comptime-known",
933 .enum_int_tag_type => "integer tag type of enum must be comptime-known",
934 .packed_struct_backing_int_type => "packed struct backing integer type must be comptime-known",
935 .packed_union_backing_int_type => "packed struct backing integer type must be comptime-known",
936
928937 .decl_name => "declaration name must be comptime-known",
929938 .field_name => "field name must be comptime-known",
930939 .tuple_field_index => "tuple field index must be comptime-known",
......@@ -948,7 +957,7 @@ pub const SimpleComptimeReason = enum(u32) {
948957 .casted_to_comptime_enum => "value casted to enum with 'comptime_int' tag type must be comptime-known",
949958 .casted_to_comptime_int => "value casted to 'comptime_int' must be comptime-known",
950959 .casted_to_comptime_float => "value casted to 'comptime_float' must be comptime-known",
951 .panic_handler => "panic handler must be comptime-known",
960 .std_builtin_decl => "'std.builtin' declaration values must be comptime-known",
952961 // zig fmt: on
953962 };
954963 }
lib/std/zig/Ast.zig+4-4
......@@ -175,10 +175,10 @@ pub fn parseTokens(
175175 .source = source,
176176 .gpa = gpa,
177177 .tokens = tokens,
178 .errors = .{},
179 .nodes = .{},
180 .extra_data = .{},
181 .scratch = .{},
178 .errors = .empty,
179 .nodes = .empty,
180 .extra_data = .empty,
181 .scratch = .empty,
182182 .tok_i = 0,
183183 };
184184 defer parser.errors.deinit(gpa);
lib/std/zig/AstGen.zig+530-1102
......@@ -1780,7 +1780,7 @@ fn structInitExpr(
17801780 try gop.value_ptr.append(sfba_allocator, name_token);
17811781 any_duplicate = true;
17821782 } else {
1783 gop.value_ptr.* = .{};
1783 gop.value_ptr.* = .empty;
17841784 try gop.value_ptr.append(sfba_allocator, name_token);
17851785 }
17861786 }
......@@ -3975,81 +3975,67 @@ fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.
39753975 return rvalue(gz, ri, result, node);
39763976}
39773977
3978const WipMembers = struct {
3979 payload: *ArrayList(u32),
3980 payload_top: usize,
3981 field_bits_start: u32,
3982 fields_start: u32,
3983 fields_end: u32,
3984 decl_index: u32 = 0,
3985 field_index: u32 = 0,
3986
3987 const Self = @This();
3988
3989 fn init(gpa: Allocator, payload: *ArrayList(u32), decl_count: u32, field_count: u32, comptime bits_per_field: u32, comptime max_field_size: u32) Allocator.Error!Self {
3990 const payload_top: u32 = @intCast(payload.items.len);
3991 const field_bits_start = payload_top + decl_count;
3992 const fields_start = field_bits_start + if (bits_per_field > 0) blk: {
3993 const fields_per_u32 = 32 / bits_per_field;
3994 break :blk (field_count + fields_per_u32 - 1) / fields_per_u32;
3995 } else 0;
3996 const payload_end = fields_start + field_count * max_field_size;
3997 try payload.resize(gpa, payload_end);
3978const Scratch = struct {
3979 astgen: *AstGen,
3980 scratch_top: u32,
3981 fn init(astgen: *AstGen) Scratch {
39983982 return .{
3999 .payload = payload,
4000 .payload_top = payload_top,
4001 .field_bits_start = field_bits_start,
4002 .fields_start = fields_start,
4003 .fields_end = fields_start,
3983 .astgen = astgen,
3984 .scratch_top = @intCast(astgen.scratch.items.len),
40043985 };
40053986 }
4006
4007 fn nextDecl(self: *Self, decl_inst: Zir.Inst.Index) void {
4008 self.payload.items[self.payload_top + self.decl_index] = @intFromEnum(decl_inst);
4009 self.decl_index += 1;
3987 fn reset(s: *Scratch) void {
3988 s.astgen.scratch.shrinkRetainingCapacity(s.scratch_top);
3989 s.* = undefined;
40103990 }
4011
4012 fn nextField(self: *Self, comptime bits_per_field: u32, bits: [bits_per_field]bool) void {
4013 const fields_per_u32 = 32 / bits_per_field;
4014 const index = self.field_bits_start + self.field_index / fields_per_u32;
4015 assert(index < self.fields_start);
4016 var bit_bag: u32 = if (self.field_index % fields_per_u32 == 0) 0 else self.payload.items[index];
4017 bit_bag >>= bits_per_field;
4018 comptime var i = 0;
4019 inline while (i < bits_per_field) : (i += 1) {
4020 bit_bag |= @as(u32, @intFromBool(bits[i])) << (32 - bits_per_field + i);
4021 }
4022 self.payload.items[index] = bit_bag;
4023 self.field_index += 1;
3991 fn addSlice(s: *Scratch, len: u32) Allocator.Error!Slice {
3992 const start: u32 = @intCast(s.astgen.scratch.items.len);
3993 try s.astgen.scratch.resize(s.astgen.gpa, start + len);
3994 return .{ .start = start, .len = len };
40243995 }
4025
4026 fn appendToField(self: *Self, data: u32) void {
4027 assert(self.fields_end < self.payload.items.len);
4028 self.payload.items[self.fields_end] = data;
4029 self.fields_end += 1;
3996 fn addOptionalSlice(s: *Scratch, present: bool, len: u32) Allocator.Error!?Slice {
3997 if (!present) return null;
3998 return try addSlice(s, len);
40303999 }
4031
4032 fn finishBits(self: *Self, comptime bits_per_field: u32) void {
4033 if (bits_per_field > 0) {
4034 const fields_per_u32 = 32 / bits_per_field;
4035 const empty_field_slots = fields_per_u32 - (self.field_index % fields_per_u32);
4036 if (self.field_index > 0 and empty_field_slots < fields_per_u32) {
4037 const index = self.field_bits_start + self.field_index / fields_per_u32;
4038 self.payload.items[index] >>= @intCast(empty_field_slots * bits_per_field);
4039 }
4040 }
4000 fn appendBodyWithFixups(s: *Scratch, body: []const Zir.Inst.Index) Allocator.Error!u32 {
4001 const len = countBodyLenAfterFixups(s.astgen, body);
4002 try s.astgen.scratch.ensureUnusedCapacity(s.astgen.gpa, len);
4003 appendBodyWithFixupsArrayList(s.astgen, &s.astgen.scratch, body);
4004 return len;
40414005 }
4042
4043 fn declsSlice(self: *Self) []u32 {
4044 return self.payload.items[self.payload_top..][0..self.decl_index];
4006 /// Returns the slice containing all data added to this `Scratch`.
4007 fn all(s: *Scratch) Slice {
4008 const len = s.astgen.scratch.items.len - s.scratch_top;
4009 return .{ .start = s.scratch_top, .len = @intCast(len) };
40454010 }
4011 const Slice = struct {
4012 start: u32,
4013 len: u32,
4014 fn get(s: Slice, astgen: *AstGen) []u32 {
4015 return astgen.scratch.items[s.start..][0..s.len];
4016 }
4017 };
4018};
40464019
4047 fn fieldsSlice(self: *Self) []u32 {
4048 return self.payload.items[self.field_bits_start..self.fields_end];
4049 }
4020const WipDecls = struct {
4021 astgen: *AstGen,
4022 slice: Scratch.Slice,
4023 index: u32,
40504024
4051 fn deinit(self: *Self) void {
4052 self.payload.items.len = self.payload_top;
4025 fn init(scratch: *Scratch, decls_len: u32) Allocator.Error!WipDecls {
4026 return .{
4027 .astgen = scratch.astgen,
4028 .slice = try scratch.addSlice(decls_len),
4029 .index = 0,
4030 };
4031 }
4032 fn finish(wip: *WipDecls) void {
4033 assert(wip.index == wip.slice.len);
4034 wip.* = undefined;
4035 }
4036 fn nextDecl(wip: *WipDecls, decl_inst: Zir.Inst.Index) void {
4037 wip.slice.get(wip.astgen)[wip.index] = @intFromEnum(decl_inst);
4038 wip.index += 1;
40534039 }
40544040};
40554041
......@@ -4057,7 +4043,7 @@ fn fnDecl(
40574043 astgen: *AstGen,
40584044 gz: *GenZir,
40594045 scope: *Scope,
4060 wip_members: *WipMembers,
4046 wip_decls: *WipDecls,
40614047 decl_node: Ast.Node.Index,
40624048 body_node: Ast.Node.OptionalIndex,
40634049 fn_proto: Ast.full.FnProto,
......@@ -4133,7 +4119,7 @@ fn fnDecl(
41334119 assert(!is_extern); // validated by parser (TODO why???)
41344120 }
41354121
4136 wip_members.nextDecl(decl_inst);
4122 wip_decls.nextDecl(decl_inst);
41374123
41384124 var type_gz: GenZir = .{
41394125 .is_comptime = true,
......@@ -4488,7 +4474,7 @@ fn globalVarDecl(
44884474 astgen: *AstGen,
44894475 gz: *GenZir,
44904476 scope: *Scope,
4491 wip_members: *WipMembers,
4477 wip_decls: *WipDecls,
44924478 node: Ast.Node.Index,
44934479 var_decl: Ast.full.VarDecl,
44944480) InnerError!void {
......@@ -4533,7 +4519,7 @@ fn globalVarDecl(
45334519 const decl_column = astgen.source_column;
45344520
45354521 const decl_inst = try gz.makeDeclaration(node);
4536 wip_members.nextDecl(decl_inst);
4522 wip_decls.nextDecl(decl_inst);
45374523
45384524 if (var_decl.ast.init_node.unwrap()) |init_node| {
45394525 if (is_extern) {
......@@ -4635,7 +4621,7 @@ fn comptimeDecl(
46354621 astgen: *AstGen,
46364622 gz: *GenZir,
46374623 scope: *Scope,
4638 wip_members: *WipMembers,
4624 wip_decls: *WipDecls,
46394625 node: Ast.Node.Index,
46404626) InnerError!void {
46414627 const tree = astgen.tree;
......@@ -4650,7 +4636,7 @@ fn comptimeDecl(
46504636 // Up top so the ZIR instruction index marks the start range of this
46514637 // top-level declaration.
46524638 const decl_inst = try gz.makeDeclaration(node);
4653 wip_members.nextDecl(decl_inst);
4639 wip_decls.nextDecl(decl_inst);
46544640 astgen.advanceSourceCursorToNode(node);
46554641
46564642 // This is just needed for the `setDeclaration` call.
......@@ -4698,7 +4684,7 @@ fn testDecl(
46984684 astgen: *AstGen,
46994685 gz: *GenZir,
47004686 scope: *Scope,
4701 wip_members: *WipMembers,
4687 wip_decls: *WipDecls,
47024688 node: Ast.Node.Index,
47034689) InnerError!void {
47044690 const tree = astgen.tree;
......@@ -4714,7 +4700,7 @@ fn testDecl(
47144700 // top-level declaration.
47154701 const decl_inst = try gz.makeDeclaration(node);
47164702
4717 wip_members.nextDecl(decl_inst);
4703 wip_decls.nextDecl(decl_inst);
47184704 astgen.advanceSourceCursorToNode(node);
47194705
47204706 // This is just needed for the `setDeclaration` call.
......@@ -4914,7 +4900,7 @@ fn structDeclInner(
49144900 node: Ast.Node.Index,
49154901 container_decl: Ast.full.ContainerDecl,
49164902 layout: std.builtin.Type.ContainerLayout,
4917 backing_int_node: Ast.Node.OptionalIndex,
4903 maybe_backing_int_node: Ast.Node.OptionalIndex,
49184904 name_strat: Zir.Inst.NameStrategy,
49194905) InnerError!Zir.Inst.Ref {
49204906 const astgen = gz.astgen;
......@@ -4930,27 +4916,29 @@ fn structDeclInner(
49304916 if (node == .root) {
49314917 return astgen.failNode(tuple_field_node, "file cannot be a tuple", .{});
49324918 } else {
4933 return tupleDecl(gz, scope, node, container_decl, layout, backing_int_node);
4919 return tupleDecl(gz, scope, node, container_decl, layout, maybe_backing_int_node);
49344920 }
49354921 }
49364922
4923 astgen.advanceSourceCursorToNode(node);
4924
49374925 const decl_inst = try gz.reserveInstructionIndex();
49384926
4939 if (container_decl.ast.members.len == 0 and backing_int_node == .none) {
4927 if (container_decl.ast.members.len == 0 and maybe_backing_int_node == .none) {
49404928 try gz.setStruct(decl_inst, .{
49414929 .src_node = node,
4930 .name_strat = name_strat,
49424931 .layout = layout,
4943 .captures_len = 0,
4944 .fields_len = 0,
4932 .backing_int_type_body_len = null,
49454933 .decls_len = 0,
4946 .has_backing_int = false,
4947 .known_non_opv = false,
4948 .known_comptime_only = false,
4934 .fields_len = 0,
4935 .any_field_aligns = false,
4936 .any_field_defaults = false,
49494937 .any_comptime_fields = false,
4950 .any_default_inits = false,
4951 .any_aligned_fields = false,
4952 .fields_hash = std.zig.hashSrc(@tagName(layout)),
4953 .name_strat = name_strat,
4938 .fields_hash = @splat(0),
4939 .captures = &.{},
4940 .capture_names = &.{},
4941 .remaining = &.{},
49544942 });
49554943 return decl_inst.toRef();
49564944 }
......@@ -4967,7 +4955,6 @@ fn structDeclInner(
49674955 // The struct_decl instruction introduces a scope in which the decls of the struct
49684956 // are in scope, so that field types, alignments, and default value expressions
49694957 // can refer to decls within the struct itself.
4970 astgen.advanceSourceCursorToNode(node);
49714958 var block_scope: GenZir = .{
49724959 .parent = &namespace.base,
49734960 .decl_node_index = node,
......@@ -4979,197 +4966,134 @@ fn structDeclInner(
49794966 };
49804967 defer block_scope.unstack();
49814968
4982 const scratch_top = astgen.scratch.items.len;
4983 defer astgen.scratch.items.len = scratch_top;
4984
4985 var backing_int_body_len: usize = 0;
4986 const backing_int_ref: Zir.Inst.Ref = blk: {
4987 if (backing_int_node.unwrap()) |arg| {
4988 if (layout != .@"packed") {
4989 return astgen.failNode(arg, "non-packed struct does not support backing integer type", .{});
4990 } else {
4991 const backing_int_ref = try typeExpr(&block_scope, &namespace.base, arg);
4992 if (!block_scope.isEmpty()) {
4993 if (!block_scope.endsWithNoReturn()) {
4994 _ = try block_scope.addBreak(.break_inline, decl_inst, backing_int_ref);
4995 }
4996
4997 const body = block_scope.instructionsSlice();
4998 const old_scratch_len = astgen.scratch.items.len;
4999 try astgen.scratch.ensureUnusedCapacity(gpa, countBodyLenAfterFixups(astgen, body));
5000 appendBodyWithFixupsArrayList(astgen, &astgen.scratch, body);
5001 backing_int_body_len = astgen.scratch.items.len - old_scratch_len;
5002 block_scope.instructions.items.len = block_scope.instructions_top;
5003 }
5004 break :blk backing_int_ref;
5005 }
5006 } else {
5007 break :blk .none;
5008 }
5009 };
4969 const scan_result = try astgen.scanContainer(&namespace, container_decl.ast.members, .@"struct");
50104970
5011 const decl_count = try astgen.scanContainer(&namespace, container_decl.ast.members, .@"struct");
5012 const field_count: u32 = @intCast(container_decl.ast.members.len - decl_count);
4971 var scratch: Scratch = .init(astgen);
4972 defer scratch.reset();
50134973
5014 const bits_per_field = 4;
5015 const max_field_size = 5;
5016 var wip_members = try WipMembers.init(gpa, &astgen.scratch, decl_count, field_count, bits_per_field, max_field_size);
5017 defer wip_members.deinit();
4974 // Replicate the structure of the ZIR trailing data in `scratch`
4975 var wip_decls: WipDecls = try .init(&scratch, scan_result.decls_len);
4976 const field_names = try scratch.addSlice(scan_result.fields_len);
4977 const field_type_body_lens = try scratch.addSlice(scan_result.fields_len);
4978 const field_align_body_lens = try scratch.addOptionalSlice(scan_result.any_field_aligns, scan_result.fields_len);
4979 const field_default_body_lens = try scratch.addOptionalSlice(scan_result.any_field_values, scan_result.fields_len);
4980 const field_comptime_bits = try scratch.addOptionalSlice(
4981 scan_result.any_comptime_fields,
4982 std.math.divCeil(u32, scan_result.fields_len, 32) catch unreachable,
4983 );
4984 if (field_comptime_bits) |bits| @memset(bits.get(astgen), 0);
50184985
5019 // We will use the scratch buffer, starting here, for the bodies:
5020 // bodies: { // for every fields_len
5021 // field_type_body_inst: Inst, // for each field_type_body_len
5022 // align_body_inst: Inst, // for each align_body_len
5023 // init_body_inst: Inst, // for each init_body_len
5024 // }
5025 // Note that the scratch buffer is simultaneously being used by WipMembers, however
5026 // it will not access any elements beyond this point in the ArrayList. It also
5027 // accesses via the ArrayList items field so it can handle the scratch buffer being
5028 // reallocated.
5029 // No defer needed here because it is handled by `wip_members.deinit()` above.
5030 const bodies_start = astgen.scratch.items.len;
4986 // Before any field bodies comes the backing int type, if specified.
4987 const backing_int_type_body_len: ?u32 = if (maybe_backing_int_node.unwrap()) |backing_int_node| len: {
4988 if (layout != .@"packed") return astgen.failNode(
4989 backing_int_node,
4990 "non-packed struct does not support backing integer type",
4991 .{},
4992 );
4993 const type_ref = try typeExpr(&block_scope, &namespace.base, backing_int_node);
4994 if (!block_scope.endsWithNoReturn()) {
4995 _ = try block_scope.addBreak(.break_inline, decl_inst, type_ref);
4996 }
4997 const body_len = try scratch.appendBodyWithFixups(block_scope.instructionsSlice());
4998 block_scope.instructions.items.len = block_scope.instructions_top;
4999 break :len body_len;
5000 } else null;
50315001
50325002 const old_hasher = astgen.src_hasher;
50335003 defer astgen.src_hasher = old_hasher;
5034 astgen.src_hasher = std.zig.SrcHasher.init(.{});
5035 astgen.src_hasher.update(@tagName(layout));
5036 if (backing_int_node.unwrap()) |arg| {
5037 astgen.src_hasher.update(tree.getNodeSource(arg));
5038 }
5004 astgen.src_hasher = .init(.{});
50395005
5040 var known_non_opv = false;
5041 var known_comptime_only = false;
5042 var any_comptime_fields = false;
5043 var any_aligned_fields = false;
5044 var any_default_inits = false;
5006 var next_field_idx: u32 = 0;
50455007 for (container_decl.ast.members) |member_node| {
5046 var member = switch (try containerMember(&block_scope, &namespace.base, &wip_members, member_node)) {
5008 var member = switch (try containerMember(&block_scope, &namespace.base, &wip_decls, member_node)) {
50475009 .decl => continue,
50485010 .field => |field| field,
50495011 };
5012 const field_idx = next_field_idx;
5013 next_field_idx += 1;
50505014
50515015 astgen.src_hasher.update(tree.getNodeSource(member_node));
50525016
5053 const field_name = try astgen.identAsString(member.ast.main_token);
50545017 member.convertToNonTupleLike(astgen.tree);
50555018 assert(!member.ast.tuple_like);
5056 wip_members.appendToField(@intFromEnum(field_name));
5057
5058 const type_expr = member.ast.type_expr.unwrap() orelse {
5059 return astgen.failTok(member.ast.main_token, "struct field missing type", .{});
5060 };
50615019
5062 const field_type = try typeExpr(&block_scope, &namespace.base, type_expr);
5063 const have_type_body = !block_scope.isEmpty();
5064 const have_align = member.ast.align_expr != .none;
5065 const have_value = member.ast.value_expr != .none;
5066 const is_comptime = member.comptime_token != null;
5020 field_names.get(astgen)[field_idx] = @intFromEnum(try astgen.identAsString(member.ast.main_token));
50675021
5068 if (is_comptime) {
5069 switch (layout) {
5070 .@"packed", .@"extern" => return astgen.failTok(member.comptime_token.?, "{s} struct fields cannot be marked comptime", .{@tagName(layout)}),
5071 .auto => any_comptime_fields = true,
5072 }
5073 } else {
5074 known_non_opv = known_non_opv or
5075 nodeImpliesMoreThanOnePossibleValue(tree, type_expr);
5076 known_comptime_only = known_comptime_only or
5077 nodeImpliesComptimeOnly(tree, type_expr);
5078 }
5079 wip_members.nextField(bits_per_field, .{ have_align, have_value, is_comptime, have_type_body });
5080
5081 if (have_type_body) {
5022 {
5023 const type_node = member.ast.type_expr.unwrap() orelse {
5024 return astgen.failTok(member.ast.main_token, "struct field missing type", .{});
5025 };
5026 const type_ref = try typeExpr(&block_scope, &namespace.base, type_node);
50825027 if (!block_scope.endsWithNoReturn()) {
5083 _ = try block_scope.addBreak(.break_inline, decl_inst, field_type);
5028 _ = try block_scope.addBreak(.break_inline, decl_inst, type_ref);
50845029 }
5085 const body = block_scope.instructionsSlice();
5086 const old_scratch_len = astgen.scratch.items.len;
5087 try astgen.scratch.ensureUnusedCapacity(gpa, countBodyLenAfterFixups(astgen, body));
5088 appendBodyWithFixupsArrayList(astgen, &astgen.scratch, body);
5089 wip_members.appendToField(@intCast(astgen.scratch.items.len - old_scratch_len));
5030 const body_len = try scratch.appendBodyWithFixups(block_scope.instructionsSlice());
5031 field_type_body_lens.get(astgen)[field_idx] = body_len;
50905032 block_scope.instructions.items.len = block_scope.instructions_top;
5091 } else {
5092 wip_members.appendToField(@intFromEnum(field_type));
50935033 }
50945034
5095 if (member.ast.align_expr.unwrap()) |align_expr| {
5035 if (member.ast.align_expr.unwrap()) |align_node| {
50965036 if (layout == .@"packed") {
5097 return astgen.failNode(align_expr, "unable to override alignment of packed struct fields", .{});
5037 return astgen.failNode(align_node, "unable to override alignment of packed struct fields", .{});
50985038 }
5099 any_aligned_fields = true;
5100 const align_ref = try expr(&block_scope, &namespace.base, coerced_align_ri, align_expr);
5039 const align_ref = try expr(&block_scope, &namespace.base, coerced_align_ri, align_node);
51015040 if (!block_scope.endsWithNoReturn()) {
51025041 _ = try block_scope.addBreak(.break_inline, decl_inst, align_ref);
51035042 }
5104 const body = block_scope.instructionsSlice();
5105 const old_scratch_len = astgen.scratch.items.len;
5106 try astgen.scratch.ensureUnusedCapacity(gpa, countBodyLenAfterFixups(astgen, body));
5107 appendBodyWithFixupsArrayList(astgen, &astgen.scratch, body);
5108 wip_members.appendToField(@intCast(astgen.scratch.items.len - old_scratch_len));
5043 const body_len = try scratch.appendBodyWithFixups(block_scope.instructionsSlice());
5044 field_align_body_lens.?.get(astgen)[field_idx] = body_len;
51095045 block_scope.instructions.items.len = block_scope.instructions_top;
5046 } else if (field_align_body_lens) |lens| {
5047 lens.get(astgen)[field_idx] = 0;
51105048 }
51115049
5112 if (member.ast.value_expr.unwrap()) |value_expr| {
5113 any_default_inits = true;
5114
5115 // The decl_inst is used as here so that we can easily reconstruct a mapping
5116 // between it and the field type when the fields inits are analyzed.
5117 const ri: ResultInfo = .{ .rl = if (field_type == .none) .none else .{ .coerced_ty = decl_inst.toRef() } };
5118
5119 const default_inst = try expr(&block_scope, &namespace.base, ri, value_expr);
5050 if (member.ast.value_expr.unwrap()) |default_node| {
5051 const ri: ResultInfo = .{ .rl = .{ .coerced_ty = decl_inst.toRef() } };
5052 const default_ref = try expr(&block_scope, &namespace.base, ri, default_node);
51205053 if (!block_scope.endsWithNoReturn()) {
5121 _ = try block_scope.addBreak(.break_inline, decl_inst, default_inst);
5054 _ = try block_scope.addBreak(.break_inline, decl_inst, default_ref);
51225055 }
5123 const body = block_scope.instructionsSlice();
5124 const old_scratch_len = astgen.scratch.items.len;
5125 try astgen.scratch.ensureUnusedCapacity(gpa, countBodyLenAfterFixups(astgen, body));
5126 appendBodyWithFixupsArrayList(astgen, &astgen.scratch, body);
5127 wip_members.appendToField(@intCast(astgen.scratch.items.len - old_scratch_len));
5056 const body_len = try scratch.appendBodyWithFixups(block_scope.instructionsSlice());
5057 field_default_body_lens.?.get(astgen)[field_idx] = body_len;
51285058 block_scope.instructions.items.len = block_scope.instructions_top;
5129 } else if (member.comptime_token) |comptime_token| {
5130 return astgen.failTok(comptime_token, "comptime field without default initialization value", .{});
5059 } else if (field_default_body_lens) |lens| {
5060 lens.get(astgen)[field_idx] = 0;
5061 }
5062
5063 if (member.comptime_token) |comptime_token| {
5064 switch (layout) {
5065 .@"packed", .@"extern" => return astgen.failTok(comptime_token, "{s} struct fields cannot be marked comptime", .{@tagName(layout)}),
5066 .auto => {},
5067 }
5068 if (member.ast.value_expr == .none) {
5069 return astgen.failTok(comptime_token, "comptime field without default initialization value", .{});
5070 }
5071 const mask = @as(u32, 1) << @intCast(field_idx % 32);
5072 field_comptime_bits.?.get(astgen)[field_idx / 32] |= mask;
51315073 }
51325074 }
5075 assert(next_field_idx == scan_result.fields_len);
5076 wip_decls.finish();
51335077
51345078 var fields_hash: std.zig.SrcHash = undefined;
51355079 astgen.src_hasher.final(&fields_hash);
51365080
51375081 try gz.setStruct(decl_inst, .{
51385082 .src_node = node,
5083 .name_strat = name_strat,
51395084 .layout = layout,
5140 .captures_len = @intCast(namespace.captures.count()),
5141 .fields_len = field_count,
5142 .decls_len = decl_count,
5143 .has_backing_int = backing_int_ref != .none,
5144 .known_non_opv = known_non_opv,
5145 .known_comptime_only = known_comptime_only,
5146 .any_comptime_fields = any_comptime_fields,
5147 .any_default_inits = any_default_inits,
5148 .any_aligned_fields = any_aligned_fields,
5085 .backing_int_type_body_len = backing_int_type_body_len,
5086 .decls_len = scan_result.decls_len,
5087 .fields_len = scan_result.fields_len,
5088 .any_field_aligns = scan_result.any_field_aligns,
5089 .any_field_defaults = scan_result.any_field_values,
5090 .any_comptime_fields = scan_result.any_comptime_fields,
51495091 .fields_hash = fields_hash,
5150 .name_strat = name_strat,
5092 .captures = namespace.captures.keys(),
5093 .capture_names = namespace.captures.values(),
5094 .remaining = scratch.all().get(astgen),
51515095 });
51525096
5153 wip_members.finishBits(bits_per_field);
5154 const decls_slice = wip_members.declsSlice();
5155 const fields_slice = wip_members.fieldsSlice();
5156 const bodies_slice = astgen.scratch.items[bodies_start..];
5157 try astgen.extra.ensureUnusedCapacity(gpa, backing_int_body_len + 2 +
5158 decls_slice.len + namespace.captures.count() * 2 + fields_slice.len + bodies_slice.len);
5159 astgen.extra.appendSliceAssumeCapacity(@ptrCast(namespace.captures.keys()));
5160 astgen.extra.appendSliceAssumeCapacity(@ptrCast(namespace.captures.values()));
5161 if (backing_int_ref != .none) {
5162 astgen.extra.appendAssumeCapacity(@intCast(backing_int_body_len));
5163 if (backing_int_body_len == 0) {
5164 astgen.extra.appendAssumeCapacity(@intFromEnum(backing_int_ref));
5165 } else {
5166 astgen.extra.appendSliceAssumeCapacity(astgen.scratch.items[scratch_top..][0..backing_int_body_len]);
5167 }
5168 }
5169 astgen.extra.appendSliceAssumeCapacity(decls_slice);
5170 astgen.extra.appendSliceAssumeCapacity(fields_slice);
5171 astgen.extra.appendSliceAssumeCapacity(bodies_slice);
5172
51735097 block_scope.unstack();
51745098 return decl_inst.toRef();
51755099}
......@@ -5281,11 +5205,29 @@ fn unionDeclInner(
52815205 auto_enum_tok: ?Ast.TokenIndex,
52825206 name_strat: Zir.Inst.NameStrategy,
52835207) InnerError!Zir.Inst.Ref {
5284 const decl_inst = try gz.reserveInstructionIndex();
5285
52865208 const astgen = gz.astgen;
52875209 const gpa = astgen.gpa;
52885210
5211 const explicit_int_or_enum_tag = switch (layout) {
5212 .auto => opt_arg_node != .none,
5213 .@"extern" => if (opt_arg_node.unwrap()) |arg_node| {
5214 return astgen.failNode(arg_node, "{s} union does not support enum tag type", .{@tagName(layout)});
5215 } else false,
5216 .@"packed" => false,
5217 };
5218
5219 if (auto_enum_tok) |t| {
5220 if (layout != .auto) {
5221 return astgen.failTok(t, "{s} union does not support enum tag type", .{@tagName(layout)});
5222 }
5223 }
5224
5225 const is_tagged = explicit_int_or_enum_tag or auto_enum_tok != null;
5226
5227 astgen.advanceSourceCursorToNode(node);
5228
5229 const decl_inst = try gz.reserveInstructionIndex();
5230
52895231 var namespace: Scope.Namespace = .{
52905232 .parent = scope,
52915233 .node = node,
......@@ -5298,7 +5240,6 @@ fn unionDeclInner(
52985240 // The union_decl instruction introduces a scope in which the decls of the union
52995241 // are in scope, so that field types, alignments, and default value expressions
53005242 // can refer to decls within the union itself.
5301 astgen.advanceSourceCursorToNode(node);
53025243 var block_scope: GenZir = .{
53035244 .parent = &namespace.base,
53045245 .decl_node_index = node,
......@@ -5310,42 +5251,42 @@ fn unionDeclInner(
53105251 };
53115252 defer block_scope.unstack();
53125253
5313 const decl_count = try astgen.scanContainer(&namespace, members, .@"union");
5314 const field_count: u32 = @intCast(members.len - decl_count);
5254 const scan_result = try astgen.scanContainer(&namespace, members, .@"union");
53155255
5316 if (layout != .auto and (auto_enum_tok != null or opt_arg_node != .none)) {
5317 if (opt_arg_node.unwrap()) |arg_node| {
5318 return astgen.failNode(arg_node, "{s} union does not support enum tag type", .{@tagName(layout)});
5319 } else {
5320 return astgen.failTok(auto_enum_tok.?, "{s} union does not support enum tag type", .{@tagName(layout)});
5321 }
5322 }
5256 var scratch: Scratch = .init(astgen);
5257 defer scratch.reset();
53235258
5324 const arg_inst: Zir.Inst.Ref = if (opt_arg_node.unwrap()) |arg_node|
5325 try typeExpr(&block_scope, &namespace.base, arg_node)
5326 else
5327 .none;
5259 // Replicate the structure of the ZIR trailing data in `scratch`
5260 var wip_decls: WipDecls = try .init(&scratch, scan_result.decls_len);
5261 const field_names = try scratch.addSlice(scan_result.fields_len);
5262 const field_type_body_lens = try scratch.addSlice(scan_result.fields_len);
5263 const field_align_body_lens = try scratch.addOptionalSlice(scan_result.any_field_aligns, scan_result.fields_len);
5264 const field_value_body_lens = try scratch.addOptionalSlice(scan_result.any_field_values, scan_result.fields_len);
53285265
5329 const bits_per_field = 4;
5330 const max_field_size = 4;
5331 var any_aligned_fields = false;
5332 var wip_members = try WipMembers.init(gpa, &astgen.scratch, decl_count, field_count, bits_per_field, max_field_size);
5333 defer wip_members.deinit();
5266 // Before any field bodies comes the tag/backing type, if specified.
5267 const arg_type_body_len: ?u32 = if (opt_arg_node.unwrap()) |arg_node| len: {
5268 const type_ref = try typeExpr(&block_scope, &namespace.base, arg_node);
5269 if (!block_scope.endsWithNoReturn()) {
5270 _ = try block_scope.addBreak(.break_inline, decl_inst, type_ref);
5271 }
5272 const body_len = try scratch.appendBodyWithFixups(block_scope.instructionsSlice());
5273 block_scope.instructions.items.len = block_scope.instructions_top;
5274 break :len body_len;
5275 } else null;
53345276
53355277 const old_hasher = astgen.src_hasher;
53365278 defer astgen.src_hasher = old_hasher;
5337 astgen.src_hasher = std.zig.SrcHasher.init(.{});
5338 astgen.src_hasher.update(@tagName(layout));
5339 astgen.src_hasher.update(&.{@intFromBool(auto_enum_tok != null)});
5340 if (opt_arg_node.unwrap()) |arg_node| {
5341 astgen.src_hasher.update(astgen.tree.getNodeSource(arg_node));
5342 }
5279 astgen.src_hasher = .init(.{});
53435280
5281 var next_field_idx: u32 = 0;
53445282 for (members) |member_node| {
5345 var member = switch (try containerMember(&block_scope, &namespace.base, &wip_members, member_node)) {
5283 var member = switch (try containerMember(&block_scope, &namespace.base, &wip_decls, member_node)) {
53465284 .decl => continue,
53475285 .field => |field| field,
53485286 };
5287 const field_idx = next_field_idx;
5288 next_field_idx += 1;
5289
53495290 astgen.src_hasher.update(astgen.tree.getNodeSource(member_node));
53505291 member.convertToNonTupleLike(astgen.tree);
53515292 if (member.ast.tuple_like) {
......@@ -5355,97 +5296,91 @@ fn unionDeclInner(
53555296 return astgen.failTok(comptime_token, "union fields cannot be marked comptime", .{});
53565297 }
53575298
5358 const field_name = try astgen.identAsString(member.ast.main_token);
5359 wip_members.appendToField(@intFromEnum(field_name));
5360
5361 const have_type = member.ast.type_expr != .none;
5362 const have_align = member.ast.align_expr != .none;
5363 const have_value = member.ast.value_expr != .none;
5364 const unused = false;
5365 wip_members.nextField(bits_per_field, .{ have_type, have_align, have_value, unused });
5299 field_names.get(astgen)[field_idx] = @intFromEnum(try astgen.identAsString(member.ast.main_token));
53665300
5367 if (member.ast.type_expr.unwrap()) |type_expr| {
5368 const field_type = try typeExpr(&block_scope, &namespace.base, type_expr);
5369 wip_members.appendToField(@intFromEnum(field_type));
5370 } else if (arg_inst == .none and auto_enum_tok == null) {
5301 if (member.ast.type_expr.unwrap()) |type_node| {
5302 const type_ref = try typeExpr(&block_scope, &namespace.base, type_node);
5303 if (!block_scope.endsWithNoReturn()) {
5304 _ = try block_scope.addBreak(.break_inline, decl_inst, type_ref);
5305 }
5306 const body_len = try scratch.appendBodyWithFixups(block_scope.instructionsSlice());
5307 field_type_body_lens.get(astgen)[field_idx] = body_len;
5308 block_scope.instructions.items.len = block_scope.instructions_top;
5309 } else if (!is_tagged) {
53715310 return astgen.failNode(member_node, "union field missing type", .{});
5311 } else {
5312 field_type_body_lens.get(astgen)[field_idx] = 0;
53725313 }
5373 if (member.ast.align_expr.unwrap()) |align_expr| {
5314
5315 if (member.ast.align_expr.unwrap()) |align_node| {
53745316 if (layout == .@"packed") {
5375 return astgen.failNode(align_expr, "unable to override alignment of packed union fields", .{});
5317 return astgen.failNode(align_node, "unable to override alignment of packed union fields", .{});
53765318 }
5377 const align_inst = try expr(&block_scope, &block_scope.base, coerced_align_ri, align_expr);
5378 wip_members.appendToField(@intFromEnum(align_inst));
5379 any_aligned_fields = true;
5380 }
5381 if (member.ast.value_expr.unwrap()) |value_expr| {
5382 if (arg_inst == .none) {
5383 return astgen.failNodeNotes(
5384 node,
5385 "explicitly valued tagged union missing integer tag type",
5386 .{},
5387 &[_]u32{
5388 try astgen.errNoteNode(
5389 value_expr,
5390 "tag value specified here",
5391 .{},
5392 ),
5393 },
5394 );
5319 const align_ref = try expr(&block_scope, &namespace.base, coerced_align_ri, align_node);
5320 if (!block_scope.endsWithNoReturn()) {
5321 _ = try block_scope.addBreak(.break_inline, decl_inst, align_ref);
53955322 }
5396 if (auto_enum_tok == null) {
5397 return astgen.failNodeNotes(
5398 node,
5399 "explicitly valued tagged union requires inferred enum tag type",
5400 .{},
5401 &[_]u32{
5402 try astgen.errNoteNode(
5403 value_expr,
5404 "tag value specified here",
5405 .{},
5406 ),
5407 },
5408 );
5323 const body_len = try scratch.appendBodyWithFixups(block_scope.instructionsSlice());
5324 field_align_body_lens.?.get(astgen)[field_idx] = body_len;
5325 block_scope.instructions.items.len = block_scope.instructions_top;
5326 } else if (field_align_body_lens) |lens| {
5327 lens.get(astgen)[field_idx] = 0;
5328 }
5329
5330 if (member.ast.value_expr.unwrap()) |value_node| {
5331 if (!explicit_int_or_enum_tag) return astgen.failNodeNotes(
5332 node,
5333 "explicitly valued tagged union missing integer tag type",
5334 .{},
5335 &.{try astgen.errNoteNode(value_node, "tag value specified here", .{})},
5336 );
5337 if (auto_enum_tok == null) return astgen.failNodeNotes(
5338 node,
5339 "explicitly valued tagged union requires inferred enum tag type",
5340 .{},
5341 &.{try astgen.errNoteNode(value_node, "tag value specified here", .{})},
5342 );
5343 const ri: ResultInfo = .{ .rl = .{ .coerced_ty = decl_inst.toRef() } };
5344 const value_ref = try expr(&block_scope, &namespace.base, ri, value_node);
5345 if (!block_scope.endsWithNoReturn()) {
5346 _ = try block_scope.addBreak(.break_inline, decl_inst, value_ref);
54095347 }
5410 const tag_value = try expr(&block_scope, &block_scope.base, .{ .rl = .{ .ty = arg_inst } }, value_expr);
5411 wip_members.appendToField(@intFromEnum(tag_value));
5348 const body_len = try scratch.appendBodyWithFixups(block_scope.instructionsSlice());
5349 field_value_body_lens.?.get(astgen)[field_idx] = body_len;
5350 block_scope.instructions.items.len = block_scope.instructions_top;
5351 } else if (field_value_body_lens) |lens| {
5352 lens.get(astgen)[field_idx] = 0;
54125353 }
54135354 }
5355 assert(next_field_idx == scan_result.fields_len);
5356 wip_decls.finish();
54145357
54155358 var fields_hash: std.zig.SrcHash = undefined;
54165359 astgen.src_hasher.final(&fields_hash);
54175360
5418 if (!block_scope.isEmpty()) {
5419 _ = try block_scope.addBreak(.break_inline, decl_inst, .void_value);
5420 }
5421
5422 const body = block_scope.instructionsSlice();
5423 const body_len = astgen.countBodyLenAfterFixups(body);
5424
54255361 try gz.setUnion(decl_inst, .{
54265362 .src_node = node,
5427 .layout = layout,
5428 .tag_type = arg_inst,
5429 .captures_len = @intCast(namespace.captures.count()),
5430 .body_len = body_len,
5431 .fields_len = field_count,
5432 .decls_len = decl_count,
5433 .auto_enum_tag = auto_enum_tok != null,
5434 .any_aligned_fields = any_aligned_fields,
5435 .fields_hash = fields_hash,
54365363 .name_strat = name_strat,
5364 .kind = switch (layout) {
5365 .auto => if (auto_enum_tok == null) l: {
5366 break :l if (opt_arg_node == .none) .auto else .tagged_explicit;
5367 } else l: {
5368 break :l if (opt_arg_node == .none) .tagged_enum else .tagged_enum_explicit;
5369 },
5370 .@"extern" => .@"extern",
5371 .@"packed" => if (opt_arg_node != .none) .packed_explicit else .@"packed",
5372 },
5373 .arg_type_body_len = arg_type_body_len,
5374 .decls_len = scan_result.decls_len,
5375 .fields_len = scan_result.fields_len,
5376 .any_field_aligns = scan_result.any_field_aligns,
5377 .any_field_values = scan_result.any_field_values,
5378 .fields_hash = fields_hash,
5379 .captures = namespace.captures.keys(),
5380 .capture_names = namespace.captures.values(),
5381 .remaining = scratch.all().get(astgen),
54375382 });
54385383
5439 wip_members.finishBits(bits_per_field);
5440 const decls_slice = wip_members.declsSlice();
5441 const fields_slice = wip_members.fieldsSlice();
5442 try astgen.extra.ensureUnusedCapacity(gpa, namespace.captures.count() * 2 + decls_slice.len + body_len + fields_slice.len);
5443 astgen.extra.appendSliceAssumeCapacity(@ptrCast(namespace.captures.keys()));
5444 astgen.extra.appendSliceAssumeCapacity(@ptrCast(namespace.captures.values()));
5445 astgen.extra.appendSliceAssumeCapacity(decls_slice);
5446 astgen.appendBodyWithFixups(body);
5447 astgen.extra.appendSliceAssumeCapacity(fields_slice);
5448
54495384 block_scope.unstack();
54505385 return decl_inst.toRef();
54515386}
......@@ -5494,103 +5429,8 @@ fn containerDecl(
54945429 if (container_decl.layout_token) |t| {
54955430 return astgen.failTok(t, "enums do not support 'packed' or 'extern'; instead provide an explicit integer tag type", .{});
54965431 }
5497 // Count total fields as well as how many have explicitly provided tag values.
5498 const counts = blk: {
5499 var values: usize = 0;
5500 var total_fields: usize = 0;
5501 var decls: usize = 0;
5502 var opt_nonexhaustive_node: Ast.Node.OptionalIndex = .none;
5503 var nonfinal_nonexhaustive = false;
5504 for (container_decl.ast.members) |member_node| {
5505 var member = tree.fullContainerField(member_node) orelse {
5506 decls += 1;
5507 continue;
5508 };
5509 member.convertToNonTupleLike(astgen.tree);
5510 if (member.ast.tuple_like) {
5511 return astgen.failTok(member.ast.main_token, "enum field missing name", .{});
5512 }
5513 if (member.comptime_token) |comptime_token| {
5514 return astgen.failTok(comptime_token, "enum fields cannot be marked comptime", .{});
5515 }
5516 if (member.ast.type_expr.unwrap()) |type_expr| {
5517 return astgen.failNodeNotes(
5518 type_expr,
5519 "enum fields do not have types",
5520 .{},
5521 &[_]u32{
5522 try astgen.errNoteNode(
5523 node,
5524 "consider 'union(enum)' here to make it a tagged union",
5525 .{},
5526 ),
5527 },
5528 );
5529 }
5530 if (member.ast.align_expr.unwrap()) |align_expr| {
5531 return astgen.failNode(align_expr, "enum fields cannot be aligned", .{});
5532 }
55335432
5534 const name_token = member.ast.main_token;
5535 if (mem.eql(u8, tree.tokenSlice(name_token), "_")) {
5536 if (opt_nonexhaustive_node.unwrap()) |nonexhaustive_node| {
5537 return astgen.failNodeNotes(
5538 member_node,
5539 "redundant non-exhaustive enum mark",
5540 .{},
5541 &[_]u32{
5542 try astgen.errNoteNode(
5543 nonexhaustive_node,
5544 "other mark here",
5545 .{},
5546 ),
5547 },
5548 );
5549 }
5550 opt_nonexhaustive_node = member_node.toOptional();
5551 if (member.ast.value_expr.unwrap()) |value_expr| {
5552 return astgen.failNode(value_expr, "'_' is used to mark an enum as non-exhaustive and cannot be assigned a value", .{});
5553 }
5554 continue;
5555 } else if (opt_nonexhaustive_node != .none) {
5556 nonfinal_nonexhaustive = true;
5557 }
5558 total_fields += 1;
5559 if (member.ast.value_expr.unwrap()) |value_expr| {
5560 if (container_decl.ast.arg == .none) {
5561 return astgen.failNode(value_expr, "value assigned to enum tag with inferred tag type", .{});
5562 }
5563 values += 1;
5564 }
5565 }
5566 if (nonfinal_nonexhaustive) {
5567 return astgen.failNode(opt_nonexhaustive_node.unwrap().?, "'_' field of non-exhaustive enum must be last", .{});
5568 }
5569 break :blk .{
5570 .total_fields = total_fields,
5571 .values = values,
5572 .decls = decls,
5573 .nonexhaustive_node = opt_nonexhaustive_node,
5574 };
5575 };
5576 if (counts.nonexhaustive_node != .none and container_decl.ast.arg == .none) {
5577 const nonexhaustive_node = counts.nonexhaustive_node.unwrap().?;
5578 return astgen.failNodeNotes(
5579 node,
5580 "non-exhaustive enum missing integer tag type",
5581 .{},
5582 &[_]u32{
5583 try astgen.errNoteNode(
5584 nonexhaustive_node,
5585 "marked non-exhaustive here",
5586 .{},
5587 ),
5588 },
5589 );
5590 }
5591 // In this case we must generate ZIR code for the tag values, similar to
5592 // how structs are handled above.
5593 const nonexhaustive = counts.nonexhaustive_node != .none;
5433 astgen.advanceSourceCursorToNode(node);
55945434
55955435 const decl_inst = try gz.reserveInstructionIndex();
55965436
......@@ -5605,7 +5445,6 @@ fn containerDecl(
56055445
56065446 // The enum_decl instruction introduces a scope in which the decls of the enum
56075447 // are in scope, so that tag values can refer to decls within the enum itself.
5608 astgen.advanceSourceCursorToNode(node);
56095448 var block_scope: GenZir = .{
56105449 .parent = &namespace.base,
56115450 .decl_node_index = node,
......@@ -5617,104 +5456,127 @@ fn containerDecl(
56175456 };
56185457 defer block_scope.unstack();
56195458
5620 _ = try astgen.scanContainer(&namespace, container_decl.ast.members, .@"enum");
5621 namespace.base.tag = .namespace;
5459 const scan_result = try astgen.scanContainer(&namespace, container_decl.ast.members, .@"enum");
5460 // The name `_` is not actually a field; it marks a non-exhaustive enum.
5461 const fields_len: u32 = scan_result.fields_len - @intFromBool(scan_result.has_underscore_field);
56225462
5623 const arg_inst: Zir.Inst.Ref = if (container_decl.ast.arg.unwrap()) |arg|
5624 try comptimeExpr(&block_scope, &namespace.base, coerced_type_ri, arg, .type)
5625 else
5626 .none;
5463 var scratch: Scratch = .init(astgen);
5464 defer scratch.reset();
56275465
5628 const bits_per_field = 1;
5629 const max_field_size = 2;
5630 var wip_members = try WipMembers.init(gpa, &astgen.scratch, @intCast(counts.decls), @intCast(counts.total_fields), bits_per_field, max_field_size);
5631 defer wip_members.deinit();
5466 // Replicate the structure of the ZIR trailing data in `scratch`
5467 var wip_decls: WipDecls = try .init(&scratch, scan_result.decls_len);
5468 const field_names = try scratch.addSlice(fields_len);
5469 const field_value_body_lens = try scratch.addOptionalSlice(scan_result.any_field_values, fields_len);
5470
5471 // Before any field bodies comes the tag type, if specified.
5472 const tag_type_body_len: ?u32 = if (container_decl.ast.arg.unwrap()) |tag_type_node| len: {
5473 const type_ref = try typeExpr(&block_scope, &namespace.base, tag_type_node);
5474 if (!block_scope.endsWithNoReturn()) {
5475 _ = try block_scope.addBreak(.break_inline, decl_inst, type_ref);
5476 }
5477 const body_len = try scratch.appendBodyWithFixups(block_scope.instructionsSlice());
5478 block_scope.instructions.items.len = block_scope.instructions_top;
5479 break :len body_len;
5480 } else null;
56325481
56335482 const old_hasher = astgen.src_hasher;
56345483 defer astgen.src_hasher = old_hasher;
5635 astgen.src_hasher = std.zig.SrcHasher.init(.{});
5636 if (container_decl.ast.arg.unwrap()) |arg| {
5637 astgen.src_hasher.update(tree.getNodeSource(arg));
5638 }
5639 astgen.src_hasher.update(&.{@intFromBool(nonexhaustive)});
5484 astgen.src_hasher = .init(.{});
56405485
5486 var next_field_idx: u32 = 0;
5487 var opt_nonexhaustive_node: Ast.Node.OptionalIndex = .none;
56415488 for (container_decl.ast.members) |member_node| {
5642 if (member_node.toOptional() == counts.nonexhaustive_node)
5643 continue;
5644 astgen.src_hasher.update(tree.getNodeSource(member_node));
5645 var member = switch (try containerMember(&block_scope, &namespace.base, &wip_members, member_node)) {
5489 var member = switch (try containerMember(&block_scope, &namespace.base, &wip_decls, member_node)) {
56465490 .decl => continue,
56475491 .field => |field| field,
56485492 };
56495493 member.convertToNonTupleLike(astgen.tree);
5650 assert(member.comptime_token == null);
5651 assert(member.ast.type_expr == .none);
5652 assert(member.ast.align_expr == .none);
5494 if (member.ast.tuple_like) return astgen.failTok(member.ast.main_token, "enum field missing name", .{});
5495 if (member.comptime_token) |t| return astgen.failTok(t, "enum fields cannot be marked comptime", .{});
5496 if (member.ast.type_expr.unwrap()) |type_node| {
5497 return astgen.failNodeNotes(type_node, "enum fields do not have types", .{}, &.{
5498 try astgen.errNoteNode(node, "consider 'union(enum)' here to make it a tagged union", .{}),
5499 });
5500 }
5501 if (member.ast.align_expr.unwrap()) |n| return astgen.failNode(n, "enum fields cannot be aligned", .{});
5502 if (mem.eql(u8, tree.tokenSlice(member.ast.main_token), "_")) {
5503 // non-exhaustive mark
5504 assert(scan_result.has_underscore_field);
5505 if (opt_nonexhaustive_node.unwrap()) |prev_node| {
5506 return astgen.failNodeNotes(member_node, "redundant non-exhaustive enum mark", .{}, &.{
5507 try astgen.errNoteNode(prev_node, "other mark here", .{}),
5508 });
5509 }
5510 if (member.ast.value_expr.unwrap()) |value_node| {
5511 return astgen.failNode(value_node, "'_' is used to mark an enum as non-exhaustive and cannot be assigned a value", .{});
5512 }
5513 if (next_field_idx != fields_len) {
5514 return astgen.failNode(member_node, "'_' field of non-exhaustive enum must be last", .{});
5515 }
5516 if (tag_type_body_len == null) {
5517 return astgen.failNodeNotes(node, "non-exhaustive enum missing integer tag type", .{}, &.{
5518 try astgen.errNoteNode(member_node, "marked non-exhaustive here", .{}),
5519 });
5520 }
5521 opt_nonexhaustive_node = member_node.toOptional();
5522 continue;
5523 }
56535524
5654 const field_name = try astgen.identAsString(member.ast.main_token);
5655 wip_members.appendToField(@intFromEnum(field_name));
5525 // This is a real field rather than a non-exhaustive mark.
5526 const field_idx = next_field_idx;
5527 next_field_idx += 1;
56565528
5657 const have_value = member.ast.value_expr != .none;
5658 wip_members.nextField(bits_per_field, .{have_value});
5529 astgen.src_hasher.update(tree.getNodeSource(member_node));
56595530
5660 if (member.ast.value_expr.unwrap()) |value_expr| {
5661 if (arg_inst == .none) {
5662 return astgen.failNodeNotes(
5663 node,
5664 "explicitly valued enum missing integer tag type",
5665 .{},
5666 &[_]u32{
5667 try astgen.errNoteNode(
5668 value_expr,
5669 "tag value specified here",
5670 .{},
5671 ),
5672 },
5673 );
5531 field_names.get(astgen)[field_idx] = @intFromEnum(try astgen.identAsString(member.ast.main_token));
5532
5533 if (member.ast.value_expr.unwrap()) |value_node| {
5534 if (tag_type_body_len == null) {
5535 return astgen.failNodeNotes(node, "explicitly valued enum missing integer tag type", .{}, &.{
5536 try astgen.errNoteNode(value_node, "tag value specified here", .{}),
5537 });
5538 }
5539 const val_ri: ResultInfo = .{ .rl = .{ .coerced_ty = decl_inst.toRef() } };
5540 const value_ref = try expr(&block_scope, &namespace.base, val_ri, value_node);
5541 if (!block_scope.endsWithNoReturn()) {
5542 _ = try block_scope.addBreak(.break_inline, decl_inst, value_ref);
56745543 }
5675 const tag_value_inst = try expr(&block_scope, &namespace.base, .{ .rl = .{ .ty = arg_inst } }, value_expr);
5676 wip_members.appendToField(@intFromEnum(tag_value_inst));
5544 const body_len = try scratch.appendBodyWithFixups(block_scope.instructionsSlice());
5545 field_value_body_lens.?.get(astgen)[field_idx] = body_len;
5546 block_scope.instructions.items.len = block_scope.instructions_top;
5547 } else if (field_value_body_lens) |lens| {
5548 lens.get(astgen)[field_idx] = 0;
56775549 }
56785550 }
5679
5680 if (!block_scope.isEmpty()) {
5681 _ = try block_scope.addBreak(.break_inline, decl_inst, .void_value);
5682 }
5551 assert(scan_result.has_underscore_field == (opt_nonexhaustive_node != .none));
5552 assert(next_field_idx == fields_len);
5553 wip_decls.finish();
56835554
56845555 var fields_hash: std.zig.SrcHash = undefined;
56855556 astgen.src_hasher.final(&fields_hash);
56865557
5687 const body = block_scope.instructionsSlice();
5688 const body_len = astgen.countBodyLenAfterFixups(body);
5689
56905558 try gz.setEnum(decl_inst, .{
56915559 .src_node = node,
5692 .nonexhaustive = nonexhaustive,
5693 .tag_type = arg_inst,
5694 .captures_len = @intCast(namespace.captures.count()),
5695 .body_len = body_len,
5696 .fields_len = @intCast(counts.total_fields),
5697 .decls_len = @intCast(counts.decls),
5698 .fields_hash = fields_hash,
56995560 .name_strat = name_strat,
5561 .tag_type_body_len = tag_type_body_len,
5562 .nonexhaustive = scan_result.has_underscore_field,
5563 .decls_len = scan_result.decls_len,
5564 .fields_len = fields_len,
5565 .any_field_values = scan_result.any_field_values,
5566 .fields_hash = fields_hash,
5567 .captures = namespace.captures.keys(),
5568 .capture_names = namespace.captures.values(),
5569 .remaining = scratch.all().get(astgen),
57005570 });
57015571
5702 wip_members.finishBits(bits_per_field);
5703 const decls_slice = wip_members.declsSlice();
5704 const fields_slice = wip_members.fieldsSlice();
5705 try astgen.extra.ensureUnusedCapacity(gpa, namespace.captures.count() * 2 + decls_slice.len + body_len + fields_slice.len);
5706 astgen.extra.appendSliceAssumeCapacity(@ptrCast(namespace.captures.keys()));
5707 astgen.extra.appendSliceAssumeCapacity(@ptrCast(namespace.captures.values()));
5708 astgen.extra.appendSliceAssumeCapacity(decls_slice);
5709 astgen.appendBodyWithFixups(body);
5710 astgen.extra.appendSliceAssumeCapacity(fields_slice);
5711
57125572 block_scope.unstack();
57135573 return rvalue(gz, ri, decl_inst.toRef(), node);
57145574 },
57155575 .keyword_opaque => {
57165576 assert(container_decl.ast.arg == .none);
57175577
5578 astgen.advanceSourceCursorToNode(node);
5579
57185580 const decl_inst = try gz.reserveInstructionIndex();
57195581
57205582 var namespace: Scope.Namespace = .{
......@@ -5726,7 +5588,6 @@ fn containerDecl(
57265588 };
57275589 defer namespace.deinit(gpa);
57285590
5729 astgen.advanceSourceCursorToNode(node);
57305591 var block_scope: GenZir = .{
57315592 .parent = &namespace.base,
57325593 .decl_node_index = node,
......@@ -5738,36 +5599,34 @@ fn containerDecl(
57385599 };
57395600 defer block_scope.unstack();
57405601
5741 const decl_count = try astgen.scanContainer(&namespace, container_decl.ast.members, .@"opaque");
5602 const scan_result = try astgen.scanContainer(&namespace, container_decl.ast.members, .@"opaque");
57425603
5743 var wip_members = try WipMembers.init(gpa, &astgen.scratch, decl_count, 0, 0, 0);
5744 defer wip_members.deinit();
5604 var scratch: Scratch = .init(astgen);
5605 defer scratch.reset();
5606 var wip_decls: WipDecls = try .init(&scratch, scan_result.decls_len);
57455607
57465608 if (container_decl.layout_token) |layout_token| {
57475609 return astgen.failTok(layout_token, "opaque types do not support 'packed' or 'extern'", .{});
57485610 }
57495611
57505612 for (container_decl.ast.members) |member_node| {
5751 const res = try containerMember(&block_scope, &namespace.base, &wip_members, member_node);
5752 if (res == .field) {
5753 return astgen.failNode(member_node, "opaque types cannot have fields", .{});
5613 switch (try containerMember(&block_scope, &namespace.base, &wip_decls, member_node)) {
5614 .decl => {},
5615 .field => return astgen.failNode(member_node, "opaque types cannot have fields", .{}),
57545616 }
57555617 }
57565618
5619 wip_decls.finish();
5620
57575621 try gz.setOpaque(decl_inst, .{
57585622 .src_node = node,
5759 .captures_len = @intCast(namespace.captures.count()),
5760 .decls_len = decl_count,
57615623 .name_strat = name_strat,
5624 .decls_len = scan_result.decls_len,
5625 .captures = namespace.captures.keys(),
5626 .capture_names = namespace.captures.values(),
5627 .decls = @ptrCast(scratch.all().get(astgen)),
57625628 });
57635629
5764 wip_members.finishBits(0);
5765 const decls_slice = wip_members.declsSlice();
5766 try astgen.extra.ensureUnusedCapacity(gpa, namespace.captures.count() * 2 + decls_slice.len);
5767 astgen.extra.appendSliceAssumeCapacity(@ptrCast(namespace.captures.keys()));
5768 astgen.extra.appendSliceAssumeCapacity(@ptrCast(namespace.captures.values()));
5769 astgen.extra.appendSliceAssumeCapacity(decls_slice);
5770
57715630 block_scope.unstack();
57725631 return rvalue(gz, ri, decl_inst.toRef(), node);
57735632 },
......@@ -5780,7 +5639,7 @@ const ContainerMemberResult = union(enum) { decl, field: Ast.full.ContainerField
57805639fn containerMember(
57815640 gz: *GenZir,
57825641 scope: *Scope,
5783 wip_members: *WipMembers,
5642 wip_decls: *WipDecls,
57845643 member_node: Ast.Node.Index,
57855644) InnerError!ContainerMemberResult {
57865645 const astgen = gz.astgen;
......@@ -5805,13 +5664,13 @@ fn containerMember(
58055664 else
58065665 .none;
58075666
5808 const prev_decl_index = wip_members.decl_index;
5809 astgen.fnDecl(gz, scope, wip_members, member_node, body, full) catch |err| switch (err) {
5667 const prev_decl_index = wip_decls.index;
5668 astgen.fnDecl(gz, scope, wip_decls, member_node, body, full) catch |err| switch (err) {
58105669 error.OutOfMemory => return error.OutOfMemory,
58115670 error.AnalysisFail => {
5812 wip_members.decl_index = prev_decl_index;
5671 wip_decls.index = prev_decl_index;
58135672 try addFailedDeclaration(
5814 wip_members,
5673 wip_decls,
58155674 gz,
58165675 .@"const",
58175676 try astgen.identAsString(full.name_token.?),
......@@ -5828,13 +5687,13 @@ fn containerMember(
58285687 .aligned_var_decl,
58295688 => {
58305689 const full = tree.fullVarDecl(member_node).?;
5831 const prev_decl_index = wip_members.decl_index;
5832 astgen.globalVarDecl(gz, scope, wip_members, member_node, full) catch |err| switch (err) {
5690 const prev_decl_index = wip_decls.index;
5691 astgen.globalVarDecl(gz, scope, wip_decls, member_node, full) catch |err| switch (err) {
58335692 error.OutOfMemory => return error.OutOfMemory,
58345693 error.AnalysisFail => {
5835 wip_members.decl_index = prev_decl_index;
5694 wip_decls.index = prev_decl_index;
58365695 try addFailedDeclaration(
5837 wip_members,
5696 wip_decls,
58385697 gz,
58395698 .@"const", // doesn't really matter
58405699 try astgen.identAsString(full.ast.mut_token + 1),
......@@ -5846,13 +5705,13 @@ fn containerMember(
58465705 },
58475706
58485707 .@"comptime" => {
5849 const prev_decl_index = wip_members.decl_index;
5850 astgen.comptimeDecl(gz, scope, wip_members, member_node) catch |err| switch (err) {
5708 const prev_decl_index = wip_decls.index;
5709 astgen.comptimeDecl(gz, scope, wip_decls, member_node) catch |err| switch (err) {
58515710 error.OutOfMemory => return error.OutOfMemory,
58525711 error.AnalysisFail => {
5853 wip_members.decl_index = prev_decl_index;
5712 wip_decls.index = prev_decl_index;
58545713 try addFailedDeclaration(
5855 wip_members,
5714 wip_decls,
58565715 gz,
58575716 .@"comptime",
58585717 .empty,
......@@ -5863,16 +5722,16 @@ fn containerMember(
58635722 };
58645723 },
58655724 .test_decl => {
5866 const prev_decl_index = wip_members.decl_index;
5725 const prev_decl_index = wip_decls.index;
58675726 // We need to have *some* decl here so that the decl count matches what's expected.
58685727 // Since it doesn't strictly matter *what* this is, let's save ourselves the trouble
58695728 // of duplicating the test name logic, and just assume this is an unnamed test.
5870 astgen.testDecl(gz, scope, wip_members, member_node) catch |err| switch (err) {
5729 astgen.testDecl(gz, scope, wip_decls, member_node) catch |err| switch (err) {
58715730 error.OutOfMemory => return error.OutOfMemory,
58725731 error.AnalysisFail => {
5873 wip_members.decl_index = prev_decl_index;
5732 wip_decls.index = prev_decl_index;
58745733 try addFailedDeclaration(
5875 wip_members,
5734 wip_decls,
58765735 gz,
58775736 .unnamed_test,
58785737 .empty,
......@@ -10619,482 +10478,6 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev
1061910478 }
1062010479}
1062110480
10622/// Returns `true` if it is known the type expression has more than one possible value;
10623/// `false` otherwise.
10624fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.Index) bool {
10625 var node = start_node;
10626 while (true) {
10627 switch (tree.nodeTag(node)) {
10628 .root,
10629 .test_decl,
10630 .switch_case,
10631 .switch_case_inline,
10632 .switch_case_one,
10633 .switch_case_inline_one,
10634 .container_field_init,
10635 .container_field_align,
10636 .container_field,
10637 .asm_output,
10638 .asm_input,
10639 .global_var_decl,
10640 .local_var_decl,
10641 .simple_var_decl,
10642 .aligned_var_decl,
10643 => unreachable,
10644
10645 .@"return",
10646 .@"break",
10647 .@"continue",
10648 .bit_not,
10649 .bool_not,
10650 .@"defer",
10651 .@"errdefer",
10652 .address_of,
10653 .negation,
10654 .negation_wrap,
10655 .@"resume",
10656 .array_type,
10657 .@"suspend",
10658 .fn_decl,
10659 .anyframe_literal,
10660 .number_literal,
10661 .enum_literal,
10662 .string_literal,
10663 .multiline_string_literal,
10664 .char_literal,
10665 .unreachable_literal,
10666 .error_set_decl,
10667 .container_decl,
10668 .container_decl_trailing,
10669 .container_decl_two,
10670 .container_decl_two_trailing,
10671 .container_decl_arg,
10672 .container_decl_arg_trailing,
10673 .tagged_union,
10674 .tagged_union_trailing,
10675 .tagged_union_two,
10676 .tagged_union_two_trailing,
10677 .tagged_union_enum_tag,
10678 .tagged_union_enum_tag_trailing,
10679 .@"asm",
10680 .asm_simple,
10681 .add,
10682 .add_wrap,
10683 .add_sat,
10684 .array_cat,
10685 .array_mult,
10686 .assign,
10687 .assign_destructure,
10688 .assign_bit_and,
10689 .assign_bit_or,
10690 .assign_shl,
10691 .assign_shl_sat,
10692 .assign_shr,
10693 .assign_bit_xor,
10694 .assign_div,
10695 .assign_sub,
10696 .assign_sub_wrap,
10697 .assign_sub_sat,
10698 .assign_mod,
10699 .assign_add,
10700 .assign_add_wrap,
10701 .assign_add_sat,
10702 .assign_mul,
10703 .assign_mul_wrap,
10704 .assign_mul_sat,
10705 .bang_equal,
10706 .bit_and,
10707 .bit_or,
10708 .shl,
10709 .shl_sat,
10710 .shr,
10711 .bit_xor,
10712 .bool_and,
10713 .bool_or,
10714 .div,
10715 .equal_equal,
10716 .error_union,
10717 .greater_or_equal,
10718 .greater_than,
10719 .less_or_equal,
10720 .less_than,
10721 .merge_error_sets,
10722 .mod,
10723 .mul,
10724 .mul_wrap,
10725 .mul_sat,
10726 .switch_range,
10727 .for_range,
10728 .field_access,
10729 .sub,
10730 .sub_wrap,
10731 .sub_sat,
10732 .slice,
10733 .slice_open,
10734 .slice_sentinel,
10735 .deref,
10736 .array_access,
10737 .error_value,
10738 .while_simple,
10739 .while_cont,
10740 .for_simple,
10741 .if_simple,
10742 .@"catch",
10743 .@"orelse",
10744 .array_init_one,
10745 .array_init_one_comma,
10746 .array_init_dot_two,
10747 .array_init_dot_two_comma,
10748 .array_init_dot,
10749 .array_init_dot_comma,
10750 .array_init,
10751 .array_init_comma,
10752 .struct_init_one,
10753 .struct_init_one_comma,
10754 .struct_init_dot_two,
10755 .struct_init_dot_two_comma,
10756 .struct_init_dot,
10757 .struct_init_dot_comma,
10758 .struct_init,
10759 .struct_init_comma,
10760 .@"while",
10761 .@"if",
10762 .@"for",
10763 .@"switch",
10764 .switch_comma,
10765 .call_one,
10766 .call_one_comma,
10767 .call,
10768 .call_comma,
10769 .block_two,
10770 .block_two_semicolon,
10771 .block,
10772 .block_semicolon,
10773 .builtin_call,
10774 .builtin_call_comma,
10775 .builtin_call_two,
10776 .builtin_call_two_comma,
10777 // these are function bodies, not pointers
10778 .fn_proto_simple,
10779 .fn_proto_multi,
10780 .fn_proto_one,
10781 .fn_proto,
10782 => return false,
10783
10784 // Forward the question to the LHS sub-expression.
10785 .@"try",
10786 .@"comptime",
10787 .@"nosuspend",
10788 => node = tree.nodeData(node).node,
10789 .grouped_expression,
10790 .unwrap_optional,
10791 => node = tree.nodeData(node).node_and_token[0],
10792
10793 .ptr_type_aligned,
10794 .ptr_type_sentinel,
10795 .ptr_type,
10796 .ptr_type_bit_range,
10797 .optional_type,
10798 .anyframe_type,
10799 .array_type_sentinel,
10800 => return true,
10801
10802 .identifier => {
10803 const ident_bytes = tree.tokenSlice(tree.nodeMainToken(node));
10804 if (primitive_instrs.get(ident_bytes)) |primitive| switch (primitive) {
10805 .anyerror_type,
10806 .anyframe_type,
10807 .anyopaque_type,
10808 .bool_type,
10809 .c_int_type,
10810 .c_long_type,
10811 .c_longdouble_type,
10812 .c_longlong_type,
10813 .c_char_type,
10814 .c_short_type,
10815 .c_uint_type,
10816 .c_ulong_type,
10817 .c_ulonglong_type,
10818 .c_ushort_type,
10819 .comptime_float_type,
10820 .comptime_int_type,
10821 .f16_type,
10822 .f32_type,
10823 .f64_type,
10824 .f80_type,
10825 .f128_type,
10826 .i16_type,
10827 .i32_type,
10828 .i64_type,
10829 .i128_type,
10830 .i8_type,
10831 .isize_type,
10832 .type_type,
10833 .u16_type,
10834 .u29_type,
10835 .u32_type,
10836 .u64_type,
10837 .u128_type,
10838 .u1_type,
10839 .u8_type,
10840 .usize_type,
10841 => return true,
10842
10843 .void_type,
10844 .bool_false,
10845 .bool_true,
10846 .null_value,
10847 .undef,
10848 .noreturn_type,
10849 => return false,
10850
10851 else => unreachable, // that's all the values from `primitives`.
10852 } else {
10853 return false;
10854 }
10855 },
10856 }
10857 }
10858}
10859
10860/// Returns `true` if it is known the expression is a type that cannot be used at runtime;
10861/// `false` otherwise.
10862fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool {
10863 var node = start_node;
10864 while (true) {
10865 switch (tree.nodeTag(node)) {
10866 .root,
10867 .test_decl,
10868 .switch_case,
10869 .switch_case_inline,
10870 .switch_case_one,
10871 .switch_case_inline_one,
10872 .container_field_init,
10873 .container_field_align,
10874 .container_field,
10875 .asm_output,
10876 .asm_input,
10877 .global_var_decl,
10878 .local_var_decl,
10879 .simple_var_decl,
10880 .aligned_var_decl,
10881 => unreachable,
10882
10883 .@"return",
10884 .@"break",
10885 .@"continue",
10886 .bit_not,
10887 .bool_not,
10888 .@"defer",
10889 .@"errdefer",
10890 .address_of,
10891 .negation,
10892 .negation_wrap,
10893 .@"resume",
10894 .array_type,
10895 .@"suspend",
10896 .fn_decl,
10897 .anyframe_literal,
10898 .number_literal,
10899 .enum_literal,
10900 .string_literal,
10901 .multiline_string_literal,
10902 .char_literal,
10903 .unreachable_literal,
10904 .error_set_decl,
10905 .container_decl,
10906 .container_decl_trailing,
10907 .container_decl_two,
10908 .container_decl_two_trailing,
10909 .container_decl_arg,
10910 .container_decl_arg_trailing,
10911 .tagged_union,
10912 .tagged_union_trailing,
10913 .tagged_union_two,
10914 .tagged_union_two_trailing,
10915 .tagged_union_enum_tag,
10916 .tagged_union_enum_tag_trailing,
10917 .@"asm",
10918 .asm_simple,
10919 .add,
10920 .add_wrap,
10921 .add_sat,
10922 .array_cat,
10923 .array_mult,
10924 .assign,
10925 .assign_destructure,
10926 .assign_bit_and,
10927 .assign_bit_or,
10928 .assign_shl,
10929 .assign_shl_sat,
10930 .assign_shr,
10931 .assign_bit_xor,
10932 .assign_div,
10933 .assign_sub,
10934 .assign_sub_wrap,
10935 .assign_sub_sat,
10936 .assign_mod,
10937 .assign_add,
10938 .assign_add_wrap,
10939 .assign_add_sat,
10940 .assign_mul,
10941 .assign_mul_wrap,
10942 .assign_mul_sat,
10943 .bang_equal,
10944 .bit_and,
10945 .bit_or,
10946 .shl,
10947 .shl_sat,
10948 .shr,
10949 .bit_xor,
10950 .bool_and,
10951 .bool_or,
10952 .div,
10953 .equal_equal,
10954 .error_union,
10955 .greater_or_equal,
10956 .greater_than,
10957 .less_or_equal,
10958 .less_than,
10959 .merge_error_sets,
10960 .mod,
10961 .mul,
10962 .mul_wrap,
10963 .mul_sat,
10964 .switch_range,
10965 .for_range,
10966 .field_access,
10967 .sub,
10968 .sub_wrap,
10969 .sub_sat,
10970 .slice,
10971 .slice_open,
10972 .slice_sentinel,
10973 .deref,
10974 .array_access,
10975 .error_value,
10976 .while_simple,
10977 .while_cont,
10978 .for_simple,
10979 .if_simple,
10980 .@"catch",
10981 .@"orelse",
10982 .array_init_one,
10983 .array_init_one_comma,
10984 .array_init_dot_two,
10985 .array_init_dot_two_comma,
10986 .array_init_dot,
10987 .array_init_dot_comma,
10988 .array_init,
10989 .array_init_comma,
10990 .struct_init_one,
10991 .struct_init_one_comma,
10992 .struct_init_dot_two,
10993 .struct_init_dot_two_comma,
10994 .struct_init_dot,
10995 .struct_init_dot_comma,
10996 .struct_init,
10997 .struct_init_comma,
10998 .@"while",
10999 .@"if",
11000 .@"for",
11001 .@"switch",
11002 .switch_comma,
11003 .call_one,
11004 .call_one_comma,
11005 .call,
11006 .call_comma,
11007 .block_two,
11008 .block_two_semicolon,
11009 .block,
11010 .block_semicolon,
11011 .builtin_call,
11012 .builtin_call_comma,
11013 .builtin_call_two,
11014 .builtin_call_two_comma,
11015 .ptr_type_aligned,
11016 .ptr_type_sentinel,
11017 .ptr_type,
11018 .ptr_type_bit_range,
11019 .optional_type,
11020 .anyframe_type,
11021 .array_type_sentinel,
11022 => return false,
11023
11024 // these are function bodies, not pointers
11025 .fn_proto_simple,
11026 .fn_proto_multi,
11027 .fn_proto_one,
11028 .fn_proto,
11029 => return true,
11030
11031 // Forward the question to the LHS sub-expression.
11032 .@"try",
11033 .@"comptime",
11034 .@"nosuspend",
11035 => node = tree.nodeData(node).node,
11036 .grouped_expression,
11037 .unwrap_optional,
11038 => node = tree.nodeData(node).node_and_token[0],
11039
11040 .identifier => {
11041 const ident_bytes = tree.tokenSlice(tree.nodeMainToken(node));
11042 if (primitive_instrs.get(ident_bytes)) |primitive| switch (primitive) {
11043 .anyerror_type,
11044 .anyframe_type,
11045 .anyopaque_type,
11046 .bool_type,
11047 .c_int_type,
11048 .c_long_type,
11049 .c_longdouble_type,
11050 .c_longlong_type,
11051 .c_char_type,
11052 .c_short_type,
11053 .c_uint_type,
11054 .c_ulong_type,
11055 .c_ulonglong_type,
11056 .c_ushort_type,
11057 .f16_type,
11058 .f32_type,
11059 .f64_type,
11060 .f80_type,
11061 .f128_type,
11062 .i16_type,
11063 .i32_type,
11064 .i64_type,
11065 .i128_type,
11066 .i8_type,
11067 .isize_type,
11068 .u16_type,
11069 .u29_type,
11070 .u32_type,
11071 .u64_type,
11072 .u128_type,
11073 .u1_type,
11074 .u8_type,
11075 .usize_type,
11076 .void_type,
11077 .bool_false,
11078 .bool_true,
11079 .null_value,
11080 .undef,
11081 .noreturn_type,
11082 => return false,
11083
11084 .comptime_float_type,
11085 .comptime_int_type,
11086 .type_type,
11087 => return true,
11088
11089 else => unreachable, // that's all the values from `primitives`.
11090 } else {
11091 return false;
11092 }
11093 },
11094 }
11095 }
11096}
11097
1109810481/// Applies `rl` semantics to `result`. Expressions which do not do their own handling of
1109910482/// result locations must call this function on their result.
1110010483/// As an example, if `ri.rl` is `.ptr`, it will write the result to the pointer.
......@@ -13044,18 +12427,19 @@ const GenZir = struct {
1304412427
1304512428 fn setStruct(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
1304612429 src_node: Ast.Node.Index,
13047 captures_len: u32,
13048 fields_len: u32,
13049 decls_len: u32,
13050 has_backing_int: bool,
12430 name_strat: Zir.Inst.NameStrategy,
1305112431 layout: std.builtin.Type.ContainerLayout,
13052 known_non_opv: bool,
13053 known_comptime_only: bool,
12432 backing_int_type_body_len: ?u32,
12433 decls_len: u32,
12434 fields_len: u32,
12435 any_field_aligns: bool,
12436 any_field_defaults: bool,
1305412437 any_comptime_fields: bool,
13055 any_default_inits: bool,
13056 any_aligned_fields: bool,
1305712438 fields_hash: std.zig.SrcHash,
13058 name_strat: Zir.Inst.NameStrategy,
12439 captures: []const Zir.Inst.Capture,
12440 capture_names: []const Zir.NullTerminatedString,
12441 /// The trailing declaration list, field information, and body instructions.
12442 remaining: []const u32,
1305912443 }) !void {
1306012444 const astgen = gz.astgen;
1306112445 const gpa = astgen.gpa;
......@@ -13063,9 +12447,16 @@ const GenZir = struct {
1306312447 // Node .root is valid for the root `struct_decl` of a file!
1306412448 assert(args.src_node != .root or gz.parent.tag == .top);
1306512449
12450 const captures_len: u32 = @intCast(args.captures.len);
12451 assert(args.capture_names.len == captures_len);
12452
1306612453 const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);
1306712454
13068 try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.StructDecl).@"struct".fields.len + 3);
12455 try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.StructDecl).@"struct".fields.len +
12456 4 + // `captures_len`, `decls_len`, `fields_len`, `backing_int_type_body_len`
12457 captures_len * 2 + // `capture`, `capture_name`
12458 args.remaining.len);
12459
1306912460 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.StructDecl{
1307012461 .fields_hash_0 = fields_hash_arr[0],
1307112462 .fields_hash_1 = fields_hash_arr[1],
......@@ -13075,31 +12466,28 @@ const GenZir = struct {
1307512466 .src_node = args.src_node,
1307612467 });
1307712468
13078 if (args.captures_len != 0) {
13079 astgen.extra.appendAssumeCapacity(args.captures_len);
13080 }
13081 if (args.fields_len != 0) {
13082 astgen.extra.appendAssumeCapacity(args.fields_len);
13083 }
13084 if (args.decls_len != 0) {
13085 astgen.extra.appendAssumeCapacity(args.decls_len);
13086 }
12469 if (captures_len != 0) astgen.extra.appendAssumeCapacity(captures_len);
12470 if (args.decls_len != 0) astgen.extra.appendAssumeCapacity(args.decls_len);
12471 if (args.fields_len != 0) astgen.extra.appendAssumeCapacity(args.fields_len);
12472 if (args.backing_int_type_body_len) |n| astgen.extra.appendAssumeCapacity(n);
12473 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.captures));
12474 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.capture_names));
12475 astgen.extra.appendSliceAssumeCapacity(args.remaining);
12476
1308712477 astgen.instructions.set(@intFromEnum(inst), .{
1308812478 .tag = .extended,
1308912479 .data = .{ .extended = .{
1309012480 .opcode = .struct_decl,
1309112481 .small = @bitCast(Zir.Inst.StructDecl.Small{
13092 .has_captures_len = args.captures_len != 0,
13093 .has_fields_len = args.fields_len != 0,
12482 .has_captures_len = captures_len != 0,
1309412483 .has_decls_len = args.decls_len != 0,
13095 .has_backing_int = args.has_backing_int,
13096 .known_non_opv = args.known_non_opv,
13097 .known_comptime_only = args.known_comptime_only,
12484 .has_fields_len = args.fields_len != 0,
1309812485 .name_strategy = args.name_strat,
1309912486 .layout = args.layout,
12487 .has_backing_int_type = args.backing_int_type_body_len != null,
12488 .any_field_aligns = args.any_field_aligns,
12489 .any_field_defaults = args.any_field_defaults,
1310012490 .any_comptime_fields = args.any_comptime_fields,
13101 .any_default_inits = args.any_default_inits,
13102 .any_aligned_fields = args.any_aligned_fields,
1310312491 }),
1310412492 .operand = payload_index,
1310512493 } },
......@@ -13108,25 +12496,34 @@ const GenZir = struct {
1310812496
1310912497 fn setUnion(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
1311012498 src_node: Ast.Node.Index,
13111 tag_type: Zir.Inst.Ref,
13112 captures_len: u32,
13113 body_len: u32,
13114 fields_len: u32,
12499 name_strat: Zir.Inst.NameStrategy,
12500 kind: Zir.Inst.UnionDecl.Kind,
12501 arg_type_body_len: ?u32,
1311512502 decls_len: u32,
13116 layout: std.builtin.Type.ContainerLayout,
13117 auto_enum_tag: bool,
13118 any_aligned_fields: bool,
12503 fields_len: u32,
12504 any_field_aligns: bool,
12505 any_field_values: bool,
1311912506 fields_hash: std.zig.SrcHash,
13120 name_strat: Zir.Inst.NameStrategy,
12507 captures: []const Zir.Inst.Capture,
12508 capture_names: []const Zir.NullTerminatedString,
12509 /// The trailing declaration list, field information, and body instructions.
12510 remaining: []const u32,
1312112511 }) !void {
1312212512 const astgen = gz.astgen;
1312312513 const gpa = astgen.gpa;
1312412514
1312512515 assert(args.src_node != .root);
1312612516
12517 const captures_len: u32 = @intCast(args.captures.len);
12518 assert(args.capture_names.len == captures_len);
12519
1312712520 const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);
1312812521
13129 try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.UnionDecl).@"struct".fields.len + 5);
12522 try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.UnionDecl).@"struct".fields.len +
12523 4 + // `captures_len`, `decls_len`, `fields_len`, `arg_type_body_len`
12524 captures_len * 2 + // `capture`, `capture_name`
12525 args.remaining.len);
12526
1313012527 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.UnionDecl{
1313112528 .fields_hash_0 = fields_hash_arr[0],
1313212529 .fields_hash_1 = fields_hash_arr[1],
......@@ -13136,35 +12533,30 @@ const GenZir = struct {
1313612533 .src_node = args.src_node,
1313712534 });
1313812535
13139 if (args.tag_type != .none) {
13140 astgen.extra.appendAssumeCapacity(@intFromEnum(args.tag_type));
13141 }
13142 if (args.captures_len != 0) {
13143 astgen.extra.appendAssumeCapacity(args.captures_len);
13144 }
13145 if (args.body_len != 0) {
13146 astgen.extra.appendAssumeCapacity(args.body_len);
13147 }
13148 if (args.fields_len != 0) {
13149 astgen.extra.appendAssumeCapacity(args.fields_len);
13150 }
13151 if (args.decls_len != 0) {
13152 astgen.extra.appendAssumeCapacity(args.decls_len);
12536 if (captures_len != 0) astgen.extra.appendAssumeCapacity(captures_len);
12537 if (args.decls_len != 0) astgen.extra.appendAssumeCapacity(args.decls_len);
12538 if (args.fields_len != 0) astgen.extra.appendAssumeCapacity(args.fields_len);
12539 if (args.kind.hasArgType()) {
12540 astgen.extra.appendAssumeCapacity(args.arg_type_body_len.?);
12541 } else {
12542 assert(args.arg_type_body_len == null);
1315312543 }
12544 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.captures));
12545 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.capture_names));
12546 astgen.extra.appendSliceAssumeCapacity(args.remaining);
12547
1315412548 astgen.instructions.set(@intFromEnum(inst), .{
1315512549 .tag = .extended,
1315612550 .data = .{ .extended = .{
1315712551 .opcode = .union_decl,
1315812552 .small = @bitCast(Zir.Inst.UnionDecl.Small{
13159 .has_tag_type = args.tag_type != .none,
13160 .has_captures_len = args.captures_len != 0,
13161 .has_body_len = args.body_len != 0,
13162 .has_fields_len = args.fields_len != 0,
12553 .has_captures_len = captures_len != 0,
1316312554 .has_decls_len = args.decls_len != 0,
12555 .has_fields_len = args.fields_len != 0,
1316412556 .name_strategy = args.name_strat,
13165 .layout = args.layout,
13166 .auto_enum_tag = args.auto_enum_tag,
13167 .any_aligned_fields = args.any_aligned_fields,
12557 .kind = args.kind,
12558 .any_field_aligns = args.any_field_aligns,
12559 .any_field_values = args.any_field_values,
1316812560 }),
1316912561 .operand = payload_index,
1317012562 } },
......@@ -13173,23 +12565,33 @@ const GenZir = struct {
1317312565
1317412566 fn setEnum(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
1317512567 src_node: Ast.Node.Index,
13176 tag_type: Zir.Inst.Ref,
13177 captures_len: u32,
13178 body_len: u32,
13179 fields_len: u32,
13180 decls_len: u32,
12568 name_strat: Zir.Inst.NameStrategy,
12569 tag_type_body_len: ?u32,
1318112570 nonexhaustive: bool,
12571 decls_len: u32,
12572 fields_len: u32,
12573 any_field_values: bool,
1318212574 fields_hash: std.zig.SrcHash,
13183 name_strat: Zir.Inst.NameStrategy,
12575 captures: []const Zir.Inst.Capture,
12576 capture_names: []const Zir.NullTerminatedString,
12577 /// The trailing declaration list, field information, and body instructions.
12578 remaining: []const u32,
1318412579 }) !void {
1318512580 const astgen = gz.astgen;
1318612581 const gpa = astgen.gpa;
1318712582
1318812583 assert(args.src_node != .root);
1318912584
12585 const captures_len: u32 = @intCast(args.captures.len);
12586 assert(args.capture_names.len == captures_len);
12587
1319012588 const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash);
1319112589
13192 try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.EnumDecl).@"struct".fields.len + 5);
12590 try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.EnumDecl).@"struct".fields.len +
12591 4 + // `captures_len`, `decls_len`, `fields_len`, `tag_type_body_len`
12592 captures_len * 2 + // `capture`, `capture_name`
12593 args.remaining.len);
12594
1319312595 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.EnumDecl{
1319412596 .fields_hash_0 = fields_hash_arr[0],
1319512597 .fields_hash_1 = fields_hash_arr[1],
......@@ -13199,33 +12601,26 @@ const GenZir = struct {
1319912601 .src_node = args.src_node,
1320012602 });
1320112603
13202 if (args.tag_type != .none) {
13203 astgen.extra.appendAssumeCapacity(@intFromEnum(args.tag_type));
13204 }
13205 if (args.captures_len != 0) {
13206 astgen.extra.appendAssumeCapacity(args.captures_len);
13207 }
13208 if (args.body_len != 0) {
13209 astgen.extra.appendAssumeCapacity(args.body_len);
13210 }
13211 if (args.fields_len != 0) {
13212 astgen.extra.appendAssumeCapacity(args.fields_len);
13213 }
13214 if (args.decls_len != 0) {
13215 astgen.extra.appendAssumeCapacity(args.decls_len);
13216 }
12604 if (captures_len != 0) astgen.extra.appendAssumeCapacity(captures_len);
12605 if (args.decls_len != 0) astgen.extra.appendAssumeCapacity(args.decls_len);
12606 if (args.fields_len != 0) astgen.extra.appendAssumeCapacity(args.fields_len);
12607 if (args.tag_type_body_len) |n| astgen.extra.appendAssumeCapacity(n);
12608 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.captures));
12609 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.capture_names));
12610 astgen.extra.appendSliceAssumeCapacity(args.remaining);
12611
1321712612 astgen.instructions.set(@intFromEnum(inst), .{
1321812613 .tag = .extended,
1321912614 .data = .{ .extended = .{
1322012615 .opcode = .enum_decl,
1322112616 .small = @bitCast(Zir.Inst.EnumDecl.Small{
13222 .has_tag_type = args.tag_type != .none,
13223 .has_captures_len = args.captures_len != 0,
13224 .has_body_len = args.body_len != 0,
13225 .has_fields_len = args.fields_len != 0,
12617 .has_captures_len = captures_len != 0,
1322612618 .has_decls_len = args.decls_len != 0,
12619 .has_fields_len = args.fields_len != 0,
1322712620 .name_strategy = args.name_strat,
12621 .has_tag_type = args.tag_type_body_len != null,
1322812622 .nonexhaustive = args.nonexhaustive,
12623 .any_field_values = args.any_field_values,
1322912624 }),
1323012625 .operand = payload_index,
1323112626 } },
......@@ -13234,33 +12629,41 @@ const GenZir = struct {
1323412629
1323512630 fn setOpaque(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
1323612631 src_node: Ast.Node.Index,
13237 captures_len: u32,
13238 decls_len: u32,
1323912632 name_strat: Zir.Inst.NameStrategy,
12633 decls_len: u32,
12634 captures: []const Zir.Inst.Capture,
12635 capture_names: []const Zir.NullTerminatedString,
12636 decls: []const Zir.Inst.Index,
1324012637 }) !void {
1324112638 const astgen = gz.astgen;
1324212639 const gpa = astgen.gpa;
1324312640
1324412641 assert(args.src_node != .root);
1324512642
13246 try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.OpaqueDecl).@"struct".fields.len + 2);
12643 const captures_len: u32 = @intCast(args.captures.len);
12644 assert(args.capture_names.len == captures_len);
12645
12646 try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.OpaqueDecl).@"struct".fields.len +
12647 2 + // `captures_len`, `decls_len`
12648 captures_len * 2 + // `capture`, `capture_name`
12649 args.decls.len);
12650
1324712651 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.OpaqueDecl{
1324812652 .src_line = astgen.source_line,
1324912653 .src_node = args.src_node,
1325012654 });
12655 if (captures_len != 0) astgen.extra.appendAssumeCapacity(captures_len);
12656 if (args.decls_len != 0) astgen.extra.appendAssumeCapacity(args.decls_len);
12657 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.captures));
12658 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.capture_names));
12659 astgen.extra.appendSliceAssumeCapacity(@ptrCast(args.decls));
1325112660
13252 if (args.captures_len != 0) {
13253 astgen.extra.appendAssumeCapacity(args.captures_len);
13254 }
13255 if (args.decls_len != 0) {
13256 astgen.extra.appendAssumeCapacity(args.decls_len);
13257 }
1325812661 astgen.instructions.set(@intFromEnum(inst), .{
1325912662 .tag = .extended,
1326012663 .data = .{ .extended = .{
1326112664 .opcode = .opaque_decl,
1326212665 .small = @bitCast(Zir.Inst.OpaqueDecl.Small{
13263 .has_captures_len = args.captures_len != 0,
12666 .has_captures_len = captures_len != 0,
1326412667 .has_decls_len = args.decls_len != 0,
1326512668 .name_strategy = args.name_strat,
1326612669 }),
......@@ -13484,14 +12887,24 @@ fn restoreSourceCursor(astgen: *AstGen, cursor: SourceCursor) void {
1348412887 astgen.source_column = cursor.column;
1348512888}
1348612889
12890const ScanContainerResult = struct {
12891 /// Includes unnamed declarations (e.g. `comptime` decls)
12892 decls_len: u32,
12893 fields_len: u32,
12894 any_field_aligns: bool,
12895 any_field_values: bool,
12896 any_comptime_fields: bool,
12897 /// Whether there is a field named `_` (indicating a non-exhaustive enum)
12898 has_underscore_field: bool,
12899};
12900
1348712901/// Detects name conflicts for decls and fields, and populates `namespace.decls` with all named declarations.
13488/// Returns the number of declarations in the namespace, including unnamed declarations (e.g. `comptime` decls).
1348912902fn scanContainer(
1349012903 astgen: *AstGen,
1349112904 namespace: *Scope.Namespace,
1349212905 members: []const Ast.Node.Index,
1349312906 container_kind: enum { @"struct", @"union", @"enum", @"opaque" },
13494) !u32 {
12907) !ScanContainerResult {
1349512908 const gpa = astgen.gpa;
1349612909 const tree = astgen.tree;
1349712910
......@@ -13521,6 +12934,10 @@ fn scanContainer(
1352112934
1352212935 var any_duplicates = false;
1352312936 var decl_count: u32 = 0;
12937 var any_field_aligns = false;
12938 var any_field_values = false;
12939 var any_comptime_fields = false;
12940 var has_underscore_field = false;
1352412941 for (members) |member_node| {
1352512942 const Kind = enum { decl, field };
1352612943 const kind: Kind, const name_token = switch (tree.nodeTag(member_node)) {
......@@ -13533,6 +12950,10 @@ fn scanContainer(
1353312950 .@"struct", .@"opaque" => {},
1353412951 .@"union", .@"enum" => full.convertToNonTupleLike(astgen.tree),
1353512952 }
12953 if (full.ast.align_expr != .none) any_field_aligns = true;
12954 if (full.ast.value_expr != .none) any_field_values = true;
12955 if (full.comptime_token != null) any_comptime_fields = true;
12956 if (mem.eql(u8, tree.tokenSlice(full.ast.main_token), "_")) has_underscore_field = true;
1353612957 if (full.ast.tuple_like) continue;
1353712958 break :blk .{ .field, full.ast.main_token };
1353812959 },
......@@ -13698,7 +13119,14 @@ fn scanContainer(
1369813119
1369913120 if (!any_duplicates) {
1370013121 if (any_invalid_declarations) return error.AnalysisFail;
13701 return decl_count;
13122 return .{
13123 .decls_len = decl_count,
13124 .fields_len = @intCast(members.len - decl_count),
13125 .any_field_aligns = any_field_aligns,
13126 .any_field_values = any_field_values,
13127 .any_comptime_fields = any_comptime_fields,
13128 .has_underscore_field = has_underscore_field,
13129 };
1370213130 }
1370313131
1370413132 for (names.keys(), names.values()) |name, first| {
......@@ -13954,7 +13382,7 @@ const DeclarationName = union(enum) {
1395413382};
1395513383
1395613384fn addFailedDeclaration(
13957 wip_members: *WipMembers,
13385 wip_decls: *WipDecls,
1395813386 gz: *GenZir,
1395913387 kind: Zir.Inst.Declaration.Unwrapped.Kind,
1396013388 name: Zir.NullTerminatedString,
......@@ -13962,7 +13390,7 @@ fn addFailedDeclaration(
1396213390 is_pub: bool,
1396313391) !void {
1396413392 const decl_inst = try gz.makeDeclaration(src_node);
13965 wip_members.nextDecl(decl_inst);
13393 wip_decls.nextDecl(decl_inst);
1396613394
1396713395 var dummy_gz = gz.makeSubBlock(&gz.base);
1396813396
lib/std/zig/ErrorBundle.zig+10-6
......@@ -243,12 +243,14 @@ fn renderErrorMessage(
243243 }
244244 try t.setColor(.reset);
245245 if (src.data.source_line != 0 and options.include_source_line) {
246 try w.splatByteAll(' ', indent);
246247 const line = eb.nullTerminatedString(src.data.source_line);
247248 for (line) |b| switch (b) {
248249 '\t' => try w.writeByte(' '),
249250 else => try w.writeByte(b),
250251 };
251252 try w.writeByte('\n');
253 try w.splatByteAll(' ', indent);
252254 // TODO basic unicode code point monospace width
253255 const before_caret = src.data.span_main - src.data.span_start;
254256 // -1 since span.main includes the caret
......@@ -267,11 +269,13 @@ fn renderErrorMessage(
267269 if (src.data.reference_trace_len > 0 and options.include_reference_trace) {
268270 try t.setColor(.reset);
269271 try t.setColor(.dim);
272 try w.splatByteAll(' ', indent);
270273 try w.print("referenced by:\n", .{});
271274 var ref_index = src.end;
272275 for (0..src.data.reference_trace_len) |_| {
273276 const ref_trace = eb.extraData(ReferenceTrace, ref_index);
274277 ref_index = ref_trace.end;
278 try w.splatByteAll(' ', indent);
275279 if (ref_trace.data.src_loc != .none) {
276280 const ref_src = eb.getSourceLocation(ref_trace.data.src_loc);
277281 try w.print(" {s}: {s}:{d}:{d}\n", .{
......@@ -340,9 +344,9 @@ pub const Wip = struct {
340344 pub fn init(wip: *Wip, gpa: Allocator) !void {
341345 wip.* = .{
342346 .gpa = gpa,
343 .string_bytes = .{},
344 .extra = .{},
345 .root_list = .{},
347 .string_bytes = .empty,
348 .extra = .empty,
349 .root_list = .empty,
346350 };
347351
348352 // So that 0 can be used to indicate a null string.
......@@ -371,9 +375,9 @@ pub const Wip = struct {
371375 wip.deinit();
372376 wip.* = .{
373377 .gpa = gpa,
374 .string_bytes = .{},
375 .extra = .{},
376 .root_list = .{},
378 .string_bytes = .empty,
379 .extra = .empty,
380 .root_list = .empty,
377381 };
378382 return empty;
379383 }
lib/std/zig/Zir.zig+564-386
......@@ -2443,7 +2443,7 @@ pub const Inst = struct {
24432443 has_align: bool,
24442444 has_addrspace: bool,
24452445 has_bit_range: bool,
2446 _: u1 = undefined,
2446 _: u1 = 0,
24472447 },
24482448 size: std.builtin.Type.Pointer.Size,
24492449 /// Index into extra. See `PtrType`.
......@@ -2668,7 +2668,7 @@ pub const Inst = struct {
26682668 has_ret_ty_body: bool,
26692669 has_any_noalias: bool,
26702670 ret_ty_is_generic: bool,
2671 _: u23 = undefined,
2671 _: u23 = 0,
26722672 };
26732673 };
26742674
......@@ -3134,7 +3134,7 @@ pub const Inst = struct {
31343134 pub const Flags = packed struct {
31353135 is_nosuspend: bool,
31363136 ensure_result_used: bool,
3137 _: u30 = undefined,
3137 _: u30 = 0,
31383138
31393139 comptime {
31403140 if (@sizeOf(Flags) != 4 or @bitSizeOf(Flags) != 32)
......@@ -3462,33 +3462,21 @@ pub const Inst = struct {
34623462 };
34633463
34643464 /// Trailing:
3465 /// 0. captures_len: u32 // if has_captures_len
3466 /// 1. fields_len: u32, // if has_fields_len
3467 /// 2. decls_len: u32, // if has_decls_len
3468 /// 3. capture: Capture // for every captures_len
3469 /// 4. capture_name: NullTerminatedString // for every captures_len
3470 /// 5. backing_int_body_len: u32, // if has_backing_int
3471 /// 6. backing_int_ref: Ref, // if has_backing_int and backing_int_body_len is 0
3472 /// 7. backing_int_body_inst: Inst, // if has_backing_int and backing_int_body_len is > 0
3473 /// 8. decl: Index, // for every decls_len; points to a `declaration` instruction
3474 /// 9. flags: u32 // for every 8 fields
3475 /// - sets of 4 bits:
3476 /// 0b000X: whether corresponding field has an align expression
3477 /// 0b00X0: whether corresponding field has a default expression
3478 /// 0b0X00: whether corresponding field is comptime
3479 /// 0bX000: whether corresponding field has a type expression
3480 /// 10. fields: { // for every fields_len
3481 /// field_name: u32,
3482 /// field_type: Ref, // if corresponding bit is not set. none means anytype.
3483 /// field_type_body_len: u32, // if corresponding bit is set
3484 /// align_body_len: u32, // if corresponding bit is set
3485 /// init_body_len: u32, // if corresponding bit is set
3486 /// }
3487 /// 11. bodies: { // for every fields_len
3488 /// field_type_body_inst: Inst, // for each field_type_body_len
3489 /// align_body_inst: Inst, // for each align_body_len
3490 /// init_body_inst: Inst, // for each init_body_len
3491 /// }
3465 /// 0. captures_len: u32 // if `has_captures_len`
3466 /// 1. decls_len: u32, // if `has_decls_len`
3467 /// 2. fields_len: u32, // if `has_fields_len`
3468 /// 3. backing_int_body_len: u32 // if `has_backing_int`
3469 /// 4. capture: Capture // for every `captures_len`
3470 /// 5. capture_name: NullTerminatedString // for every `captures_len`
3471 /// 6. decl: Index, // for every `decls_len`; points to a `declaration` instruction
3472 /// 7. field_name: NullTerminatedString // for every `fields_len`
3473 /// 8. field_type_body_len: u32 // for every `fields_len`
3474 /// 9. field_align_body_len: u32 // for every `fields_len` if `any_field_aligns`
3475 /// 10. field_default_body_len: u32 // for every `fields_len` if `any_field_defaults`
3476 /// 11. field_comptime_bits: u32 // one bit per `fields_len` if `any_comptime_fields`
3477 /// // LSB is first field, minimum number of `u32` needed
3478 /// 12. backing_int_body_inst: Inst.Index // for each `backing_int_body_len`
3479 /// 13. body_inst: Inst.Index // type body, then align body, then default body, for each field
34923480 pub const StructDecl = struct {
34933481 // These fields should be concatenated and reinterpreted as a `std.zig.SrcHash`.
34943482 // This hash contains the source of all fields, and any specified attributes (`extern`, backing type, etc).
......@@ -3500,19 +3488,18 @@ pub const Inst = struct {
35003488 /// This node provides a new absolute baseline node for all instructions within this struct.
35013489 src_node: Ast.Node.Index,
35023490
3503 pub const Small = packed struct {
3491 pub const Small = packed struct(u16) {
35043492 has_captures_len: bool,
3505 has_fields_len: bool,
35063493 has_decls_len: bool,
3507 has_backing_int: bool,
3508 known_non_opv: bool,
3509 known_comptime_only: bool,
3494 has_fields_len: bool,
35103495 name_strategy: NameStrategy,
35113496 layout: std.builtin.Type.ContainerLayout,
3512 any_default_inits: bool,
3497 /// Always `false` if `layout != .@"packed"`.
3498 has_backing_int_type: bool,
3499 any_field_aligns: bool,
3500 any_field_defaults: bool,
35133501 any_comptime_fields: bool,
3514 any_aligned_fields: bool,
3515 _: u3 = undefined,
3502 _: u5 = 0,
35163503 };
35173504 };
35183505
......@@ -3633,21 +3620,17 @@ pub const Inst = struct {
36333620 };
36343621
36353622 /// Trailing:
3636 /// 0. tag_type: Ref, // if has_tag_type
3637 /// 1. captures_len: u32, // if has_captures_len
3638 /// 2. body_len: u32, // if has_body_len
3639 /// 3. fields_len: u32, // if has_fields_len
3640 /// 4. decls_len: u32, // if has_decls_len
3641 /// 5. capture: Capture // for every captures_len
3642 /// 6. capture_name: NullTerminatedString // for every captures_len
3643 /// 7. decl: Index, // for every decls_len; points to a `declaration` instruction
3644 /// 8. inst: Index // for every body_len
3645 /// 9. has_bits: u32 // for every 32 fields
3646 /// - the bit is whether corresponding field has an value expression
3647 /// 10. fields: { // for every fields_len
3648 /// field_name: u32,
3649 /// value: Ref, // if corresponding bit is set
3650 /// }
3623 /// 0. captures_len: u32, // if has_captures_len
3624 /// 1. decls_len: u32, // if has_decls_len
3625 /// 2. fields_len: u32, // if has_fields_len
3626 /// 3. tag_type_body_len: u32, // if has_tag_type
3627 /// 4. capture: Capture // for every `captures_len`
3628 /// 5. capture_name: NullTerminatedString // for every `captures_len`
3629 /// 6. decl: Index, // for every `decls_len`; points to a `declaration` instruction
3630 /// 7. field_name: NullTerminatedString // for every `fields_len`
3631 /// 8. field_value_body_len: u32 // for every `fields_len` if `any_field_values`
3632 /// 9. tag_type_body_inst: Inst.Index // for each `tag_type_body_len`
3633 /// 10. body_inst: Inst.Index // value body for each field
36513634 pub const EnumDecl = struct {
36523635 // These fields should be concatenated and reinterpreted as a `std.zig.SrcHash`.
36533636 // This hash contains the source of all fields, and the backing type if specified.
......@@ -3659,40 +3642,32 @@ pub const Inst = struct {
36593642 /// This node provides a new absolute baseline node for all instructions within this struct.
36603643 src_node: Ast.Node.Index,
36613644
3662 pub const Small = packed struct {
3663 has_tag_type: bool,
3645 pub const Small = packed struct(u16) {
36643646 has_captures_len: bool,
3665 has_body_len: bool,
3666 has_fields_len: bool,
36673647 has_decls_len: bool,
3648 has_fields_len: bool,
36683649 name_strategy: NameStrategy,
3650 has_tag_type: bool,
36693651 nonexhaustive: bool,
3670 _: u8 = undefined,
3652 any_field_values: bool,
3653 _: u8 = 0,
36713654 };
36723655 };
36733656
36743657 /// Trailing:
3675 /// 0. tag_type: Ref, // if has_tag_type
3676 /// 1. captures_len: u32 // if has_captures_len
3677 /// 2. body_len: u32, // if has_body_len
3678 /// 3. fields_len: u32, // if has_fields_len
3679 /// 4. decls_len: u32, // if has_decls_len
3680 /// 5. capture: Capture // for every captures_len
3681 /// 6. capture_name: NullTerminatedString // for every captures_len
3682 /// 7. decl: Index, // for every decls_len; points to a `declaration` instruction
3683 /// 8. inst: Index // for every body_len
3684 /// 9. has_bits: u32 // for every 8 fields
3685 /// - sets of 4 bits:
3686 /// 0b000X: whether corresponding field has a type expression
3687 /// 0b00X0: whether corresponding field has a align expression
3688 /// 0b0X00: whether corresponding field has a tag value expression
3689 /// 0bX000: unused
3690 /// 10. fields: { // for every fields_len
3691 /// field_name: NullTerminatedString, // null terminated string index
3692 /// field_type: Ref, // if corresponding bit is set
3693 /// align: Ref, // if corresponding bit is set
3694 /// tag_value: Ref, // if corresponding bit is set
3695 /// }
3658 /// 0. captures_len: u32 // if `has_captures_len`
3659 /// 1. decls_len: u32, // if `has_decls_len`
3660 /// 2. fields_len: u32, // if `has_fields_len`
3661 /// 3. arg_type_body_len: u32, // if `kind.hasArgType()`
3662 /// 4. capture: Capture // for every `captures_len`
3663 /// 5. capture_name: NullTerminatedString // for every `captures_len`
3664 /// 6. decl: Index, // for every `decls_len`; points to a `declaration` instruction
3665 /// 7. field_name: NullTerminatedString // for every `fields_len`
3666 /// 8. field_type_body_len: u32 // for every `fields_len`
3667 /// 9 . field_align_body_len: u32 // for every `fields_len` if `any_field_aligns`
3668 /// 10. field_value_body_len: u32 // for every `fields_len` if `any_field_values`
3669 /// 11. arg_type_body_inst: Inst.Index // for each `arg_type_body_len`
3670 /// 12. body_inst: Inst.Index // type body, then align body, then value body, for each field
36963671 pub const UnionDecl = struct {
36973672 // These fields should be concatenated and reinterpreted as a `std.zig.SrcHash`.
36983673 // This hash contains the source of all fields, and any specified attributes (`extern` etc).
......@@ -3704,23 +3679,47 @@ pub const Inst = struct {
37043679 /// This node provides a new absolute baseline node for all instructions within this struct.
37053680 src_node: Ast.Node.Index,
37063681
3707 pub const Small = packed struct {
3708 has_tag_type: bool,
3682 pub const Small = packed struct(u16) {
37093683 has_captures_len: bool,
3710 has_body_len: bool,
3711 has_fields_len: bool,
37123684 has_decls_len: bool,
3685 has_fields_len: bool,
37133686 name_strategy: NameStrategy,
3714 layout: std.builtin.Type.ContainerLayout,
3715 /// has_tag_type | auto_enum_tag | result
3716 /// -------------------------------------
3717 /// false | false | union { }
3718 /// false | true | union(enum) { }
3719 /// true | true | union(enum(T)) { }
3720 /// true | false | union(T) { }
3721 auto_enum_tag: bool,
3722 any_aligned_fields: bool,
3723 _: u5 = undefined,
3687 kind: Kind,
3688 any_field_aligns: bool,
3689 any_field_values: bool,
3690 _: u6 = 0,
3691 };
3692
3693 pub const Kind = enum(u3) {
3694 /// `union`
3695 auto,
3696 /// `union(T)`
3697 tagged_explicit,
3698 /// `union(enum)`
3699 tagged_enum,
3700 /// `union(enum(T))`
3701 tagged_enum_explicit,
3702 /// `extern union`
3703 @"extern",
3704 /// `packed union`
3705 @"packed",
3706 /// `packed union(T)`
3707 packed_explicit,
3708
3709 pub fn hasArgType(k: Kind) bool {
3710 return switch (k) {
3711 .auto, .tagged_enum, .@"extern", .@"packed" => false,
3712 .tagged_explicit, .tagged_enum_explicit, .packed_explicit => true,
3713 };
3714 }
3715
3716 pub fn layout(k: Kind) std.builtin.Type.ContainerLayout {
3717 return switch (k) {
3718 .auto, .tagged_explicit, .tagged_enum, .tagged_enum_explicit => .auto,
3719 .@"extern" => .@"extern",
3720 .@"packed", .packed_explicit => .@"packed",
3721 };
3722 }
37243723 };
37253724 };
37263725
......@@ -3735,11 +3734,11 @@ pub const Inst = struct {
37353734 /// This node provides a new absolute baseline node for all instructions within this struct.
37363735 src_node: Ast.Node.Index,
37373736
3738 pub const Small = packed struct {
3737 pub const Small = packed struct(u16) {
37393738 has_captures_len: bool,
37403739 has_decls_len: bool,
37413740 name_strategy: NameStrategy,
3742 _: u12 = undefined,
3741 _: u12 = 0,
37433742 };
37443743 };
37453744
......@@ -3904,12 +3903,12 @@ pub const Inst = struct {
39043903 pub const AllocExtended = struct {
39053904 src_node: Ast.Node.Offset,
39063905
3907 pub const Small = packed struct {
3906 pub const Small = packed struct(u16) {
39083907 has_type: bool,
39093908 has_align: bool,
39103909 is_const: bool,
39113910 is_comptime: bool,
3912 _: u12 = undefined,
3911 _: u12 = 0,
39133912 };
39143913 };
39153914
......@@ -4012,135 +4011,6 @@ pub const Inst = struct {
40124011 };
40134012};
40144013
4015pub const DeclIterator = struct {
4016 extra_index: u32,
4017 decls_remaining: u32,
4018 zir: Zir,
4019
4020 pub fn next(it: *DeclIterator) ?Inst.Index {
4021 if (it.decls_remaining == 0) return null;
4022 const decl_inst: Zir.Inst.Index = @enumFromInt(it.zir.extra[it.extra_index]);
4023 it.extra_index += 1;
4024 it.decls_remaining -= 1;
4025 assert(it.zir.instructions.items(.tag)[@intFromEnum(decl_inst)] == .declaration);
4026 return decl_inst;
4027 }
4028};
4029
4030pub fn declIterator(zir: Zir, decl_inst: Zir.Inst.Index) DeclIterator {
4031 const inst = zir.instructions.get(@intFromEnum(decl_inst));
4032 assert(inst.tag == .extended);
4033 const extended = inst.data.extended;
4034 switch (extended.opcode) {
4035 .struct_decl => {
4036 const small: Inst.StructDecl.Small = @bitCast(extended.small);
4037 var extra_index: u32 = @intCast(extended.operand + @typeInfo(Inst.StructDecl).@"struct".fields.len);
4038 const captures_len = if (small.has_captures_len) captures_len: {
4039 const captures_len = zir.extra[extra_index];
4040 extra_index += 1;
4041 break :captures_len captures_len;
4042 } else 0;
4043 extra_index += @intFromBool(small.has_fields_len);
4044 const decls_len = if (small.has_decls_len) decls_len: {
4045 const decls_len = zir.extra[extra_index];
4046 extra_index += 1;
4047 break :decls_len decls_len;
4048 } else 0;
4049
4050 extra_index += captures_len * 2;
4051
4052 if (small.has_backing_int) {
4053 const backing_int_body_len = zir.extra[extra_index];
4054 extra_index += 1; // backing_int_body_len
4055 if (backing_int_body_len == 0) {
4056 extra_index += 1; // backing_int_ref
4057 } else {
4058 extra_index += backing_int_body_len; // backing_int_body_inst
4059 }
4060 }
4061
4062 return .{
4063 .extra_index = extra_index,
4064 .decls_remaining = decls_len,
4065 .zir = zir,
4066 };
4067 },
4068 .enum_decl => {
4069 const small: Inst.EnumDecl.Small = @bitCast(extended.small);
4070 var extra_index: u32 = @intCast(extended.operand + @typeInfo(Inst.EnumDecl).@"struct".fields.len);
4071 extra_index += @intFromBool(small.has_tag_type);
4072 const captures_len = if (small.has_captures_len) captures_len: {
4073 const captures_len = zir.extra[extra_index];
4074 extra_index += 1;
4075 break :captures_len captures_len;
4076 } else 0;
4077 extra_index += @intFromBool(small.has_body_len);
4078 extra_index += @intFromBool(small.has_fields_len);
4079 const decls_len = if (small.has_decls_len) decls_len: {
4080 const decls_len = zir.extra[extra_index];
4081 extra_index += 1;
4082 break :decls_len decls_len;
4083 } else 0;
4084
4085 extra_index += captures_len * 2;
4086
4087 return .{
4088 .extra_index = extra_index,
4089 .decls_remaining = decls_len,
4090 .zir = zir,
4091 };
4092 },
4093 .union_decl => {
4094 const small: Inst.UnionDecl.Small = @bitCast(extended.small);
4095 var extra_index: u32 = @intCast(extended.operand + @typeInfo(Inst.UnionDecl).@"struct".fields.len);
4096 extra_index += @intFromBool(small.has_tag_type);
4097 const captures_len = if (small.has_captures_len) captures_len: {
4098 const captures_len = zir.extra[extra_index];
4099 extra_index += 1;
4100 break :captures_len captures_len;
4101 } else 0;
4102 extra_index += @intFromBool(small.has_body_len);
4103 extra_index += @intFromBool(small.has_fields_len);
4104 const decls_len = if (small.has_decls_len) decls_len: {
4105 const decls_len = zir.extra[extra_index];
4106 extra_index += 1;
4107 break :decls_len decls_len;
4108 } else 0;
4109
4110 extra_index += captures_len * 2;
4111
4112 return .{
4113 .extra_index = extra_index,
4114 .decls_remaining = decls_len,
4115 .zir = zir,
4116 };
4117 },
4118 .opaque_decl => {
4119 const small: Inst.OpaqueDecl.Small = @bitCast(extended.small);
4120 var extra_index: u32 = @intCast(extended.operand + @typeInfo(Inst.OpaqueDecl).@"struct".fields.len);
4121 const decls_len = if (small.has_decls_len) decls_len: {
4122 const decls_len = zir.extra[extra_index];
4123 extra_index += 1;
4124 break :decls_len decls_len;
4125 } else 0;
4126 const captures_len = if (small.has_captures_len) captures_len: {
4127 const captures_len = zir.extra[extra_index];
4128 extra_index += 1;
4129 break :captures_len captures_len;
4130 } else 0;
4131
4132 extra_index += captures_len * 2;
4133
4134 return .{
4135 .extra_index = extra_index,
4136 .decls_remaining = decls_len,
4137 .zir = zir,
4138 };
4139 },
4140 else => unreachable,
4141 }
4142}
4143
41444014/// `DeclContents` contains all "interesting" instructions found within a declaration by `findTrackable`.
41454015/// These instructions are partitioned into a few different sets, since this makes ZIR instruction mapping
41464016/// more effective.
......@@ -4524,7 +4394,7 @@ fn findTrackableInner(
45244394 try zir.findTrackableBody(gpa, contents, defers, body);
45254395 },
45264396
4527 // Reifications and opaque declarations need tracking, but have no body.
4397 // Reifications and opaque declarations need tracking, but have no bodies.
45284398 .reify_enum,
45294399 .reify_struct,
45304400 .reify_union,
......@@ -4535,150 +4405,37 @@ fn findTrackableInner(
45354405 .struct_decl => {
45364406 try contents.explicit_types.append(gpa, inst);
45374407
4538 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
4539 const extra = zir.extraData(Zir.Inst.StructDecl, extended.operand);
4540 var extra_index = extra.end;
4541 const captures_len = if (small.has_captures_len) blk: {
4542 const captures_len = zir.extra[extra_index];
4543 extra_index += 1;
4544 break :blk captures_len;
4545 } else 0;
4546 const fields_len = if (small.has_fields_len) blk: {
4547 const fields_len = zir.extra[extra_index];
4548 extra_index += 1;
4549 break :blk fields_len;
4550 } else 0;
4551 const decls_len = if (small.has_decls_len) blk: {
4552 const decls_len = zir.extra[extra_index];
4553 extra_index += 1;
4554 break :blk decls_len;
4555 } else 0;
4556 extra_index += captures_len * 2;
4557 if (small.has_backing_int) {
4558 const backing_int_body_len = zir.extra[extra_index];
4559 extra_index += 1;
4560 if (backing_int_body_len == 0) {
4561 extra_index += 1; // backing_int_ref
4562 } else {
4563 const body = zir.bodySlice(extra_index, backing_int_body_len);
4564 extra_index += backing_int_body_len;
4565 try zir.findTrackableBody(gpa, contents, defers, body);
4566 }
4408 const struct_decl = zir.getStructDecl(inst);
4409 var it = struct_decl.iterateFields();
4410 while (it.next()) |field| {
4411 try zir.findTrackableBody(gpa, contents, defers, field.type_body);
4412 if (field.align_body) |b| try zir.findTrackableBody(gpa, contents, defers, b);
4413 if (field.default_body) |b| try zir.findTrackableBody(gpa, contents, defers, b);
45674414 }
4568 extra_index += decls_len;
4569
4570 // This ZIR is structured in a slightly awkward way, so we have to split up the iteration.
4571 // `extra_index` iterates `flags` (bags of bits).
4572 // `fields_extra_index` iterates `fields`.
4573 // We accumulate the total length of bodies into `total_bodies_len`. This is sufficient because
4574 // the bodies are packed together in `extra` and we only need to traverse their instructions (we
4575 // don't really care about the structure).
4576
4577 const bits_per_field = 4;
4578 const fields_per_u32 = 32 / bits_per_field;
4579 const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;
4580 var cur_bit_bag: u32 = undefined;
4581
4582 var fields_extra_index = extra_index + bit_bags_count;
4583 var total_bodies_len: u32 = 0;
4584
4585 for (0..fields_len) |field_i| {
4586 if (field_i % fields_per_u32 == 0) {
4587 cur_bit_bag = zir.extra[extra_index];
4588 extra_index += 1;
4589 }
4590
4591 const has_align = @as(u1, @truncate(cur_bit_bag)) != 0;
4592 cur_bit_bag >>= 1;
4593 const has_init = @as(u1, @truncate(cur_bit_bag)) != 0;
4594 cur_bit_bag >>= 2; // also skip `is_comptime`; we don't care
4595 const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;
4596 cur_bit_bag >>= 1;
4597
4598 fields_extra_index += 1; // field_name
4599
4600 if (has_type_body) {
4601 const field_type_body_len = zir.extra[fields_extra_index];
4602 total_bodies_len += field_type_body_len;
4603 }
4604 fields_extra_index += 1; // field_type or field_type_body_len
4605
4606 if (has_align) {
4607 const align_body_len = zir.extra[fields_extra_index];
4608 fields_extra_index += 1;
4609 total_bodies_len += align_body_len;
4610 }
4611
4612 if (has_init) {
4613 const init_body_len = zir.extra[fields_extra_index];
4614 fields_extra_index += 1;
4615 total_bodies_len += init_body_len;
4616 }
4617 }
4618
4619 // Now, `fields_extra_index` points to `bodies`. Let's treat this as one big body.
4620 const merged_bodies = zir.bodySlice(fields_extra_index, total_bodies_len);
4621 try zir.findTrackableBody(gpa, contents, defers, merged_bodies);
46224415 },
46234416
4624 // Union declarations need tracking and have a body.
4417 // Union declarations need tracking and have bodies.
46254418 .union_decl => {
46264419 try contents.explicit_types.append(gpa, inst);
46274420
4628 const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small);
4629 const extra = zir.extraData(Zir.Inst.UnionDecl, extended.operand);
4630 var extra_index = extra.end;
4631 extra_index += @intFromBool(small.has_tag_type);
4632 const captures_len = if (small.has_captures_len) blk: {
4633 const captures_len = zir.extra[extra_index];
4634 extra_index += 1;
4635 break :blk captures_len;
4636 } else 0;
4637 const body_len = if (small.has_body_len) blk: {
4638 const body_len = zir.extra[extra_index];
4639 extra_index += 1;
4640 break :blk body_len;
4641 } else 0;
4642 extra_index += @intFromBool(small.has_fields_len);
4643 const decls_len = if (small.has_decls_len) blk: {
4644 const decls_len = zir.extra[extra_index];
4645 extra_index += 1;
4646 break :blk decls_len;
4647 } else 0;
4648 extra_index += captures_len * 2;
4649 extra_index += decls_len;
4650 const body = zir.bodySlice(extra_index, body_len);
4651 try zir.findTrackableBody(gpa, contents, defers, body);
4421 const union_decl = zir.getUnionDecl(inst);
4422 var it = union_decl.iterateFields();
4423 while (it.next()) |field| {
4424 if (field.type_body) |b| try zir.findTrackableBody(gpa, contents, defers, b);
4425 if (field.align_body) |b| try zir.findTrackableBody(gpa, contents, defers, b);
4426 if (field.value_body) |b| try zir.findTrackableBody(gpa, contents, defers, b);
4427 }
46524428 },
46534429
4654 // Enum declarations need tracking and have a body.
4430 // Enum declarations need tracking and have bodies.
46554431 .enum_decl => {
46564432 try contents.explicit_types.append(gpa, inst);
46574433
4658 const small: Zir.Inst.EnumDecl.Small = @bitCast(extended.small);
4659 const extra = zir.extraData(Zir.Inst.EnumDecl, extended.operand);
4660 var extra_index = extra.end;
4661 extra_index += @intFromBool(small.has_tag_type);
4662 const captures_len = if (small.has_captures_len) blk: {
4663 const captures_len = zir.extra[extra_index];
4664 extra_index += 1;
4665 break :blk captures_len;
4666 } else 0;
4667 const body_len = if (small.has_body_len) blk: {
4668 const body_len = zir.extra[extra_index];
4669 extra_index += 1;
4670 break :blk body_len;
4671 } else 0;
4672 extra_index += @intFromBool(small.has_fields_len);
4673 const decls_len = if (small.has_decls_len) blk: {
4674 const decls_len = zir.extra[extra_index];
4675 extra_index += 1;
4676 break :blk decls_len;
4677 } else 0;
4678 extra_index += captures_len * 2;
4679 extra_index += decls_len;
4680 const body = zir.bodySlice(extra_index, body_len);
4681 try zir.findTrackableBody(gpa, contents, defers, body);
4434 const enum_decl = zir.getEnumDecl(inst);
4435 var it = enum_decl.iterateFields();
4436 while (it.next()) |field| {
4437 if (field.value_body) |b| try zir.findTrackableBody(gpa, contents, defers, b);
4438 }
46824439 },
46834440 }
46844441 },
......@@ -5481,34 +5238,455 @@ pub fn assertTrackable(zir: Zir, inst_idx: Zir.Inst.Index) void {
54815238 }
54825239}
54835240
5484pub fn typeCapturesLen(zir: Zir, type_decl: Inst.Index) u32 {
5241pub fn typeDecls(zir: Zir, type_decl: Inst.Index) []const Zir.Inst.Index {
54855242 const inst = zir.instructions.get(@intFromEnum(type_decl));
54865243 assert(inst.tag == .extended);
5487 switch (inst.data.extended.opcode) {
5488 .struct_decl => {
5489 const small: Inst.StructDecl.Small = @bitCast(inst.data.extended.small);
5490 if (!small.has_captures_len) return 0;
5491 const extra = zir.extraData(Inst.StructDecl, inst.data.extended.operand);
5492 return zir.extra[extra.end];
5493 },
5494 .union_decl => {
5495 const small: Inst.UnionDecl.Small = @bitCast(inst.data.extended.small);
5496 if (!small.has_captures_len) return 0;
5497 const extra = zir.extraData(Inst.UnionDecl, inst.data.extended.operand);
5498 return zir.extra[extra.end + @intFromBool(small.has_tag_type)];
5499 },
5500 .enum_decl => {
5501 const small: Inst.EnumDecl.Small = @bitCast(inst.data.extended.small);
5502 if (!small.has_captures_len) return 0;
5503 const extra = zir.extraData(Inst.EnumDecl, inst.data.extended.operand);
5504 return zir.extra[extra.end + @intFromBool(small.has_tag_type)];
5505 },
5506 .opaque_decl => {
5507 const small: Inst.OpaqueDecl.Small = @bitCast(inst.data.extended.small);
5508 if (!small.has_captures_len) return 0;
5509 const extra = zir.extraData(Inst.OpaqueDecl, inst.data.extended.operand);
5510 return zir.extra[extra.end];
5511 },
5244 return switch (inst.data.extended.opcode) {
5245 .struct_decl => zir.getStructDecl(type_decl).decls,
5246 .union_decl => zir.getUnionDecl(type_decl).decls,
5247 .enum_decl => zir.getEnumDecl(type_decl).decls,
5248 .opaque_decl => zir.getOpaqueDecl(type_decl).decls,
55125249 else => unreachable,
5250 };
5251}
5252
5253pub fn getStructDecl(zir: *const Zir, struct_decl: Inst.Index) UnwrappedStructDecl {
5254 const inst_data = zir.instructions.get(@intFromEnum(struct_decl));
5255 assert(inst_data.tag == .extended);
5256 assert(inst_data.data.extended.opcode == .struct_decl);
5257 const small: Inst.StructDecl.Small = @bitCast(inst_data.data.extended.small);
5258 const extra = zir.extraData(Inst.StructDecl, inst_data.data.extended.operand);
5259 var extra_index = extra.end;
5260 const captures_len: u32 = if (small.has_captures_len) blk: {
5261 const captures_len = zir.extra[extra_index];
5262 extra_index += 1;
5263 break :blk captures_len;
5264 } else 0;
5265 const decls_len: u32 = if (small.has_decls_len) blk: {
5266 const decls_len = zir.extra[extra_index];
5267 extra_index += 1;
5268 break :blk decls_len;
5269 } else 0;
5270 const fields_len: u32 = if (small.has_fields_len) blk: {
5271 const fields_len = zir.extra[extra_index];
5272 extra_index += 1;
5273 break :blk fields_len;
5274 } else 0;
5275 const backing_int_type_body_len: u32 = if (small.has_backing_int_type) len: {
5276 const body_len = zir.extra[extra_index];
5277 extra_index += 1;
5278 break :len body_len;
5279 } else 0;
5280 const captures: []const Inst.Capture = @ptrCast(zir.extra[extra_index..][0..captures_len]);
5281 extra_index += captures_len;
5282 const capture_names: []const NullTerminatedString = @ptrCast(zir.extra[extra_index..][0..captures_len]);
5283 extra_index += captures_len;
5284 const decls: []const Inst.Index = @ptrCast(zir.extra[extra_index..][0..decls_len]);
5285 extra_index += decls_len;
5286 const field_names: []const NullTerminatedString = @ptrCast(zir.extra[extra_index..][0..fields_len]);
5287 extra_index += fields_len;
5288 const field_type_body_lens: []const u32 = @ptrCast(zir.extra[extra_index..][0..fields_len]);
5289 extra_index += fields_len;
5290 const field_align_body_lens: ?[]const u32 = if (small.any_field_aligns) lens: {
5291 const lens = zir.extra[extra_index..][0..fields_len];
5292 extra_index += fields_len;
5293 break :lens @ptrCast(lens);
5294 } else null;
5295 const field_default_body_lens: ?[]const u32 = if (small.any_field_defaults) lens: {
5296 const lens = zir.extra[extra_index..][0..fields_len];
5297 extra_index += fields_len;
5298 break :lens @ptrCast(lens);
5299 } else null;
5300 const field_comptime_bits: ?[]const u32 = if (small.any_comptime_fields) bits: {
5301 const bits_len = std.math.divCeil(u32, fields_len, 32) catch unreachable;
5302 const bits = zir.extra[extra_index..][0..bits_len];
5303 extra_index += bits_len;
5304 break :bits bits;
5305 } else null;
5306 const backing_int_type_body: ?[]const Zir.Inst.Index = switch (backing_int_type_body_len) {
5307 0 => null,
5308 else => |n| zir.bodySlice(extra_index, n),
5309 };
5310 extra_index += backing_int_type_body_len;
5311 const field_bodies_overlong: []const Inst.Index = @ptrCast(zir.extra[extra_index..]);
5312 return .{
5313 .src_line = extra.data.src_line,
5314 .src_node = extra.data.src_node,
5315 .name_strategy = small.name_strategy,
5316 .captures = captures,
5317 .capture_names = capture_names,
5318 .decls = decls,
5319 .layout = small.layout,
5320 .backing_int_type_body = backing_int_type_body,
5321 .field_names = field_names,
5322 .field_type_body_lens = field_type_body_lens,
5323 .field_align_body_lens = field_align_body_lens,
5324 .field_default_body_lens = field_default_body_lens,
5325 .field_comptime_bits = field_comptime_bits,
5326 .field_bodies_overlong = field_bodies_overlong,
5327 };
5328}
5329pub const UnwrappedStructDecl = struct {
5330 src_line: u32,
5331 src_node: Ast.Node.Index,
5332 name_strategy: Inst.NameStrategy,
5333
5334 captures: []const Inst.Capture,
5335 capture_names: []const NullTerminatedString,
5336
5337 decls: []const Inst.Index,
5338
5339 layout: std.builtin.Type.ContainerLayout,
5340 backing_int_type_body: ?[]const Inst.Index,
5341
5342 field_names: []const NullTerminatedString,
5343 field_type_body_lens: []const u32,
5344 field_align_body_lens: ?[]const u32,
5345 field_default_body_lens: ?[]const u32,
5346 field_comptime_bits: ?[]const u32,
5347 field_bodies_overlong: []const Inst.Index,
5348
5349 pub fn iterateFields(struct_decl: UnwrappedStructDecl) FieldIterator {
5350 return .{
5351 .next_idx = 0,
5352 .names = struct_decl.field_names,
5353 .type_body_lens = struct_decl.field_type_body_lens,
5354 .align_body_lens = struct_decl.field_align_body_lens,
5355 .default_body_lens = struct_decl.field_default_body_lens,
5356 .comptime_bits = struct_decl.field_comptime_bits,
5357 .bodies_overlong = struct_decl.field_bodies_overlong,
5358 };
55135359 }
5360
5361 pub const FieldIterator = struct {
5362 next_idx: u32,
5363 names: []const NullTerminatedString,
5364 type_body_lens: []const u32,
5365 align_body_lens: ?[]const u32,
5366 default_body_lens: ?[]const u32,
5367 comptime_bits: ?[]const u32,
5368 bodies_overlong: []const Inst.Index,
5369 pub const Field = struct {
5370 idx: u32,
5371 name: NullTerminatedString,
5372 type_body: []const Inst.Index,
5373 align_body: ?[]const Inst.Index,
5374 default_body: ?[]const Inst.Index,
5375 is_comptime: bool,
5376 };
5377 pub fn next(it: *FieldIterator) ?Field {
5378 const idx = it.next_idx;
5379 if (idx == it.names.len) return null;
5380 it.next_idx += 1;
5381 return .{
5382 .idx = idx,
5383 .name = it.names[idx],
5384 .type_body = it.body(it.type_body_lens[idx]).?,
5385 .align_body = it.body(if (it.align_body_lens) |l| l[idx] else 0),
5386 .default_body = it.body(if (it.default_body_lens) |l| l[idx] else 0),
5387 .is_comptime = ct: {
5388 const bits = it.comptime_bits orelse break :ct false;
5389 const big = bits[idx / 32];
5390 const shifted = big >> @intCast(idx % 32);
5391 break :ct @as(u1, @truncate(shifted)) == 1;
5392 },
5393 };
5394 }
5395 fn body(it: *FieldIterator, len: u32) ?[]const Inst.Index {
5396 if (len == 0) return null;
5397 const b = it.bodies_overlong[0..len];
5398 it.bodies_overlong = it.bodies_overlong[len..];
5399 return b;
5400 }
5401 };
5402};
5403
5404pub fn getUnionDecl(zir: *const Zir, union_decl: Inst.Index) UnwrappedUnionDecl {
5405 const inst_data = zir.instructions.get(@intFromEnum(union_decl));
5406 assert(inst_data.tag == .extended);
5407 assert(inst_data.data.extended.opcode == .union_decl);
5408 const small: Inst.UnionDecl.Small = @bitCast(inst_data.data.extended.small);
5409 const extra = zir.extraData(Inst.UnionDecl, inst_data.data.extended.operand);
5410 var extra_index = extra.end;
5411 const captures_len: u32 = if (small.has_captures_len) blk: {
5412 const captures_len = zir.extra[extra_index];
5413 extra_index += 1;
5414 break :blk captures_len;
5415 } else 0;
5416 const decls_len: u32 = if (small.has_decls_len) blk: {
5417 const decls_len = zir.extra[extra_index];
5418 extra_index += 1;
5419 break :blk decls_len;
5420 } else 0;
5421 const fields_len: u32 = if (small.has_fields_len) blk: {
5422 const fields_len = zir.extra[extra_index];
5423 extra_index += 1;
5424 break :blk fields_len;
5425 } else 0;
5426 const arg_type_body_len: u32 = if (small.kind.hasArgType()) len: {
5427 const body_len = zir.extra[extra_index];
5428 extra_index += 1;
5429 break :len body_len;
5430 } else 0;
5431 const captures: []const Inst.Capture = @ptrCast(zir.extra[extra_index..][0..captures_len]);
5432 extra_index += captures_len;
5433 const capture_names: []const NullTerminatedString = @ptrCast(zir.extra[extra_index..][0..captures_len]);
5434 extra_index += captures_len;
5435 const decls: []const Inst.Index = @ptrCast(zir.extra[extra_index..][0..decls_len]);
5436 extra_index += decls_len;
5437 const field_names: []const NullTerminatedString = @ptrCast(zir.extra[extra_index..][0..fields_len]);
5438 extra_index += fields_len;
5439 const field_type_body_lens: []const u32 = @ptrCast(zir.extra[extra_index..][0..fields_len]);
5440 extra_index += fields_len;
5441 const field_align_body_lens: ?[]const u32 = if (small.any_field_aligns) lens: {
5442 const lens = zir.extra[extra_index..][0..fields_len];
5443 extra_index += fields_len;
5444 break :lens @ptrCast(lens);
5445 } else null;
5446 const field_value_body_lens: ?[]const u32 = if (small.any_field_values) lens: {
5447 const lens = zir.extra[extra_index..][0..fields_len];
5448 extra_index += fields_len;
5449 break :lens @ptrCast(lens);
5450 } else null;
5451 const arg_type_body: ?[]const Zir.Inst.Index = switch (arg_type_body_len) {
5452 0 => null,
5453 else => |n| zir.bodySlice(extra_index, n),
5454 };
5455 extra_index += arg_type_body_len;
5456 const field_bodies_overlong: []const Inst.Index = @ptrCast(zir.extra[extra_index..]);
5457 return .{
5458 .src_line = extra.data.src_line,
5459 .src_node = extra.data.src_node,
5460 .name_strategy = small.name_strategy,
5461 .captures = captures,
5462 .capture_names = capture_names,
5463 .decls = decls,
5464 .kind = small.kind,
5465 .arg_type_body = arg_type_body,
5466 .field_names = field_names,
5467 .field_type_body_lens = field_type_body_lens,
5468 .field_align_body_lens = field_align_body_lens,
5469 .field_value_body_lens = field_value_body_lens,
5470 .field_bodies_overlong = field_bodies_overlong,
5471 };
55145472}
5473pub const UnwrappedUnionDecl = struct {
5474 src_line: u32,
5475 src_node: Ast.Node.Index,
5476 name_strategy: Inst.NameStrategy,
5477
5478 captures: []const Inst.Capture,
5479 capture_names: []const NullTerminatedString,
5480
5481 decls: []const Inst.Index,
5482
5483 kind: Inst.UnionDecl.Kind,
5484 arg_type_body: ?[]const Inst.Index,
5485
5486 field_names: []const NullTerminatedString,
5487 field_type_body_lens: []const u32,
5488 field_align_body_lens: ?[]const u32,
5489 field_value_body_lens: ?[]const u32,
5490 field_bodies_overlong: []const Inst.Index,
5491
5492 pub fn iterateFields(union_decl: UnwrappedUnionDecl) FieldIterator {
5493 return .{
5494 .next_idx = 0,
5495 .names = union_decl.field_names,
5496 .type_body_lens = union_decl.field_type_body_lens,
5497 .align_body_lens = union_decl.field_align_body_lens,
5498 .value_body_lens = union_decl.field_value_body_lens,
5499 .bodies_overlong = union_decl.field_bodies_overlong,
5500 };
5501 }
5502
5503 pub const FieldIterator = struct {
5504 next_idx: u32,
5505 names: []const NullTerminatedString,
5506 type_body_lens: []const u32,
5507 align_body_lens: ?[]const u32,
5508 value_body_lens: ?[]const u32,
5509 bodies_overlong: []const Inst.Index,
5510 pub const Field = struct {
5511 idx: u32,
5512 name: NullTerminatedString,
5513 type_body: ?[]const Inst.Index,
5514 align_body: ?[]const Inst.Index,
5515 value_body: ?[]const Inst.Index,
5516 };
5517 pub fn next(it: *FieldIterator) ?Field {
5518 const idx = it.next_idx;
5519 if (idx == it.names.len) return null;
5520 it.next_idx += 1;
5521 return .{
5522 .idx = idx,
5523 .name = it.names[idx],
5524 .type_body = it.body(it.type_body_lens[idx]),
5525 .align_body = it.body(if (it.align_body_lens) |l| l[idx] else 0),
5526 .value_body = it.body(if (it.value_body_lens) |l| l[idx] else 0),
5527 };
5528 }
5529 fn body(it: *FieldIterator, len: u32) ?[]const Inst.Index {
5530 if (len == 0) return null;
5531 const b = it.bodies_overlong[0..len];
5532 it.bodies_overlong = it.bodies_overlong[len..];
5533 return b;
5534 }
5535 };
5536};
5537
5538pub fn getEnumDecl(zir: *const Zir, enum_decl: Inst.Index) UnwrappedEnumDecl {
5539 const inst_data = zir.instructions.get(@intFromEnum(enum_decl));
5540 assert(inst_data.tag == .extended);
5541 assert(inst_data.data.extended.opcode == .enum_decl);
5542 const small: Inst.EnumDecl.Small = @bitCast(inst_data.data.extended.small);
5543 const extra = zir.extraData(Inst.EnumDecl, inst_data.data.extended.operand);
5544 var extra_index = extra.end;
5545 const captures_len: u32 = if (small.has_captures_len) blk: {
5546 const captures_len = zir.extra[extra_index];
5547 extra_index += 1;
5548 break :blk captures_len;
5549 } else 0;
5550 const decls_len: u32 = if (small.has_decls_len) blk: {
5551 const decls_len = zir.extra[extra_index];
5552 extra_index += 1;
5553 break :blk decls_len;
5554 } else 0;
5555 const fields_len: u32 = if (small.has_fields_len) blk: {
5556 const fields_len = zir.extra[extra_index];
5557 extra_index += 1;
5558 break :blk fields_len;
5559 } else 0;
5560 const tag_type_body_len: u32 = if (small.has_tag_type) len: {
5561 const body_len = zir.extra[extra_index];
5562 extra_index += 1;
5563 break :len body_len;
5564 } else 0;
5565 const captures: []const Inst.Capture = @ptrCast(zir.extra[extra_index..][0..captures_len]);
5566 extra_index += captures_len;
5567 const capture_names: []const NullTerminatedString = @ptrCast(zir.extra[extra_index..][0..captures_len]);
5568 extra_index += captures_len;
5569 const decls: []const Inst.Index = @ptrCast(zir.extra[extra_index..][0..decls_len]);
5570 extra_index += decls_len;
5571 const field_names: []const NullTerminatedString = @ptrCast(zir.extra[extra_index..][0..fields_len]);
5572 extra_index += fields_len;
5573 const field_value_body_lens: ?[]const u32 = if (small.any_field_values) lens: {
5574 const lens = zir.extra[extra_index..][0..fields_len];
5575 extra_index += fields_len;
5576 break :lens @ptrCast(lens);
5577 } else null;
5578 const tag_type_body: ?[]const Zir.Inst.Index = switch (tag_type_body_len) {
5579 0 => null,
5580 else => |n| zir.bodySlice(extra_index, n),
5581 };
5582 extra_index += tag_type_body_len;
5583 const field_bodies_overlong: []const Inst.Index = @ptrCast(zir.extra[extra_index..]);
5584 return .{
5585 .src_line = extra.data.src_line,
5586 .src_node = extra.data.src_node,
5587 .name_strategy = small.name_strategy,
5588 .captures = captures,
5589 .capture_names = capture_names,
5590 .decls = decls,
5591 .tag_type_body = tag_type_body,
5592 .nonexhaustive = small.nonexhaustive,
5593 .field_names = field_names,
5594 .field_value_body_lens = field_value_body_lens,
5595 .field_bodies_overlong = field_bodies_overlong,
5596 };
5597}
5598pub const UnwrappedEnumDecl = struct {
5599 src_line: u32,
5600 src_node: Ast.Node.Index,
5601 name_strategy: Inst.NameStrategy,
5602
5603 captures: []const Inst.Capture,
5604 capture_names: []const NullTerminatedString,
5605
5606 decls: []const Inst.Index,
5607
5608 tag_type_body: ?[]const Inst.Index,
5609 nonexhaustive: bool,
5610
5611 field_names: []const NullTerminatedString,
5612 field_value_body_lens: ?[]const u32,
5613 field_bodies_overlong: []const Inst.Index,
5614
5615 pub fn iterateFields(enum_decl: UnwrappedEnumDecl) FieldIterator {
5616 return .{
5617 .next_idx = 0,
5618 .names = enum_decl.field_names,
5619 .value_body_lens = enum_decl.field_value_body_lens,
5620 .bodies_overlong = enum_decl.field_bodies_overlong,
5621 };
5622 }
5623
5624 pub const FieldIterator = struct {
5625 next_idx: u32,
5626 names: []const NullTerminatedString,
5627 value_body_lens: ?[]const u32,
5628 bodies_overlong: []const Inst.Index,
5629 pub const Field = struct {
5630 idx: u32,
5631 name: NullTerminatedString,
5632 value_body: ?[]const Inst.Index,
5633 };
5634 pub fn next(it: *FieldIterator) ?Field {
5635 const idx = it.next_idx;
5636 if (idx == it.names.len) return null;
5637 it.next_idx += 1;
5638 return .{
5639 .idx = idx,
5640 .name = it.names[idx],
5641 .value_body = it.body(if (it.value_body_lens) |l| l[idx] else 0),
5642 };
5643 }
5644 fn body(it: *FieldIterator, len: u32) ?[]const Inst.Index {
5645 if (len == 0) return null;
5646 const b = it.bodies_overlong[0..len];
5647 it.bodies_overlong = it.bodies_overlong[len..];
5648 return b;
5649 }
5650 };
5651};
5652
5653pub fn getOpaqueDecl(zir: *const Zir, opaque_decl: Inst.Index) UnwrappedOpaqueDecl {
5654 const inst_data = zir.instructions.get(@intFromEnum(opaque_decl));
5655 assert(inst_data.tag == .extended);
5656 assert(inst_data.data.extended.opcode == .opaque_decl);
5657 const small: Inst.OpaqueDecl.Small = @bitCast(inst_data.data.extended.small);
5658 const extra = zir.extraData(Inst.OpaqueDecl, inst_data.data.extended.operand);
5659 var extra_index = extra.end;
5660 const captures_len: u32 = if (small.has_captures_len) blk: {
5661 const captures_len = zir.extra[extra_index];
5662 extra_index += 1;
5663 break :blk captures_len;
5664 } else 0;
5665 const decls_len: u32 = if (small.has_decls_len) blk: {
5666 const decls_len = zir.extra[extra_index];
5667 extra_index += 1;
5668 break :blk decls_len;
5669 } else 0;
5670 const captures: []const Inst.Capture = @ptrCast(zir.extra[extra_index..][0..captures_len]);
5671 extra_index += captures_len;
5672 const capture_names: []const NullTerminatedString = @ptrCast(zir.extra[extra_index..][0..captures_len]);
5673 extra_index += captures_len;
5674 const decls: []const Inst.Index = @ptrCast(zir.extra[extra_index..][0..decls_len]);
5675 extra_index += decls_len;
5676 return .{
5677 .src_line = extra.data.src_line,
5678 .src_node = extra.data.src_node,
5679 .name_strategy = small.name_strategy,
5680 .captures = captures,
5681 .capture_names = capture_names,
5682 .decls = decls,
5683 };
5684}
5685pub const UnwrappedOpaqueDecl = struct {
5686 src_line: u32,
5687 src_node: Ast.Node.Index,
5688 name_strategy: Inst.NameStrategy,
5689 captures: []const Inst.Capture,
5690 capture_names: []const NullTerminatedString,
5691 decls: []const Inst.Index,
5692};
lib/std/zig/llvm/BitcodeReader.zig+5-5
......@@ -34,8 +34,8 @@ pub const Block = struct {
3434
3535 const default: Info = .{
3636 .block_name = &.{},
37 .record_names = .{},
38 .abbrevs = .{ .abbrevs = .{} },
37 .record_names = .empty,
38 .abbrevs = .{ .abbrevs = .empty },
3939 };
4040
4141 const set_bid_id: u32 = 1;
......@@ -109,8 +109,8 @@ pub fn init(allocator: std.mem.Allocator, options: InitOptions) BitcodeReader {
109109 .keep_names = options.keep_names,
110110 .bit_buffer = 0,
111111 .bit_offset = 0,
112 .stack = .{},
113 .block_info = .{},
112 .stack = .empty,
113 .block_info = .empty,
114114 };
115115}
116116
......@@ -278,7 +278,7 @@ fn startBlock(bc: *BitcodeReader, block_id: ?u32, new_abbrev_len: u6) !void {
278278 state.* = .{
279279 .block_id = block_id,
280280 .abbrev_id_width = new_abbrev_len,
281 .abbrevs = .{ .abbrevs = .{} },
281 .abbrevs = .{ .abbrevs = .empty },
282282 };
283283 try state.abbrevs.abbrevs.ensureTotalCapacity(
284284 bc.allocator,
lib/std/zig/llvm/Builder.zig+238-126
......@@ -7,6 +7,7 @@ const Allocator = std.mem.Allocator;
77const assert = std.debug.assert;
88const DW = std.dwarf;
99const log = std.log.scoped(.llvm);
10const maxInt = std.math.maxInt;
1011const Writer = std.Io.Writer;
1112
1213const bitcode_writer = @import("bitcode_writer.zig");
......@@ -55,6 +56,8 @@ constant_items: std.MultiArrayList(Constant.Item),
5556constant_extra: std.ArrayList(u32),
5657constant_limbs: std.ArrayList(std.math.big.Limb),
5758
59alignment_forward_references: std.ArrayList(Alignment),
60
5861metadata_map: std.AutoArrayHashMapUnmanaged(void, void),
5962metadata_items: std.MultiArrayList(Metadata.Item),
6063metadata_extra: std.ArrayList(u32),
......@@ -85,7 +88,7 @@ pub const Options = struct {
8588};
8689
8790pub const String = enum(u32) {
88 none = std.math.maxInt(u31),
91 none = maxInt(u31),
8992 empty,
9093 _,
9194
......@@ -245,7 +248,7 @@ pub const Type = enum(u32) {
245248 ptr,
246249 @"ptr addrspace(4)",
247250
248 none = std.math.maxInt(u32),
251 none = maxInt(u32),
249252 _,
250253
251254 pub const ptr_amdgpu_constant =
......@@ -941,7 +944,7 @@ pub const Attribute = union(Kind) {
941944 inalloca: Type,
942945 sret: Type,
943946 elementtype: Type,
944 @"align": Alignment,
947 @"align": Alignment.Lazy,
945948 @"noalias",
946949 nocapture,
947950 nofree,
......@@ -956,7 +959,7 @@ pub const Attribute = union(Kind) {
956959 immarg,
957960 noundef,
958961 nofpclass: FpClass,
959 alignstack: Alignment,
962 alignstack: Alignment.Lazy,
960963 allocalign,
961964 allocptr,
962965 readnone,
......@@ -964,7 +967,7 @@ pub const Attribute = union(Kind) {
964967 writeonly,
965968
966969 // Function Attributes
967 //alignstack: Alignment,
970 //alignstack: Alignment.Lazy,
968971 allockind: AllocKind,
969972 allocsize: AllocSize,
970973 alwaysinline,
......@@ -1145,7 +1148,7 @@ pub const Attribute = union(Kind) {
11451148 return @unionInit(Attribute, field.name, switch (field.type) {
11461149 void => {},
11471150 u32 => storage.value,
1148 Alignment, String, Type, UwTable => @enumFromInt(storage.value),
1151 Alignment.Lazy, String, Type, UwTable => @enumFromInt(storage.value),
11491152 AllocKind, AllocSize, FpClass, Memory, VScaleRange => @bitCast(storage.value),
11501153 else => @compileError("bad payload type: " ++ field.name ++ ": " ++
11511154 @typeName(field.type)),
......@@ -1246,7 +1249,7 @@ pub const Attribute = union(Kind) {
12461249 .sret,
12471250 .elementtype,
12481251 => |ty| try w.print(" {s}({f})", .{ @tagName(attribute), ty.fmt(data.builder, .percent) }),
1249 .@"align" => |alignment| try w.print("{f}", .{alignment.fmt(" ")}),
1252 .@"align" => |alignment| try w.print("{f}", .{alignment.resolve(data.builder).fmt(" ")}),
12501253 .dereferenceable,
12511254 .dereferenceable_or_null,
12521255 => |size| try w.print(" {s}({d})", .{ @tagName(attribute), size }),
......@@ -1270,7 +1273,7 @@ pub const Attribute = union(Kind) {
12701273 },
12711274 .alignstack => |alignment| {
12721275 try w.print(" {t}", .{attribute});
1273 const alignment_bytes = alignment.toByteUnits() orelse return;
1276 const alignment_bytes = alignment.resolve(data.builder).toByteUnits() orelse return;
12741277 if (data.flags.pound) {
12751278 try w.print("={d}", .{alignment_bytes});
12761279 } else {
......@@ -1435,8 +1438,8 @@ pub const Attribute = union(Kind) {
14351438 //sanitize_memtag,
14361439 sanitize_address_dyninit = 102,
14371440
1438 string = std.math.maxInt(u31),
1439 none = std.math.maxInt(u32),
1441 string = maxInt(u31),
1442 none = maxInt(u32),
14401443 _,
14411444
14421445 pub const len = @typeInfo(Kind).@"enum".fields.len - 2;
......@@ -1516,12 +1519,12 @@ pub const Attribute = union(Kind) {
15161519 elem_size: u16,
15171520 num_elems: u16,
15181521
1519 pub const none = std.math.maxInt(u16);
1522 pub const none = maxInt(u16);
15201523
15211524 fn toLlvm(self: AllocSize) packed struct(u64) { num_elems: u32, elem_size: u32 } {
15221525 return .{ .num_elems = switch (self.num_elems) {
15231526 else => self.num_elems,
1524 none => std.math.maxInt(u32),
1527 none => maxInt(u32),
15251528 }, .elem_size = self.elem_size };
15261529 }
15271530 };
......@@ -1577,7 +1580,7 @@ pub const Attribute = union(Kind) {
15771580 inline else => |value, tag| .{ .kind = @as(Kind, self), .value = switch (@TypeOf(value)) {
15781581 void => 0,
15791582 u32 => value,
1580 Alignment, String, Type, UwTable => @intFromEnum(value),
1583 Alignment.Lazy, String, Type, UwTable => @intFromEnum(value),
15811584 AllocKind, AllocSize, FpClass, Memory, VScaleRange => @bitCast(value),
15821585 else => @compileError("bad payload type: " ++ @tagName(tag) ++ @typeName(@TypeOf(value))),
15831586 } },
......@@ -1627,7 +1630,7 @@ pub const FunctionAttributes = enum(u32) {
16271630 const params_index = 2;
16281631
16291632 pub const Wip = struct {
1630 maps: Maps = .{},
1633 maps: Maps = .empty,
16311634
16321635 const Map = std.AutoArrayHashMapUnmanaged(Attribute.Kind, Attribute.Index);
16331636 const Maps = std.ArrayList(Map);
......@@ -2017,9 +2020,32 @@ pub const ExternallyInitialized = enum {
20172020};
20182021
20192022pub const Alignment = enum(u6) {
2020 default = std.math.maxInt(u6),
2023 default = maxInt(u6),
20212024 _,
20222025
2026 pub const Lazy = enum(u32) {
2027 /// Values which fit in a `u6` are already-resolved `Alignment` values. Other values are
2028 /// indices into `Builder.alignment_forward_references`, offset by `maxInt(u6)`.
2029 _,
2030
2031 pub fn wrap(a: Alignment) Lazy {
2032 return @enumFromInt(@intFromEnum(a));
2033 }
2034 pub fn resolve(l: Lazy, b: *const Builder) Alignment {
2035 return switch (@intFromEnum(l)) {
2036 0...maxInt(u6) => |raw| @enumFromInt(raw),
2037 else => |offset_index| b.alignment_forward_references.items[offset_index - maxInt(u6)],
2038 };
2039 }
2040
2041 fn fromFwdRefIndex(index: usize) Lazy {
2042 return @enumFromInt(index + maxInt(u6));
2043 }
2044 fn toFwdRefIndex(l: Lazy) usize {
2045 return @intFromEnum(l) - maxInt(u6);
2046 }
2047 };
2048
20232049 pub fn fromByteUnits(bytes: u64) Alignment {
20242050 if (bytes == 0) return .default;
20252051 assert(std.math.isPowerOfTwo(bytes));
......@@ -2028,11 +2054,17 @@ pub const Alignment = enum(u6) {
20282054 }
20292055
20302056 pub fn toByteUnits(self: Alignment) ?u64 {
2031 return if (self == .default) null else @as(u64, 1) << @intFromEnum(self);
2057 return switch (self) {
2058 .default => null,
2059 else => @as(u64, 1) << @intFromEnum(self),
2060 };
20322061 }
20332062
20342063 pub fn toLlvm(self: Alignment) u6 {
2035 return if (self == .default) 0 else (@intFromEnum(self) + 1);
2064 return switch (self) {
2065 .default => 0,
2066 else => @intFromEnum(self) + 1,
2067 };
20362068 }
20372069
20382070 pub const Prefixed = struct {
......@@ -2180,7 +2212,7 @@ pub const CallConv = enum(u10) {
21802212};
21812213
21822214pub const StrtabString = enum(u32) {
2183 none = std.math.maxInt(u31),
2215 none = maxInt(u31),
21842216 empty,
21852217 _,
21862218
......@@ -2308,7 +2340,7 @@ pub const Global = struct {
23082340 },
23092341
23102342 pub const Index = enum(u32) {
2311 none = std.math.maxInt(u32),
2343 none = maxInt(u32),
23122344 _,
23132345
23142346 pub fn unwrap(self: Index, builder: *const Builder) Index {
......@@ -2478,7 +2510,7 @@ pub const Alias = struct {
24782510 aliasee: Constant = .no_init,
24792511
24802512 pub const Index = enum(u32) {
2481 none = std.math.maxInt(u32),
2513 none = maxInt(u32),
24822514 _,
24832515
24842516 pub fn ptr(self: Index, builder: *Builder) *Alias {
......@@ -2530,7 +2562,7 @@ pub const Variable = struct {
25302562 alignment: Alignment = .default,
25312563
25322564 pub const Index = enum(u32) {
2533 none = std.math.maxInt(u32),
2565 none = maxInt(u32),
25342566 _,
25352567
25362568 pub fn ptr(self: Index, builder: *Builder) *Variable {
......@@ -3949,7 +3981,7 @@ pub const Intrinsic = enum {
39493981 .params = &.{
39503982 .{
39513983 .kind = .{ .type = Type.ptr_amdgpu_constant },
3952 .attrs = &.{.{ .@"align" = Builder.Alignment.fromByteUnits(4) }},
3984 .attrs = &.{.{ .@"align" = .wrap(.fromByteUnits(4)) }},
39533985 },
39543986 },
39553987 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
......@@ -4048,7 +4080,7 @@ pub const Function = struct {
40484080 section: String = .none,
40494081 alignment: Alignment = .default,
40504082 blocks: []const Block = &.{},
4051 instructions: std.MultiArrayList(Instruction) = .{},
4083 instructions: std.MultiArrayList(Instruction) = .empty,
40524084 names: [*]const String = &[0]String{},
40534085 value_indices: [*]const u32 = &[0]u32{},
40544086 strip: bool,
......@@ -4057,7 +4089,7 @@ pub const Function = struct {
40574089 extra: []const u32 = &.{},
40584090
40594091 pub const Index = enum(u32) {
4060 none = std.math.maxInt(u32),
4092 none = maxInt(u32),
40614093 _,
40624094
40634095 pub fn ptr(self: Index, builder: *Builder) *Function {
......@@ -4411,7 +4443,7 @@ pub const Function = struct {
44114443 };
44124444
44134445 pub const Index = enum(u32) {
4414 none = std.math.maxInt(u31),
4446 none = maxInt(u31),
44154447 _,
44164448
44174449 pub fn name(self: Instruction.Index, function: *const Function) String {
......@@ -5007,7 +5039,7 @@ pub const Function = struct {
50075039 fsub = 12,
50085040 fmax = 13,
50095041 fmin = 14,
5010 none = std.math.maxInt(u5),
5042 none = maxInt(u5),
50115043 };
50125044 };
50135045
......@@ -5222,13 +5254,13 @@ pub const WipFunction = struct {
52225254 .prev_debug_location = .no_location,
52235255 .debug_location = .no_location,
52245256 .cursor = undefined,
5225 .blocks = .{},
5226 .instructions = .{},
5227 .names = .{},
5257 .blocks = .empty,
5258 .instructions = .empty,
5259 .names = .empty,
52285260 .strip = options.strip,
5229 .debug_locations = .{},
5230 .debug_values = .{},
5231 .extra = .{},
5261 .debug_locations = .empty,
5262 .debug_values = .empty,
5263 .extra = .empty,
52325264 };
52335265 errdefer self.deinit();
52345266
......@@ -5265,7 +5297,7 @@ pub const WipFunction = struct {
52655297 self.blocks.appendAssumeCapacity(.{
52665298 .name = final_name,
52675299 .incoming = incoming,
5268 .instructions = .{},
5300 .instructions = .empty,
52695301 });
52705302 return index;
52715303 }
......@@ -6132,8 +6164,8 @@ pub const WipFunction = struct {
61326164 kind: MemoryAccessKind,
61336165 @"inline": bool,
61346166 ) Allocator.Error!Instruction.Index {
6135 var dst_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = dst_align })};
6136 var src_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = src_align })};
6167 var dst_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = .wrap(dst_align) })};
6168 var src_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = .wrap(src_align) })};
61376169 const value = try self.callIntrinsic(
61386170 .normal,
61396171 try self.builder.fnAttrs(&.{
......@@ -6162,8 +6194,8 @@ pub const WipFunction = struct {
61626194 len: Value,
61636195 kind: MemoryAccessKind,
61646196 ) Allocator.Error!Instruction.Index {
6165 var dst_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = dst_align })};
6166 var src_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = src_align })};
6197 var dst_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = .wrap(dst_align) })};
6198 var src_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = .wrap(src_align) })};
61676199 const value = try self.callIntrinsic(
61686200 .normal,
61696201 try self.builder.fnAttrs(&.{
......@@ -6192,7 +6224,7 @@ pub const WipFunction = struct {
61926224 kind: MemoryAccessKind,
61936225 @"inline": bool,
61946226 ) Allocator.Error!Instruction.Index {
6195 var dst_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = dst_align })};
6227 var dst_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = .wrap(dst_align) })};
61966228 const value = try self.callIntrinsic(
61976229 .normal,
61986230 try self.builder.fnAttrs(&.{ .none, .none, try self.builder.attrs(&dst_attrs) }),
......@@ -6325,7 +6357,7 @@ pub const WipFunction = struct {
63256357 function.blocks = &.{};
63266358 gpa.free(function.names[0..function.instructions.len]);
63276359 function.debug_locations.deinit(gpa);
6328 function.debug_locations = .{};
6360 function.debug_locations = .empty;
63296361 gpa.free(function.debug_values);
63306362 function.debug_values = &.{};
63316363 gpa.free(function.extra);
......@@ -7329,7 +7361,7 @@ pub const Constant = enum(u32) {
73297361 //indices: [info.indices_len]Constant,
73307362
73317363 pub const Kind = enum { normal, inbounds };
7332 pub const InRangeIndex = enum(u16) { none = std.math.maxInt(u16), _ };
7364 pub const InRangeIndex = enum(u16) { none = maxInt(u16), _ };
73337365 pub const Info = packed struct(u32) { indices_len: u16, inrange: InRangeIndex };
73347366 };
73357367
......@@ -7579,7 +7611,7 @@ pub const Constant = enum(u32) {
75797611 string: [
75807612 (std.math.big.int.Const{
75817613 .limbs = &([1]std.math.big.Limb{
7582 std.math.maxInt(std.math.big.Limb),
7614 maxInt(std.math.big.Limb),
75837615 } ** expected_limbs),
75847616 .positive = false,
75857617 }).sizeInBaseUpperBound(10)
......@@ -7643,7 +7675,7 @@ pub const Constant = enum(u32) {
76437675 std.math.minInt(Exponent64),
76447676 else => @as(Exponent64, repr.exponent) +
76457677 (std.math.floatExponentMax(f64) - std.math.floatExponentMax(f32)),
7646 std.math.maxInt(Exponent32) => std.math.maxInt(Exponent64),
7678 maxInt(Exponent32) => maxInt(Exponent64),
76477679 },
76487680 .sign = repr.sign,
76497681 }))});
......@@ -7820,7 +7852,7 @@ pub const Constant = enum(u32) {
78207852};
78217853
78227854pub const Value = enum(u32) {
7823 none = std.math.maxInt(u31),
7855 none = maxInt(u31),
78247856 false = first_constant + @intFromEnum(Constant.false),
78257857 true = first_constant + @intFromEnum(Constant.true),
78267858 @"0" = first_constant + @intFromEnum(Constant.@"0"),
......@@ -8021,6 +8053,7 @@ pub const Metadata = packed struct(u32) {
80218053 composite_vector_type,
80228054 derived_pointer_type,
80238055 derived_member_type,
8056 derived_typedef_type,
80248057 subroutine_type,
80258058 enumerator_unsigned,
80268059 enumerator_signed_positive,
......@@ -8064,6 +8097,7 @@ pub const Metadata = packed struct(u32) {
80648097 .composite_vector_type,
80658098 .derived_pointer_type,
80668099 .derived_member_type,
8100 .derived_typedef_type,
80678101 .subroutine_type,
80688102 .enumerator_unsigned,
80698103 .enumerator_signed_positive,
......@@ -8391,7 +8425,7 @@ pub const Metadata = packed struct(u32) {
83918425 map: std.AutoArrayHashMapUnmanaged(union(enum) {
83928426 metadata: Metadata,
83938427 debug_location: DebugLocation.Location,
8394 }, void) = .{},
8428 }, void) = .empty,
83958429
83968430 const FormatData = struct {
83978431 formatter: *Formatter,
......@@ -8649,52 +8683,54 @@ pub fn init(options: Options) Allocator.Error!Builder {
86498683 .source_filename = .none,
86508684 .data_layout = .none,
86518685 .target_triple = .none,
8652 .module_asm = .{},
8686 .module_asm = .empty,
86538687
8654 .string_map = .{},
8655 .string_indices = .{},
8656 .string_bytes = .{},
8688 .string_map = .empty,
8689 .string_indices = .empty,
8690 .string_bytes = .empty,
86578691
8658 .types = .{},
8692 .types = .empty,
86598693 .next_unnamed_type = @enumFromInt(0),
8660 .next_unique_type_id = .{},
8661 .type_map = .{},
8662 .type_items = .{},
8663 .type_extra = .{},
8694 .next_unique_type_id = .empty,
8695 .type_map = .empty,
8696 .type_items = .empty,
8697 .type_extra = .empty,
86648698
8665 .attributes = .{},
8666 .attributes_map = .{},
8667 .attributes_indices = .{},
8668 .attributes_extra = .{},
8699 .attributes = .empty,
8700 .attributes_map = .empty,
8701 .attributes_indices = .empty,
8702 .attributes_extra = .empty,
86698703
8670 .function_attributes_set = .{},
8704 .function_attributes_set = .empty,
86718705
8672 .globals = .{},
8706 .globals = .empty,
86738707 .next_unnamed_global = @enumFromInt(0),
86748708 .next_replaced_global = .none,
8675 .next_unique_global_id = .{},
8676 .aliases = .{},
8677 .variables = .{},
8678 .functions = .{},
8679
8680 .strtab_string_map = .{},
8681 .strtab_string_indices = .{},
8682 .strtab_string_bytes = .{},
8683
8684 .constant_map = .{},
8685 .constant_items = .{},
8686 .constant_extra = .{},
8687 .constant_limbs = .{},
8688
8689 .metadata_map = .{},
8690 .metadata_items = .{},
8691 .metadata_extra = .{},
8692 .metadata_limbs = .{},
8693 .metadata_forward_references = .{},
8694 .metadata_named = .{},
8695 .metadata_string_map = .{},
8696 .metadata_string_indices = .{},
8697 .metadata_string_bytes = .{},
8709 .next_unique_global_id = .empty,
8710 .aliases = .empty,
8711 .variables = .empty,
8712 .functions = .empty,
8713
8714 .strtab_string_map = .empty,
8715 .strtab_string_indices = .empty,
8716 .strtab_string_bytes = .empty,
8717
8718 .constant_map = .empty,
8719 .constant_items = .empty,
8720 .constant_extra = .empty,
8721 .constant_limbs = .empty,
8722
8723 .alignment_forward_references = .empty,
8724
8725 .metadata_map = .empty,
8726 .metadata_items = .empty,
8727 .metadata_extra = .empty,
8728 .metadata_limbs = .empty,
8729 .metadata_forward_references = .empty,
8730 .metadata_named = .empty,
8731 .metadata_string_map = .empty,
8732 .metadata_string_indices = .empty,
8733 .metadata_string_bytes = .empty,
86988734 };
86998735 errdefer self.deinit();
87008736
......@@ -8798,51 +8834,55 @@ pub fn clearAndFree(self: *Builder) void {
87988834}
87998835
88008836pub fn deinit(self: *Builder) void {
8801 self.module_asm.deinit(self.gpa);
8837 const gpa = self.gpa;
88028838
8803 self.string_map.deinit(self.gpa);
8804 self.string_indices.deinit(self.gpa);
8805 self.string_bytes.deinit(self.gpa);
8839 self.module_asm.deinit(gpa);
88068840
8807 self.types.deinit(self.gpa);
8808 self.next_unique_type_id.deinit(self.gpa);
8809 self.type_map.deinit(self.gpa);
8810 self.type_items.deinit(self.gpa);
8811 self.type_extra.deinit(self.gpa);
8841 self.string_map.deinit(gpa);
8842 self.string_indices.deinit(gpa);
8843 self.string_bytes.deinit(gpa);
88128844
8813 self.attributes.deinit(self.gpa);
8814 self.attributes_map.deinit(self.gpa);
8815 self.attributes_indices.deinit(self.gpa);
8816 self.attributes_extra.deinit(self.gpa);
8845 self.types.deinit(gpa);
8846 self.next_unique_type_id.deinit(gpa);
8847 self.type_map.deinit(gpa);
8848 self.type_items.deinit(gpa);
8849 self.type_extra.deinit(gpa);
88178850
8818 self.function_attributes_set.deinit(self.gpa);
8851 self.attributes.deinit(gpa);
8852 self.attributes_map.deinit(gpa);
8853 self.attributes_indices.deinit(gpa);
8854 self.attributes_extra.deinit(gpa);
88198855
8820 self.globals.deinit(self.gpa);
8821 self.next_unique_global_id.deinit(self.gpa);
8822 self.aliases.deinit(self.gpa);
8823 self.variables.deinit(self.gpa);
8824 for (self.functions.items) |*function| function.deinit(self.gpa);
8825 self.functions.deinit(self.gpa);
8856 self.function_attributes_set.deinit(gpa);
8857
8858 self.globals.deinit(gpa);
8859 self.next_unique_global_id.deinit(gpa);
8860 self.aliases.deinit(gpa);
8861 self.variables.deinit(gpa);
8862 for (self.functions.items) |*function| function.deinit(gpa);
8863 self.functions.deinit(gpa);
8864
8865 self.strtab_string_map.deinit(gpa);
8866 self.strtab_string_indices.deinit(gpa);
8867 self.strtab_string_bytes.deinit(gpa);
88268868
8827 self.strtab_string_map.deinit(self.gpa);
8828 self.strtab_string_indices.deinit(self.gpa);
8829 self.strtab_string_bytes.deinit(self.gpa);
8869 self.constant_map.deinit(gpa);
8870 self.constant_items.deinit(gpa);
8871 self.constant_extra.deinit(gpa);
8872 self.constant_limbs.deinit(gpa);
88308873
8831 self.constant_map.deinit(self.gpa);
8832 self.constant_items.deinit(self.gpa);
8833 self.constant_extra.deinit(self.gpa);
8834 self.constant_limbs.deinit(self.gpa);
8874 self.alignment_forward_references.deinit(gpa);
88358875
8836 self.metadata_map.deinit(self.gpa);
8837 self.metadata_items.deinit(self.gpa);
8838 self.metadata_extra.deinit(self.gpa);
8839 self.metadata_limbs.deinit(self.gpa);
8840 self.metadata_forward_references.deinit(self.gpa);
8841 self.metadata_named.deinit(self.gpa);
8876 self.metadata_map.deinit(gpa);
8877 self.metadata_items.deinit(gpa);
8878 self.metadata_extra.deinit(gpa);
8879 self.metadata_limbs.deinit(gpa);
8880 self.metadata_forward_references.deinit(gpa);
8881 self.metadata_named.deinit(gpa);
88428882
8843 self.metadata_string_map.deinit(self.gpa);
8844 self.metadata_string_indices.deinit(self.gpa);
8845 self.metadata_string_bytes.deinit(self.gpa);
8883 self.metadata_string_map.deinit(gpa);
8884 self.metadata_string_indices.deinit(gpa);
8885 self.metadata_string_bytes.deinit(gpa);
88468886
88478887 self.* = undefined;
88488888}
......@@ -8960,7 +9000,7 @@ pub fn structType(
89609000pub fn opaqueType(self: *Builder, name: String) Allocator.Error!Type {
89619001 try self.string_map.ensureUnusedCapacity(self.gpa, 1);
89629002 if (name.slice(self)) |id| {
8963 const count: usize = comptime std.fmt.count("{d}", .{std.math.maxInt(u32)});
9003 const count: usize = comptime std.fmt.count("{d}", .{maxInt(u32)});
89649004 try self.string_bytes.ensureUnusedCapacity(self.gpa, id.len + count);
89659005 }
89669006 try self.string_indices.ensureUnusedCapacity(self.gpa, 1);
......@@ -9576,6 +9616,21 @@ pub fn asmValue(
95769616 return (try self.asmConst(ty, info, assembly, constraints)).toValue();
95779617}
95789618
9619/// The initial "resolved" value of the forward reference is `Alignment.default`.
9620pub fn alignmentForwardReference(b: *Builder) Allocator.Error!Alignment.Lazy {
9621 const index = b.alignment_forward_references.items.len;
9622 try b.alignment_forward_references.append(b.gpa, .default);
9623 return .fromFwdRefIndex(index);
9624}
9625
9626/// Updates the "resolved" value of the alignment forward reference `fwd_ref` to `value`.
9627///
9628/// Asserts that `fwd_ref` is a forward reference, as opposed to a resolved alignment value.
9629pub fn resolveAlignmentForwardReference(b: *Builder, fwd_ref: Alignment.Lazy, value: Alignment) void {
9630 const index = fwd_ref.toFwdRefIndex();
9631 b.alignment_forward_references.items[index] = value;
9632}
9633
95799634pub fn dump(b: *Builder, io: Io) void {
95809635 var buffer: [4000]u8 = undefined;
95819636 const stderr: Io.File = .stderr();
......@@ -10463,15 +10518,18 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
1046310518 },
1046410519 .derived_pointer_type,
1046510520 .derived_member_type,
10521 .derived_typedef_type,
1046610522 => |kind| {
1046710523 const extra = self.metadataExtraData(Metadata.DerivedType, metadata_item.data);
1046810524 try metadata_formatter.specialized(.@"!", .DIDerivedType, .{
1046910525 .tag = @as(enum {
1047010526 DW_TAG_pointer_type,
1047110527 DW_TAG_member,
10528 DW_TAG_typedef,
1047210529 }, switch (kind) {
1047310530 .derived_pointer_type => .DW_TAG_pointer_type,
1047410531 .derived_member_type => .DW_TAG_member,
10532 .derived_typedef_type => .DW_TAG_typedef,
1047510533 else => unreachable,
1047610534 }),
1047710535 .name = extra.name,
......@@ -10510,7 +10568,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
1051010568 string: [
1051110569 (std.math.big.int.Const{
1051210570 .limbs = &([1]std.math.big.Limb{
10513 std.math.maxInt(std.math.big.Limb),
10571 maxInt(std.math.big.Limb),
1051410572 } ** expected_limbs),
1051510573 .positive = false,
1051610574 }).sizeInBaseUpperBound(10)
......@@ -10660,7 +10718,7 @@ fn printEscapedString(slice: []const u8, quotes: QuoteBehavior, w: *Writer) Writ
1066010718fn ensureUnusedGlobalCapacity(self: *Builder, name: StrtabString) Allocator.Error!void {
1066110719 try self.strtab_string_map.ensureUnusedCapacity(self.gpa, 1);
1066210720 if (name.slice(self)) |id| {
10663 const count: usize = comptime std.fmt.count("{d}", .{std.math.maxInt(u32)});
10721 const count: usize = comptime std.fmt.count("{d}", .{maxInt(u32)});
1066410722 try self.strtab_string_bytes.ensureUnusedCapacity(self.gpa, id.len + count);
1066510723 }
1066610724 try self.strtab_string_indices.ensureUnusedCapacity(self.gpa, 1);
......@@ -12069,7 +12127,7 @@ pub fn trailingMetadataStringAssumeCapacity(self: *Builder) Metadata.String {
1206912127 const start = self.metadata_string_indices.getLast();
1207012128 const bytes: []const u8 = self.metadata_string_bytes.items[start..];
1207112129 assert(bytes.len > 0);
12072 const gop = self.metadata_string_map.getOrPutAssumeCapacityAdapted(bytes, String.Adapter{ .builder = self });
12130 const gop = self.metadata_string_map.getOrPutAssumeCapacityAdapted(bytes, Metadata.String.Adapter{ .builder = self });
1207312131 if (gop.found_existing) {
1207412132 self.metadata_string_bytes.shrinkRetainingCapacity(start);
1207512133 } else {
......@@ -12360,6 +12418,30 @@ pub fn debugMemberType(
1236012418 );
1236112419}
1236212420
12421pub fn debugTypedefType(
12422 self: *Builder,
12423 name: ?Metadata.String,
12424 file: ?Metadata,
12425 scope: ?Metadata,
12426 line: u32,
12427 underlying_type: ?Metadata,
12428 size_in_bits: u64,
12429 align_in_bits: u64,
12430 offset_in_bits: u64,
12431) Allocator.Error!Metadata {
12432 try self.ensureUnusedMetadataCapacity(1, Metadata.DerivedType, 0);
12433 return self.debugTypedefTypeAssumeCapacity(
12434 name,
12435 file,
12436 scope,
12437 line,
12438 underlying_type,
12439 size_in_bits,
12440 align_in_bits,
12441 offset_in_bits,
12442 );
12443}
12444
1236312445pub fn debugSubroutineType(self: *Builder, types_tuple: ?Metadata) Allocator.Error!Metadata {
1236412446 try self.ensureUnusedMetadataCapacity(1, Metadata.SubroutineType, 0);
1236512447 return self.debugSubroutineTypeAssumeCapacity(types_tuple);
......@@ -12467,11 +12549,12 @@ pub fn metadataConstant(self: *Builder, value: Constant) Allocator.Error!Metadat
1246712549 return self.metadataConstantAssumeCapacity(value);
1246812550}
1246912551
12552/// Resolves the given forward reference to the given value (which is not itself a forward
12553/// reference). If the forward reference is already resolved, its target is replaced.
1247012554pub fn resolveDebugForwardReference(self: *Builder, fwd_ref: Metadata, value: Metadata) void {
1247112555 assert(fwd_ref.kind == .forward);
12472 const resolved = &self.metadata_forward_references.items[fwd_ref.index];
12473 assert(resolved.is_none);
12474 resolved.* = value.toOptional();
12556 assert(value.kind != .forward);
12557 self.metadata_forward_references.items[fwd_ref.index] = value.toOptional();
1247512558}
1247612559
1247712560fn metadataSimpleAssumeCapacity(self: *Builder, tag: Metadata.Tag, value: anytype) Metadata {
......@@ -12874,6 +12957,33 @@ fn debugMemberTypeAssumeCapacity(
1287412957 });
1287512958}
1287612959
12960fn debugTypedefTypeAssumeCapacity(
12961 self: *Builder,
12962 name: ?Metadata.String,
12963 file: ?Metadata,
12964 scope: ?Metadata,
12965 line: u32,
12966 underlying_type: ?Metadata,
12967 size_in_bits: u64,
12968 align_in_bits: u64,
12969 offset_in_bits: u64,
12970) Metadata {
12971 assert(!self.strip);
12972 return self.metadataSimpleAssumeCapacity(.derived_typedef_type, Metadata.DerivedType{
12973 .name = .wrap(name),
12974 .file = .wrap(file),
12975 .scope = .wrap(scope),
12976 .line = line,
12977 .underlying_type = .wrap(underlying_type),
12978 .size_in_bits_lo = @truncate(size_in_bits),
12979 .size_in_bits_hi = @truncate(size_in_bits >> 32),
12980 .align_in_bits_lo = @truncate(align_in_bits),
12981 .align_in_bits_hi = @truncate(align_in_bits >> 32),
12982 .offset_in_bits_lo = @truncate(offset_in_bits),
12983 .offset_in_bits_hi = @truncate(offset_in_bits >> 32),
12984 });
12985}
12986
1287712987fn debugSubroutineTypeAssumeCapacity(self: *Builder, types_tuple: ?Metadata) Metadata {
1287812988 assert(!self.strip);
1287912989 return self.metadataSimpleAssumeCapacity(.subroutine_type, Metadata.SubroutineType{
......@@ -13461,7 +13571,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
1346113571 try record.ensureUnusedCapacity(self.gpa, 3);
1346213572 record.appendAssumeCapacity(1);
1346313573 record.appendAssumeCapacity(@intFromEnum(kind));
13464 record.appendAssumeCapacity(alignment.toByteUnits() orelse 0);
13574 record.appendAssumeCapacity(alignment.resolve(self).toByteUnits() orelse 0);
1346513575 },
1346613576 .dereferenceable,
1346713577 .dereferenceable_or_null,
......@@ -14222,12 +14332,14 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco
1422214332 },
1422314333 .derived_pointer_type,
1422414334 .derived_member_type,
14335 .derived_typedef_type,
1422514336 => |kind| {
1422614337 const extra = self.metadataExtraData(Metadata.DerivedType, data);
1422714338 try metadata_block.writeAbbrevAdapted(MetadataBlock.DerivedType{
1422814339 .tag = switch (kind) {
1422914340 .derived_pointer_type => DW.TAG.pointer_type,
1423014341 .derived_member_type => DW.TAG.member,
14342 .derived_typedef_type => DW.TAG.typedef,
1423114343 else => unreachable,
1423214344 },
1423314345 .name = extra.name,
lib/std/zig/target.zig+9-8
......@@ -503,8 +503,7 @@ pub fn intByteSize(target: *const std.Target, bits: u16) u16 {
503503pub fn intAlignment(target: *const std.Target, bits: u16) u16 {
504504 return switch (target.cpu.arch) {
505505 .x86 => switch (bits) {
506 0 => 0,
507 1...8 => 1,
506 0...8 => 1,
508507 9...16 => 2,
509508 17...32 => 4,
510509 33...64 => switch (target.os.tag) {
......@@ -514,17 +513,19 @@ pub fn intAlignment(target: *const std.Target, bits: u16) u16 {
514513 else => 16,
515514 },
516515 .x86_64 => switch (bits) {
517 0 => 0,
518 1...8 => 1,
516 0...8 => 1,
519517 9...16 => 2,
520518 17...32 => 4,
521519 33...64 => 8,
522520 else => 16,
523521 },
524 else => return @min(
525 std.math.ceilPowerOfTwoPromote(u16, @as(u16, @intCast((@as(u17, bits) + 7) / 8))),
526 target.cMaxIntAlignment(),
527 ),
522 else => switch (bits) {
523 0 => 1,
524 else => @min(
525 std.math.ceilPowerOfTwoPromote(u16, @intCast((@as(u17, bits) + 7) / 8)),
526 target.cMaxIntAlignment(),
527 ),
528 },
528529 };
529530}
530531
lib/std/zon/Serializer.zig+3-1
......@@ -793,9 +793,11 @@ test checkValueDepth {
793793 try expectValueDepthEquals(2, @as(?u32, 1));
794794 try expectValueDepthEquals(1, @as(?u32, null));
795795 try expectValueDepthEquals(1, null);
796 try expectValueDepthEquals(2, &1);
797796 try expectValueDepthEquals(3, &@as(?u32, 1));
798797
798 // The pointer drops the implicit comptime-ness, so we need to specify 'comptime' here
799 try comptime expectValueDepthEquals(2, &1);
800
799801 const Union = union(enum) {
800802 x: u32,
801803 y: struct { x: u32 },
lib/std/zon/parse.zig+3-3
......@@ -591,7 +591,7 @@ const Parser = struct {
591591 if (pointer.child == u8 and
592592 pointer.is_const and
593593 (pointer.sentinel() == null or pointer.sentinel() == 0) and
594 pointer.alignment == 1)
594 (pointer.alignment == null or pointer.alignment == 1))
595595 {
596596 if (opt) {
597597 return self.failNode(node, "expected optional string");
......@@ -717,7 +717,7 @@ const Parser = struct {
717717 pointer.size != .slice or
718718 !pointer.is_const or
719719 (pointer.sentinel() != null and pointer.sentinel() != 0) or
720 pointer.alignment != 1)
720 (pointer.alignment != null and pointer.alignment != 1))
721721 {
722722 return error.WrongType;
723723 }
......@@ -742,7 +742,7 @@ const Parser = struct {
742742 const slice = try self.gpa.allocWithOptions(
743743 pointer.child,
744744 nodes.len,
745 .fromByteUnits(pointer.alignment),
745 .fromByteUnitsOptional(pointer.alignment),
746746 pointer.sentinel(),
747747 );
748748 errdefer self.gpa.free(slice);
lib/zig.h+9-1
......@@ -151,6 +151,14 @@
151151#define zig_has_attribute(attribute) 0
152152#endif
153153
154#if __STDC_VERSION__ >= 201112L
155#define zig_static_assert(cond, msg) _Static_assert(cond, msg)
156#elif zig_has_attribute(unused)
157#define zig_static_assert(cond, _) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[!!(cond)] __attribute__((unused))
158#else
159#define zig_static_assert(cond, _) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[!!(cond)]
160#endif
161
154162#if __STDC_VERSION__ >= 202311L
155163#define zig_threadlocal thread_local
156164#elif __STDC_VERSION__ >= 201112L
......@@ -259,7 +267,7 @@
259267#endif
260268
261269#if zig_has_attribute(packed) || defined(zig_tinyc)
262#define zig_packed(definition) __attribute__((packed)) definition
270#define zig_packed(definition) definition __attribute__((packed))
263271#elif defined(zig_msvc)
264272#define zig_packed(definition) __pragma(pack(1)) definition __pragma(pack())
265273#else
src/Air.zig+5-8
......@@ -14,7 +14,6 @@ const Type = @import("Type.zig");
1414const Value = @import("Value.zig");
1515const Zcu = @import("Zcu.zig");
1616const print = @import("Air/print.zig");
17const types_resolved = @import("Air/types_resolved.zig");
1817
1918pub const Legalize = @import("Air/Legalize.zig");
2019pub const Liveness = @import("Air/Liveness.zig");
......@@ -173,8 +172,8 @@ pub const Inst = struct {
173172 /// outside the provenance of the operand, the result is undefined.
174173 ///
175174 /// Uses the `ty_pl` field. Payload is `Bin`. The lhs is the pointer,
176 /// rhs is the offset. Result type is the same as lhs. The operand may
177 /// be a slice.
175 /// rhs is the offset. Result type is the same as lhs. The operand type's
176 /// pointer size may be `.slice`, `.many`, or `.c`.
178177 ptr_add,
179178 /// Subtract an offset, in element type units, from a pointer,
180179 /// returning a new pointer. Element type may not be zero bits.
......@@ -183,8 +182,8 @@ pub const Inst = struct {
183182 /// outside the provenance of the operand, the result is undefined.
184183 ///
185184 /// Uses the `ty_pl` field. Payload is `Bin`. The lhs is the pointer,
186 /// rhs is the offset. Result type is the same as lhs. The operand may
187 /// be a slice.
185 /// rhs is the offset. Result type is the same as lhs. The operand type's
186 /// pointer size may be `.slice`, `.many`, or `.c`.
188187 ptr_sub,
189188 /// Given two operands which can be floats, integers, or vectors, returns the
190189 /// greater of the operands. For vectors it operates element-wise.
......@@ -693,6 +692,7 @@ pub const Inst = struct {
693692 /// Uses the `ty_pl` field with payload `Bin`.
694693 slice_elem_ptr,
695694 /// Given a pointer value, and element index, return the element value at that index.
695 /// The pointer size is either `.c` or `.many`.
696696 /// Result type is the element type of the pointer operand.
697697 /// Uses the `bin_op` field.
698698 ptr_elem_val,
......@@ -2440,9 +2440,6 @@ pub fn unwrapShuffleTwo(air: *const Air, zcu: *const Zcu, inst_index: Inst.Index
24402440 };
24412441}
24422442
2443pub const typesFullyResolved = types_resolved.typesFullyResolved;
2444pub const typeFullyResolved = types_resolved.checkType;
2445pub const valFullyResolved = types_resolved.checkVal;
24462443pub const legalize = Legalize.legalize;
24472444pub const write = print.write;
24482445pub const writeInst = print.writeInst;
src/Air/Liveness.zig+5-5
......@@ -153,8 +153,8 @@ pub fn analyze(zcu: *Zcu, air: Air, intern_pool: *InternPool) Allocator.Error!Li
153153 usize,
154154 (air.instructions.len * bpi + @bitSizeOf(usize) - 1) / @bitSizeOf(usize),
155155 ),
156 .extra = .{},
157 .special = .{},
156 .extra = .empty,
157 .special = .empty,
158158 .intern_pool = intern_pool,
159159 };
160160 errdefer gpa.free(a.tomb_bits);
......@@ -175,7 +175,7 @@ pub fn analyze(zcu: *Zcu, air: Air, intern_pool: *InternPool) Allocator.Error!Li
175175 var data: LivenessPassData(.main_analysis) = .{};
176176 defer data.deinit(gpa);
177177 data.old_extra = a.extra;
178 a.extra = .{};
178 a.extra = .empty;
179179 try analyzeBody(&a, .main_analysis, &data, main_body);
180180 assert(data.live_set.count() == 0);
181181 }
......@@ -999,7 +999,7 @@ fn analyzeInstBlock(
999999
10001000 // If the block is noreturn, block deaths not only aren't useful, they're impossible to
10011001 // find: there could be more stuff alive after the block than before it!
1002 if (!a.intern_pool.isNoReturn(ty.toIntern())) {
1002 if (!ty.isNoReturn(a.zcu)) {
10031003 // The block kills the difference in the live sets
10041004 const block_scope = data.block_scopes.get(inst).?;
10051005 const num_deaths = data.live_set.count() - block_scope.live_set.count();
......@@ -1360,7 +1360,7 @@ fn analyzeInstSwitchBr(
13601360 const mirrored_deaths = try gpa.alloc(DeathList, ncases + 1);
13611361 defer gpa.free(mirrored_deaths);
13621362
1363 @memset(mirrored_deaths, .{});
1363 @memset(mirrored_deaths, .empty);
13641364 defer for (mirrored_deaths) |*md| md.deinit(gpa);
13651365
13661366 {
src/Air/Liveness/Verify.zig+1-1
......@@ -465,7 +465,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
465465
466466 for (block_liveness.deaths) |death| try self.verifyDeath(inst, death);
467467
468 if (ip.isNoReturn(block_ty.toIntern())) {
468 if (block_ty.isNoReturn(self.zcu)) {
469469 assert(!self.blocks.contains(inst));
470470 } else {
471471 var live = if (self.blocks.fetchRemove(inst)) |kv| kv.value else {
src/Air/print.zig+17-27
......@@ -692,33 +692,23 @@ const Writer = struct {
692692
693693 const zcu = w.pt.zcu;
694694 const ip = &zcu.intern_pool;
695 const aggregate = ip.indexToKey(unwrapped_asm.clobbers).aggregate;
696 const struct_type: Type = .fromInterned(aggregate.ty);
697 switch (aggregate.storage) {
698 .elems => |elems| for (elems, 0..) |elem, i| {
699 switch (elem) {
700 .bool_true => {
701 const clobber = struct_type.structFieldName(i, zcu).toSlice(ip).?;
702 assert(clobber.len != 0);
703 try s.writeAll(", ~{");
704 try s.writeAll(clobber);
705 try s.writeAll("}");
706 },
707 .bool_false => continue,
708 else => unreachable,
709 }
710 },
711 .repeated_elem => |elem| {
712 try s.writeAll(", ");
713 try s.writeAll(switch (elem) {
714 .bool_true => "<all clobbers>",
715 .bool_false => "<no clobbers>",
716 else => unreachable,
717 });
718 },
719 .bytes => |bytes| {
720 try s.print(", {x}", .{bytes});
721 },
695 const clobbers_val: Value = .fromInterned(unwrapped_asm.clobbers);
696 const clobbers_ty = clobbers_val.typeOf(zcu);
697 var clobbers_bigint_buf: Value.BigIntSpace = undefined;
698 const clobbers_bigint = clobbers_val.toBigInt(&clobbers_bigint_buf, zcu);
699 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
700 assert(clobbers_ty.fieldType(field_index, zcu).toIntern() == .bool_type);
701 const limb_bits = @bitSizeOf(std.math.big.Limb);
702 if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
703 switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
704 0 => continue, // field is false
705 1 => {}, // field is true
706 }
707 const clobber = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;
708 assert(clobber.len != 0);
709 try s.writeAll(", ~{");
710 try s.writeAll(clobber);
711 try s.writeAll("}");
722712 }
723713 const asm_source = unwrapped_asm.source;
724714 try s.print(", \"{f}\"", .{std.zig.fmtString(asm_source)});
src/Air/types_resolved.zig deleted-536
......@@ -1,536 +0,0 @@
1const Air = @import("../Air.zig");
2const Zcu = @import("../Zcu.zig");
3const Type = @import("../Type.zig");
4const Value = @import("../Value.zig");
5const InternPool = @import("../InternPool.zig");
6
7/// Given a body of AIR instructions, returns whether all type resolution necessary for codegen is complete.
8/// If `false`, then type resolution must have failed, so codegen cannot proceed.
9pub fn typesFullyResolved(air: Air, zcu: *Zcu) bool {
10 return checkBody(air, air.getMainBody(), zcu);
11}
12
13fn checkBody(air: Air, body: []const Air.Inst.Index, zcu: *Zcu) bool {
14 const tags = air.instructions.items(.tag);
15 const datas = air.instructions.items(.data);
16
17 for (body) |inst| {
18 const data = datas[@intFromEnum(inst)];
19 switch (tags[@intFromEnum(inst)]) {
20 .inferred_alloc, .inferred_alloc_comptime => unreachable,
21
22 .arg => {
23 if (!checkType(data.arg.ty.toType(), zcu)) return false;
24 },
25
26 .add,
27 .add_safe,
28 .add_optimized,
29 .add_wrap,
30 .add_sat,
31 .sub,
32 .sub_safe,
33 .sub_optimized,
34 .sub_wrap,
35 .sub_sat,
36 .mul,
37 .mul_safe,
38 .mul_optimized,
39 .mul_wrap,
40 .mul_sat,
41 .div_float,
42 .div_float_optimized,
43 .div_trunc,
44 .div_trunc_optimized,
45 .div_floor,
46 .div_floor_optimized,
47 .div_exact,
48 .div_exact_optimized,
49 .rem,
50 .rem_optimized,
51 .mod,
52 .mod_optimized,
53 .max,
54 .min,
55 .bit_and,
56 .bit_or,
57 .shr,
58 .shr_exact,
59 .shl,
60 .shl_exact,
61 .shl_sat,
62 .xor,
63 .cmp_lt,
64 .cmp_lt_optimized,
65 .cmp_lte,
66 .cmp_lte_optimized,
67 .cmp_eq,
68 .cmp_eq_optimized,
69 .cmp_gte,
70 .cmp_gte_optimized,
71 .cmp_gt,
72 .cmp_gt_optimized,
73 .cmp_neq,
74 .cmp_neq_optimized,
75 .bool_and,
76 .bool_or,
77 .store,
78 .store_safe,
79 .set_union_tag,
80 .array_elem_val,
81 .slice_elem_val,
82 .ptr_elem_val,
83 .memset,
84 .memset_safe,
85 .memcpy,
86 .memmove,
87 .atomic_store_unordered,
88 .atomic_store_monotonic,
89 .atomic_store_release,
90 .atomic_store_seq_cst,
91 .legalize_vec_elem_val,
92 => {
93 if (!checkRef(data.bin_op.lhs, zcu)) return false;
94 if (!checkRef(data.bin_op.rhs, zcu)) return false;
95 },
96
97 .not,
98 .bitcast,
99 .clz,
100 .ctz,
101 .popcount,
102 .byte_swap,
103 .bit_reverse,
104 .abs,
105 .load,
106 .fptrunc,
107 .fpext,
108 .intcast,
109 .intcast_safe,
110 .trunc,
111 .optional_payload,
112 .optional_payload_ptr,
113 .optional_payload_ptr_set,
114 .wrap_optional,
115 .unwrap_errunion_payload,
116 .unwrap_errunion_err,
117 .unwrap_errunion_payload_ptr,
118 .unwrap_errunion_err_ptr,
119 .errunion_payload_ptr_set,
120 .wrap_errunion_payload,
121 .wrap_errunion_err,
122 .struct_field_ptr_index_0,
123 .struct_field_ptr_index_1,
124 .struct_field_ptr_index_2,
125 .struct_field_ptr_index_3,
126 .get_union_tag,
127 .slice_len,
128 .slice_ptr,
129 .ptr_slice_len_ptr,
130 .ptr_slice_ptr_ptr,
131 .array_to_slice,
132 .int_from_float,
133 .int_from_float_optimized,
134 .int_from_float_safe,
135 .int_from_float_optimized_safe,
136 .float_from_int,
137 .splat,
138 .error_set_has_value,
139 .addrspace_cast,
140 .c_va_arg,
141 .c_va_copy,
142 => {
143 if (!checkType(data.ty_op.ty.toType(), zcu)) return false;
144 if (!checkRef(data.ty_op.operand, zcu)) return false;
145 },
146
147 .alloc,
148 .ret_ptr,
149 .c_va_start,
150 => {
151 if (!checkType(data.ty, zcu)) return false;
152 },
153
154 .ptr_add,
155 .ptr_sub,
156 .add_with_overflow,
157 .sub_with_overflow,
158 .mul_with_overflow,
159 .shl_with_overflow,
160 .slice,
161 .slice_elem_ptr,
162 .ptr_elem_ptr,
163 => {
164 const bin = air.extraData(Air.Bin, data.ty_pl.payload).data;
165 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
166 if (!checkRef(bin.lhs, zcu)) return false;
167 if (!checkRef(bin.rhs, zcu)) return false;
168 },
169
170 .block,
171 .loop,
172 => {
173 const block = air.unwrapBlock(inst);
174 if (!checkType(block.ty, zcu)) return false;
175 if (!checkBody(
176 air,
177 block.body,
178 zcu,
179 )) return false;
180 },
181
182 .dbg_inline_block => {
183 const block = air.unwrapDbgBlock(inst);
184 if (!checkType(block.ty, zcu)) return false;
185 if (!checkBody(
186 air,
187 block.body,
188 zcu,
189 )) return false;
190 },
191
192 .sqrt,
193 .sin,
194 .cos,
195 .tan,
196 .exp,
197 .exp2,
198 .log,
199 .log2,
200 .log10,
201 .floor,
202 .ceil,
203 .round,
204 .trunc_float,
205 .neg,
206 .neg_optimized,
207 .is_null,
208 .is_non_null,
209 .is_null_ptr,
210 .is_non_null_ptr,
211 .is_err,
212 .is_non_err,
213 .is_err_ptr,
214 .is_non_err_ptr,
215 .ret,
216 .ret_safe,
217 .ret_load,
218 .is_named_enum_value,
219 .tag_name,
220 .error_name,
221 .cmp_lt_errors_len,
222 .c_va_end,
223 .set_err_return_trace,
224 => {
225 if (!checkRef(data.un_op, zcu)) return false;
226 },
227
228 .br, .switch_dispatch => {
229 if (!checkRef(data.br.operand, zcu)) return false;
230 },
231
232 .cmp_vector,
233 .cmp_vector_optimized,
234 => {
235 const extra = air.extraData(Air.VectorCmp, data.ty_pl.payload).data;
236 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
237 if (!checkRef(extra.lhs, zcu)) return false;
238 if (!checkRef(extra.rhs, zcu)) return false;
239 },
240
241 .reduce,
242 .reduce_optimized,
243 => {
244 if (!checkRef(data.reduce.operand, zcu)) return false;
245 },
246
247 .struct_field_ptr,
248 .struct_field_val,
249 => {
250 const extra = air.extraData(Air.StructField, data.ty_pl.payload).data;
251 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
252 if (!checkRef(extra.struct_operand, zcu)) return false;
253 },
254
255 .shuffle_one => {
256 const unwrapped = air.unwrapShuffleOne(zcu, inst);
257 if (!checkType(unwrapped.result_ty, zcu)) return false;
258 if (!checkRef(unwrapped.operand, zcu)) return false;
259 for (unwrapped.mask) |m| switch (m.unwrap()) {
260 .elem => {},
261 .value => |val| if (!checkVal(.fromInterned(val), zcu)) return false,
262 };
263 },
264
265 .shuffle_two => {
266 const unwrapped = air.unwrapShuffleTwo(zcu, inst);
267 if (!checkType(unwrapped.result_ty, zcu)) return false;
268 if (!checkRef(unwrapped.operand_a, zcu)) return false;
269 if (!checkRef(unwrapped.operand_b, zcu)) return false;
270 // No values to check because there are no comptime-known values other than undef
271 },
272
273 .cmpxchg_weak,
274 .cmpxchg_strong,
275 => {
276 const extra = air.extraData(Air.Cmpxchg, data.ty_pl.payload).data;
277 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
278 if (!checkRef(extra.ptr, zcu)) return false;
279 if (!checkRef(extra.expected_value, zcu)) return false;
280 if (!checkRef(extra.new_value, zcu)) return false;
281 },
282
283 .aggregate_init => {
284 const ty = data.ty_pl.ty.toType();
285 const elems_len: usize = @intCast(ty.arrayLen(zcu));
286 const elems: []const Air.Inst.Ref = @ptrCast(air.extra.items[data.ty_pl.payload..][0..elems_len]);
287 if (!checkType(ty, zcu)) return false;
288 if (ty.zigTypeTag(zcu) == .@"struct") {
289 for (elems, 0..) |elem, elem_idx| {
290 if (ty.structFieldIsComptime(elem_idx, zcu)) continue;
291 if (!checkRef(elem, zcu)) return false;
292 }
293 } else {
294 for (elems) |elem| {
295 if (!checkRef(elem, zcu)) return false;
296 }
297 }
298 },
299
300 .union_init => {
301 const extra = air.extraData(Air.UnionInit, data.ty_pl.payload).data;
302 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
303 if (!checkRef(extra.init, zcu)) return false;
304 },
305
306 .field_parent_ptr => {
307 const extra = air.extraData(Air.FieldParentPtr, data.ty_pl.payload).data;
308 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
309 if (!checkRef(extra.field_ptr, zcu)) return false;
310 },
311
312 .atomic_load => {
313 if (!checkRef(data.atomic_load.ptr, zcu)) return false;
314 },
315
316 .prefetch => {
317 if (!checkRef(data.prefetch.ptr, zcu)) return false;
318 },
319
320 .runtime_nav_ptr => {
321 if (!checkType(.fromInterned(data.ty_nav.ty), zcu)) return false;
322 },
323
324 .select,
325 .mul_add,
326 .legalize_vec_store_elem,
327 => {
328 const bin = air.extraData(Air.Bin, data.pl_op.payload).data;
329 if (!checkRef(data.pl_op.operand, zcu)) return false;
330 if (!checkRef(bin.lhs, zcu)) return false;
331 if (!checkRef(bin.rhs, zcu)) return false;
332 },
333
334 .atomic_rmw => {
335 const extra = air.extraData(Air.AtomicRmw, data.pl_op.payload).data;
336 if (!checkRef(data.pl_op.operand, zcu)) return false;
337 if (!checkRef(extra.operand, zcu)) return false;
338 },
339
340 .call,
341 .call_always_tail,
342 .call_never_tail,
343 .call_never_inline,
344 => {
345 const call = air.unwrapCall(inst);
346 const args = call.args;
347 if (!checkRef(call.callee, zcu)) return false;
348 for (args) |arg| if (!checkRef(arg, zcu)) return false;
349 },
350
351 .dbg_var_ptr,
352 .dbg_var_val,
353 .dbg_arg_inline,
354 => {
355 if (!checkRef(data.pl_op.operand, zcu)) return false;
356 },
357
358 .@"try", .try_cold => {
359 const unwrapped_try = air.unwrapTry(inst);
360 if (!checkRef(unwrapped_try.error_union, zcu)) return false;
361 if (!checkBody(
362 air,
363 unwrapped_try.else_body,
364 zcu,
365 )) return false;
366 },
367
368 .try_ptr, .try_ptr_cold => {
369 const unwrapped_try = air.unwrapTryPtr(inst);
370 if (!checkType(unwrapped_try.error_union_payload_ptr_ty.toType(), zcu)) return false;
371 if (!checkRef(unwrapped_try.error_union_ptr, zcu)) return false;
372 if (!checkBody(
373 air,
374 unwrapped_try.else_body,
375 zcu,
376 )) return false;
377 },
378
379 .cond_br => {
380 const cond_br = air.unwrapCondBr(inst);
381 if (!checkRef(cond_br.condition, zcu)) return false;
382 if (!checkBody(
383 air,
384 cond_br.then_body,
385 zcu,
386 )) return false;
387 if (!checkBody(
388 air,
389 cond_br.else_body,
390 zcu,
391 )) return false;
392 },
393
394 .switch_br, .loop_switch_br => {
395 const switch_br = air.unwrapSwitch(inst);
396 if (!checkRef(switch_br.operand, zcu)) return false;
397 var it = switch_br.iterateCases();
398 while (it.next()) |case| {
399 for (case.items) |item| if (!checkRef(item, zcu)) return false;
400 for (case.ranges) |range| {
401 if (!checkRef(range[0], zcu)) return false;
402 if (!checkRef(range[1], zcu)) return false;
403 }
404 if (!checkBody(air, case.body, zcu)) return false;
405 }
406 if (!checkBody(air, it.elseBody(), zcu)) return false;
407 },
408
409 .assembly => {
410 const unwrapped_asm = air.unwrapAsm(inst);
411 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
412 // Luckily, we only care about the inputs and outputs, so we don't have to do
413 // the whole null-terminated string dance.
414 const outputs = unwrapped_asm.outputs;
415 const inputs = unwrapped_asm.inputs;
416
417 for (outputs) |output| if (output != .none and !checkRef(output, zcu)) return false;
418 for (inputs) |input| if (input != .none and !checkRef(input, zcu)) return false;
419 },
420
421 .legalize_compiler_rt_call => {
422 const rt_call = air.unwrapCompilerRtCall(inst);
423 const args = rt_call.args;
424 for (args) |arg| if (!checkRef(arg, zcu)) return false;
425 },
426
427 .trap,
428 .breakpoint,
429 .ret_addr,
430 .frame_addr,
431 .unreach,
432 .wasm_memory_size,
433 .wasm_memory_grow,
434 .work_item_id,
435 .work_group_size,
436 .work_group_id,
437 .dbg_stmt,
438 .dbg_empty_stmt,
439 .err_return_trace,
440 .save_err_return_trace_index,
441 .repeat,
442 => {},
443 }
444 }
445 return true;
446}
447
448fn checkRef(ref: Air.Inst.Ref, zcu: *Zcu) bool {
449 const ip_index = ref.toInterned() orelse {
450 // This operand refers back to a previous instruction.
451 // We have already checked that instruction's type.
452 // So, there's no need to check this operand's type.
453 return true;
454 };
455 return checkVal(Value.fromInterned(ip_index), zcu);
456}
457
458pub fn checkVal(val: Value, zcu: *Zcu) bool {
459 const ty = val.typeOf(zcu);
460 if (!checkType(ty, zcu)) return false;
461 if (val.isUndef(zcu)) return true;
462 if (ty.toIntern() == .type_type and !checkType(val.toType(), zcu)) return false;
463 // Check for lazy values
464 switch (zcu.intern_pool.indexToKey(val.toIntern())) {
465 .int => |int| switch (int.storage) {
466 .u64, .i64, .big_int => return true,
467 .lazy_align, .lazy_size => |ty_index| {
468 return checkType(Type.fromInterned(ty_index), zcu);
469 },
470 },
471 else => return true,
472 }
473}
474
475pub fn checkType(ty: Type, zcu: *Zcu) bool {
476 const ip = &zcu.intern_pool;
477 if (ty.isGenericPoison()) return true;
478 return switch (ty.zigTypeTag(zcu)) {
479 .type,
480 .void,
481 .bool,
482 .noreturn,
483 .int,
484 .float,
485 .error_set,
486 .@"enum",
487 .@"opaque",
488 .vector,
489 // These types can appear due to some dummy instructions Sema introduces and expects to be omitted by Liveness.
490 // It's a little silly -- but fine, we'll return `true`.
491 .comptime_float,
492 .comptime_int,
493 .undefined,
494 .null,
495 .enum_literal,
496 => true,
497
498 .frame,
499 .@"anyframe",
500 => @panic("TODO Air.types_resolved.checkType async frames"),
501
502 .optional => checkType(ty.childType(zcu), zcu),
503 .error_union => checkType(ty.errorUnionPayload(zcu), zcu),
504 .pointer => checkType(ty.childType(zcu), zcu),
505 .array => checkType(ty.childType(zcu), zcu),
506
507 .@"fn" => {
508 const info = zcu.typeToFunc(ty).?;
509 for (0..info.param_types.len) |i| {
510 const param_ty = info.param_types.get(ip)[i];
511 if (!checkType(Type.fromInterned(param_ty), zcu)) return false;
512 }
513 return checkType(Type.fromInterned(info.return_type), zcu);
514 },
515 .@"struct" => switch (ip.indexToKey(ty.toIntern())) {
516 .struct_type => {
517 const struct_obj = zcu.typeToStruct(ty).?;
518 return switch (struct_obj.layout) {
519 .@"packed" => struct_obj.backingIntTypeUnordered(ip) != .none,
520 .auto, .@"extern" => struct_obj.flagsUnordered(ip).fully_resolved,
521 };
522 },
523 .tuple_type => |tuple| {
524 for (0..tuple.types.len) |i| {
525 const field_is_comptime = tuple.values.get(ip)[i] != .none;
526 if (field_is_comptime) continue;
527 const field_ty = tuple.types.get(ip)[i];
528 if (!checkType(Type.fromInterned(field_ty), zcu)) return false;
529 }
530 return true;
531 },
532 else => unreachable,
533 },
534 .@"union" => return zcu.typeToUnion(ty).?.flagsUnordered(ip).status == .fully_resolved,
535 };
536}
src/Compilation.zig+57-718
......@@ -21,7 +21,6 @@ const introspect = @import("introspect.zig");
2121const link = @import("link.zig");
2222const tracy = @import("tracy.zig");
2323const trace = tracy.trace;
24const traceNamed = tracy.traceNamed;
2524const build_options = @import("build_options");
2625const LibCInstallation = std.zig.LibCInstallation;
2726const glibc = @import("libs/glibc.zig");
......@@ -89,6 +88,9 @@ framework_dirs: []const []const u8,
8988/// These are only for DLLs dependencies fulfilled by the `.def` files shipped
9089/// with Zig. Static libraries are provided as `link.Input` values.
9190windows_libs: std.StringArrayHashMapUnmanaged(void),
91/// The number of items in `windows_libs` which we have already built. All items at or after this
92/// index will be built in `performAllTheWork`.
93windows_libs_num_done: u32,
9294version: ?std.SemanticVersion,
9395libc_installation: ?*const LibCInstallation,
9496skip_linker_dependencies: bool,
......@@ -126,16 +128,6 @@ oneshot_prelink_tasks: std.ArrayList(link.PrelinkTask),
126128/// work is queued or not.
127129queued_jobs: QueuedJobs,
128130
129work_queues: [
130 len: {
131 var len: usize = 0;
132 for (std.enums.values(Job.Tag)) |tag| {
133 len = @max(Job.stage(tag) + 1, len);
134 }
135 break :len len;
136 }
137]std.Deque(Job),
138
139131/// These jobs are to invoke the Clang compiler to create an object file, which
140132/// gets linked with the Compilation.
141133c_object_work_queue: std.Deque(*CObject),
......@@ -962,65 +954,6 @@ pub const RcSourceFile = struct {
962954 extra_flags: []const []const u8 = &.{},
963955};
964956
965const Job = union(enum) {
966 /// Given the generated AIR for a function, put it onto the code generation queue.
967 /// This `Job` exists (instead of the `link.ZcuTask` being directly queued) to ensure that
968 /// all types are resolved before the linker task is queued.
969 /// If the backend does not support `Zcu.Feature.separate_thread`, codegen and linking happen immediately.
970 /// Before queueing this `Job`, increase the estimated total item count for both
971 /// `comp.zcu.?.codegen_prog_node` and `comp.link_prog_node`.
972 codegen_func: struct {
973 func: InternPool.Index,
974 /// The AIR emitted from analyzing `func`; owned by this `Job` in `gpa`.
975 air: Air,
976 },
977 /// Queue a `link.ZcuTask` to emit this non-function `Nav` into the output binary.
978 /// This `Job` exists (instead of the `link.ZcuTask` being directly queued) to ensure that
979 /// all types are resolved before the linker task is queued.
980 /// If the backend does not support `Zcu.Feature.separate_thread`, the task is run immediately.
981 /// Before queueing this `Job`, increase the estimated total item count for `comp.link_prog_node`.
982 link_nav: InternPool.Nav.Index,
983 /// Queue a `link.ZcuTask` to emit debug information for this container type.
984 /// This `Job` exists (instead of the `link.ZcuTask` being directly queued) to ensure that
985 /// all types are resolved before the linker task is queued.
986 /// If the backend does not support `Zcu.Feature.separate_thread`, the task is run immediately.
987 /// Before queueing this `Job`, increase the estimated total item count for `comp.link_prog_node`.
988 link_type: InternPool.Index,
989 /// Before queueing this `Job`, increase the estimated total item count for `comp.link_prog_node`.
990 update_line_number: InternPool.TrackedInst.Index,
991 /// The `AnalUnit`, which is *not* a `func`, must be semantically analyzed.
992 /// This may be its first time being analyzed, or it may be outdated.
993 /// If the unit is a test function, an `analyze_func` job will then be queued.
994 analyze_comptime_unit: InternPool.AnalUnit,
995 /// This function must be semantically analyzed.
996 /// This may be its first time being analyzed, or it may be outdated.
997 /// After analysis, a `codegen_func` job will be queued.
998 /// These must be separate jobs to ensure any needed type resolution occurs *before* codegen.
999 /// This job is separate from `analyze_comptime_unit` because it has a different priority.
1000 analyze_func: InternPool.Index,
1001 /// The main source file for the module needs to be analyzed.
1002 analyze_mod: *Package.Module,
1003 /// Fully resolve the given `struct` or `union` type.
1004 resolve_type_fully: InternPool.Index,
1005
1006 /// The value is the index into `windows_libs`.
1007 windows_import_lib: usize,
1008
1009 const Tag = @typeInfo(Job).@"union".tag_type.?;
1010 fn stage(tag: Tag) usize {
1011 return switch (tag) {
1012 // Prioritize functions so that codegen can get to work on them on a
1013 // separate thread, while Sema goes back to its own work.
1014 .resolve_type_fully, .analyze_func, .codegen_func => 0,
1015 else => 1,
1016 };
1017 }
1018 comptime {
1019 // Job dependencies
1020 assert(stage(.resolve_type_fully) <= stage(.codegen_func));
1021 }
1022};
1023
1024957pub const CObject = struct {
1025958 /// Relative to cwd. Owned by arena.
1026959 src: CSourceFile,
......@@ -1412,7 +1345,6 @@ pub const MiscTask = enum {
14121345 wasi_libc_crt_file,
14131346 compiler_rt,
14141347 libzigc,
1415 analyze_mod,
14161348 link_depfile,
14171349 docs_copy,
14181350 docs_wasm,
......@@ -2297,7 +2229,6 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
22972229 .root_mod = options.root_mod,
22982230 .config = options.config,
22992231 .dirs = options.dirs,
2300 .work_queues = @splat(.empty),
23012232 .c_object_work_queue = .empty,
23022233 .win32_resource_work_queue = .empty,
23032234 .c_source_files = options.c_source_files,
......@@ -2331,6 +2262,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
23312262 .root_name = root_name,
23322263 .sysroot = sysroot,
23332264 .windows_libs = .empty,
2265 .windows_libs_num_done = 0,
23342266 .version = options.version,
23352267 .libc_installation = libc_dirs.libc_installation,
23362268 .compiler_rt_strat = compiler_rt_strat,
......@@ -2693,16 +2625,6 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
26932625 }
26942626 }
26952627
2696 // Generate Windows import libs.
2697 if (target.os.tag == .windows) {
2698 const count = comp.windows_libs.count();
2699 for (0..count) |i| {
2700 try comp.queueJob(.{ .windows_import_lib = i });
2701 }
2702 // when integrating coff linker with prelink, the above `queueJob` will need to move
2703 // to something in `dispatchPrelinkWork`, which must queue all prelink link tasks
2704 // *before* we begin working on the main job queue.
2705 }
27062628 if (comp.wantBuildLibUnwindFromSource()) {
27072629 comp.queued_jobs.libunwind = true;
27082630 }
......@@ -2786,7 +2708,6 @@ pub fn destroy(comp: *Compilation) void {
27862708 if (comp.zcu) |zcu| zcu.deinit();
27872709 comp.cache_use.deinit(io);
27882710
2789 for (&comp.work_queues) |*work_queue| work_queue.deinit(gpa);
27902711 comp.c_object_work_queue.deinit(gpa);
27912712 comp.win32_resource_work_queue.deinit(gpa);
27922713
......@@ -3461,9 +3382,6 @@ fn flush(comp: *Compilation, arena: Allocator, tid: Zcu.PerThread.Id) (Io.Cancel
34613382 error.OutOfMemory, error.Canceled => |e| return e,
34623383 };
34633384 }
3464 if (comp.zcu) |zcu| {
3465 try link.File.C.flushEmitH(zcu);
3466 }
34673385}
34683386
34693387/// This function is called by the frontend before flush(). It communicates that
......@@ -3728,7 +3646,9 @@ const Header = extern struct {
37283646 src_hash_deps_len: u32,
37293647 nav_val_deps_len: u32,
37303648 nav_ty_deps_len: u32,
3731 interned_deps_len: u32,
3649 type_layout_deps_len: u32,
3650 struct_defaults_deps_len: u32,
3651 func_ies_deps_len: u32,
37323652 zon_file_deps_len: u32,
37333653 embed_file_deps_len: u32,
37343654 namespace_deps_len: u32,
......@@ -3776,7 +3696,9 @@ pub fn saveState(comp: *Compilation) !void {
37763696 .src_hash_deps_len = @intCast(ip.src_hash_deps.count()),
37773697 .nav_val_deps_len = @intCast(ip.nav_val_deps.count()),
37783698 .nav_ty_deps_len = @intCast(ip.nav_ty_deps.count()),
3779 .interned_deps_len = @intCast(ip.interned_deps.count()),
3699 .type_layout_deps_len = @intCast(ip.type_layout_deps.count()),
3700 .struct_defaults_deps_len = @intCast(ip.struct_defaults_deps.count()),
3701 .func_ies_deps_len = @intCast(ip.func_ies_deps.count()),
37803702 .zon_file_deps_len = @intCast(ip.zon_file_deps.count()),
37813703 .embed_file_deps_len = @intCast(ip.embed_file_deps.count()),
37823704 .namespace_deps_len = @intCast(ip.namespace_deps.count()),
......@@ -3800,7 +3722,7 @@ pub fn saveState(comp: *Compilation) !void {
38003722 },
38013723 });
38023724
3803 try bufs.ensureTotalCapacityPrecise(22 + 9 * pt_headers.items.len);
3725 try bufs.ensureTotalCapacityPrecise(26 + 9 * pt_headers.items.len);
38043726 addBuf(&bufs, mem.asBytes(&header));
38053727 addBuf(&bufs, @ptrCast(pt_headers.items));
38063728
......@@ -3810,8 +3732,12 @@ pub fn saveState(comp: *Compilation) !void {
38103732 addBuf(&bufs, @ptrCast(ip.nav_val_deps.values()));
38113733 addBuf(&bufs, @ptrCast(ip.nav_ty_deps.keys()));
38123734 addBuf(&bufs, @ptrCast(ip.nav_ty_deps.values()));
3813 addBuf(&bufs, @ptrCast(ip.interned_deps.keys()));
3814 addBuf(&bufs, @ptrCast(ip.interned_deps.values()));
3735 addBuf(&bufs, @ptrCast(ip.type_layout_deps.keys()));
3736 addBuf(&bufs, @ptrCast(ip.type_layout_deps.values()));
3737 addBuf(&bufs, @ptrCast(ip.struct_defaults_deps.keys()));
3738 addBuf(&bufs, @ptrCast(ip.struct_defaults_deps.values()));
3739 addBuf(&bufs, @ptrCast(ip.func_ies_deps.keys()));
3740 addBuf(&bufs, @ptrCast(ip.func_ies_deps.values()));
38153741 addBuf(&bufs, @ptrCast(ip.zon_file_deps.keys()));
38163742 addBuf(&bufs, @ptrCast(ip.zon_file_deps.values()));
38173743 addBuf(&bufs, @ptrCast(ip.embed_file_deps.keys()));
......@@ -4128,21 +4054,12 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
41284054 const SortOrder = struct {
41294055 zcu: *Zcu,
41304056 errors: []const *Zcu.ErrorMsg,
4131 read_err: *?ReadError,
4132 const ReadError = struct {
4133 file: *Zcu.File,
4134 err: Zcu.File.GetSourceError,
4135 };
41364057 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {
4137 if (ctx.read_err.* != null) return lhs_index < rhs_index;
4138 var bad_file: *Zcu.File = undefined;
4139 return ctx.errors[lhs_index].src_loc.lessThan(ctx.errors[rhs_index].src_loc, ctx.zcu, &bad_file) catch |err| {
4140 ctx.read_err.* = .{
4141 .file = bad_file,
4142 .err = err,
4143 };
4144 return lhs_index < rhs_index;
4145 };
4058 return Zcu.ErrorMsg.order(
4059 ctx.errors[lhs_index],
4060 ctx.errors[rhs_index],
4061 ctx.zcu,
4062 ).compare(.lt);
41464063 }
41474064 };
41484065
......@@ -4152,16 +4069,10 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
41524069 var entries = try zcu.failed_analysis.entries.clone(gpa);
41534070 errdefer entries.deinit(gpa);
41544071
4155 var read_err: ?SortOrder.ReadError = null;
41564072 entries.sort(SortOrder{
41574073 .zcu = zcu,
41584074 .errors = entries.items(.value),
4159 .read_err = &read_err,
41604075 });
4161 if (read_err) |e| {
4162 try unableToLoadZcuFile(zcu, &bundle, e.file, e.err);
4163 break :zcu_errors;
4164 }
41654076 break :s entries.slice();
41664077 };
41674078 defer sorted_failed_analysis.deinit(gpa);
......@@ -4200,6 +4111,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
42004111 }
42014112 }
42024113 }
4114 try zcu.addDependencyLoopErrors(&bundle);
42034115 for (zcu.failed_codegen.values()) |error_msg| {
42044116 try addModuleErrorMsg(zcu, &bundle, error_msg.*, false);
42054117 }
......@@ -4219,7 +4131,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
42194131 .notes_len = 1,
42204132 });
42214133 const notes_start = try bundle.reserveNotes(1);
4222 bundle.extra.items[notes_start] = @intFromEnum(try bundle.addErrorMessage(.{
4134 bundle.extra.items[notes_start] = @intFromEnum(bundle.addErrorMessageAssumeCapacity(.{
42234135 .msg = try bundle.printString("use '--error-limit {d}' to increase limit", .{
42244136 actual_error_count,
42254137 }),
......@@ -4241,10 +4153,10 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
42414153 .notes_len = 2,
42424154 });
42434155 const notes_start = try bundle.reserveNotes(2);
4244 bundle.extra.items[notes_start + 0] = @intFromEnum(try bundle.addErrorMessage(.{
4156 bundle.extra.items[notes_start + 0] = @intFromEnum(bundle.addErrorMessageAssumeCapacity(.{
42454157 .msg = try bundle.addString("run 'zig libc -h' to learn about libc installations"),
42464158 }));
4247 bundle.extra.items[notes_start + 1] = @intFromEnum(try bundle.addErrorMessage(.{
4159 bundle.extra.items[notes_start + 1] = @intFromEnum(bundle.addErrorMessageAssumeCapacity(.{
42484160 .msg = try bundle.addString("run 'zig targets' to see the targets for which zig can always provide libc"),
42494161 }));
42504162 }
......@@ -4268,7 +4180,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
42684180 if (!refs.contains(logging_unit)) continue;
42694181 try messages.append(gpa, .{
42704182 .src_loc = compile_log.src(),
4271 .msg = undefined, // populated later
4183 .msg = "", // populated later, but must be valid for `sort` call below
42724184 .notes = &.{},
42734185 // We actually clear this later for most of these, but we populate
42744186 // this field for now to avoid having to allocate more data to track
......@@ -4281,33 +4193,11 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
42814193
42824194 // Okay, there *are* referenced compile logs. Sort them into a consistent order.
42834195
4284 {
4285 const SortContext = struct {
4286 zcu: *Zcu,
4287 read_err: *?ReadError,
4288 const ReadError = struct {
4289 file: *Zcu.File,
4290 err: Zcu.File.GetSourceError,
4291 };
4292 fn lessThan(ctx: @This(), lhs: Zcu.ErrorMsg, rhs: Zcu.ErrorMsg) bool {
4293 if (ctx.read_err.* != null) return false;
4294 var bad_file: *Zcu.File = undefined;
4295 return lhs.src_loc.lessThan(rhs.src_loc, ctx.zcu, &bad_file) catch |err| {
4296 ctx.read_err.* = .{
4297 .file = bad_file,
4298 .err = err,
4299 };
4300 return false;
4301 };
4302 }
4303 };
4304 var read_err: ?SortContext.ReadError = null;
4305 std.mem.sort(Zcu.ErrorMsg, messages.items, @as(SortContext, .{ .read_err = &read_err, .zcu = zcu }), SortContext.lessThan);
4306 if (read_err) |e| {
4307 try unableToLoadZcuFile(zcu, &bundle, e.file, e.err);
4308 break :compile_log_text "";
4196 std.mem.sort(Zcu.ErrorMsg, messages.items, zcu, struct {
4197 fn lessThan(zcu_inner: *Zcu, lhs: Zcu.ErrorMsg, rhs: Zcu.ErrorMsg) bool {
4198 return Zcu.ErrorMsg.order(&lhs, &rhs, zcu_inner).compare(.lt);
43094199 }
4310 }
4200 }.lessThan);
43114201
43124202 var log_text: std.ArrayList(u8) = .empty;
43134203 defer log_text.deinit(gpa);
......@@ -4331,6 +4221,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) error{OutOfMemory}!ErrorBundle {
43314221
43324222 break :compile_log_text try log_text.toOwnedSlice(gpa);
43334223 };
4224 defer gpa.free(compile_log_text);
43344225
43354226 // TODO: eventually, this should be behind `std.debug.runtime_safety`. But right now, this is a
43364227 // very common way for incremental compilation bugs to manifest, so let's always check it.
......@@ -4439,7 +4330,6 @@ pub fn addModuleErrorMsg(
44394330 already_added_error: bool,
44404331) Allocator.Error!void {
44414332 const gpa = eb.gpa;
4442 const ip = &zcu.intern_pool;
44434333 const err_src_loc = module_err_msg.src_loc.upgrade(zcu);
44444334 const err_source = err_src_loc.file_scope.getSource(zcu) catch |err| {
44454335 return unableToLoadZcuFile(zcu, eb, err_src_loc.file_scope, err);
......@@ -4452,66 +4342,12 @@ pub fn addModuleErrorMsg(
44524342 var ref_traces: std.ArrayList(ErrorBundle.ReferenceTrace) = .empty;
44534343 defer ref_traces.deinit(gpa);
44544344
4455 rt: {
4456 const rt_root = module_err_msg.reference_trace_root.unwrap() orelse break :rt;
4457 const max_references = zcu.comp.reference_trace orelse refs: {
4458 if (already_added_error) break :rt;
4345 if (module_err_msg.reference_trace_root.unwrap()) |root| {
4346 const frame_limit: u32 = zcu.comp.reference_trace orelse refs: {
4347 if (already_added_error) break :refs 0;
44594348 break :refs default_reference_trace_len;
44604349 };
4461
4462 const all_references = try zcu.resolveReferences();
4463
4464 var seen: std.AutoHashMapUnmanaged(InternPool.AnalUnit, void) = .empty;
4465 defer seen.deinit(gpa);
4466
4467 var referenced_by = rt_root;
4468 while (all_references.get(referenced_by)) |maybe_ref| {
4469 const ref = maybe_ref orelse break;
4470 const gop = try seen.getOrPut(gpa, ref.referencer);
4471 if (gop.found_existing) break;
4472 if (ref_traces.items.len < max_references) {
4473 var last_call_src = ref.src;
4474 var opt_inline_frame = ref.inline_frame;
4475 while (opt_inline_frame.unwrap()) |inline_frame| {
4476 const f = inline_frame.ptr(zcu).*;
4477 const func_nav = ip.indexToKey(f.callee).func.owner_nav;
4478 const func_name = ip.getNav(func_nav).name.toSlice(ip);
4479 addReferenceTraceFrame(zcu, eb, &ref_traces, func_name, last_call_src, true) catch |err| switch (err) {
4480 error.OutOfMemory => |e| return e,
4481 error.AlreadyReported => {
4482 // An incomplete reference trace isn't the end of the world; just cut it off.
4483 break :rt;
4484 },
4485 };
4486 last_call_src = f.call_src;
4487 opt_inline_frame = f.parent;
4488 }
4489 const root_name: ?[]const u8 = switch (ref.referencer.unwrap()) {
4490 .@"comptime" => "comptime",
4491 .nav_val, .nav_ty => |nav| ip.getNav(nav).name.toSlice(ip),
4492 .type => |ty| Type.fromInterned(ty).containerTypeName(ip).toSlice(ip),
4493 .func => |f| ip.getNav(zcu.funcInfo(f).owner_nav).name.toSlice(ip),
4494 .memoized_state => null,
4495 };
4496 if (root_name) |n| {
4497 addReferenceTraceFrame(zcu, eb, &ref_traces, n, last_call_src, false) catch |err| switch (err) {
4498 error.OutOfMemory => |e| return e,
4499 error.AlreadyReported => {
4500 // An incomplete reference trace isn't the end of the world; just cut it off.
4501 break :rt;
4502 },
4503 };
4504 }
4505 }
4506 referenced_by = ref.referencer;
4507 }
4508
4509 if (seen.count() > ref_traces.items.len) {
4510 try ref_traces.append(gpa, .{
4511 .decl_name = @intCast(seen.count() - ref_traces.items.len),
4512 .src_loc = .none,
4513 });
4514 }
4350 try zcu.populateReferenceTrace(root, frame_limit, eb, &ref_traces);
45154351 }
45164352
45174353 const src_loc = try eb.addSourceLocation(.{
......@@ -4576,43 +4412,10 @@ pub fn addModuleErrorMsg(
45764412 const notes_start = try eb.reserveNotes(notes_len);
45774413
45784414 for (notes_start.., notes.keys()) |i, note| {
4579 eb.extra.items[i] = @intFromEnum(try eb.addErrorMessage(note));
4415 eb.extra.items[i] = @intFromEnum(eb.addErrorMessageAssumeCapacity(note));
45804416 }
45814417}
45824418
4583fn addReferenceTraceFrame(
4584 zcu: *Zcu,
4585 eb: *ErrorBundle.Wip,
4586 ref_traces: *std.ArrayList(ErrorBundle.ReferenceTrace),
4587 name: []const u8,
4588 lazy_src: Zcu.LazySrcLoc,
4589 inlined: bool,
4590) error{ OutOfMemory, AlreadyReported }!void {
4591 const gpa = zcu.gpa;
4592 const src = lazy_src.upgrade(zcu);
4593 const source = src.file_scope.getSource(zcu) catch |err| {
4594 try unableToLoadZcuFile(zcu, eb, src.file_scope, err);
4595 return error.AlreadyReported;
4596 };
4597 const span = src.span(zcu) catch |err| {
4598 try unableToLoadZcuFile(zcu, eb, src.file_scope, err);
4599 return error.AlreadyReported;
4600 };
4601 const loc = std.zig.findLineColumn(source, span.main);
4602 try ref_traces.append(gpa, .{
4603 .decl_name = try eb.printString("{s}{s}", .{ name, if (inlined) " [inlined]" else "" }),
4604 .src_loc = try eb.addSourceLocation(.{
4605 .src_path = try eb.printString("{f}", .{src.file_scope.path.fmt(zcu.comp)}),
4606 .span_start = span.start,
4607 .span_main = span.main,
4608 .span_end = span.end,
4609 .line = @intCast(loc.line),
4610 .column = @intCast(loc.column),
4611 .source_line = 0,
4612 }),
4613 });
4614}
4615
46164419fn addWholeFileError(
46174420 zcu: *Zcu,
46184421 eb: *ErrorBundle.Wip,
......@@ -4669,13 +4472,7 @@ fn performAllTheWork(
46694472 comp: *Compilation,
46704473 main_progress_node: std.Progress.Node,
46714474 update_arena: Allocator,
4672) JobError!void {
4673 defer if (comp.zcu) |zcu| {
4674 zcu.codegen_task_pool.cancel(zcu);
4675 // Regardless of errors, `comp.zcu` needs to update its generation number.
4676 zcu.generation += 1;
4677 };
4678
4475) (Allocator.Error || Io.Cancelable)!void {
46794476 const io = comp.io;
46804477
46814478 // This is awkward: we don't want to start the timer until later, but we won't want to stop it
......@@ -4708,216 +4505,32 @@ fn performAllTheWork(
47084505 misc_group.async(io, workerDocsWasm, .{ comp, main_progress_node });
47094506 }
47104507
4711 if (comp.zcu) |zcu| {
4712 const tracy_trace = traceNamed(@src(), "astgen");
4713 defer tracy_trace.end();
4714
4715 const zir_prog_node = main_progress_node.start("AST Lowering", 0);
4716 defer zir_prog_node.end();
4717
4718 var timer = comp.startTimer();
4719 defer if (timer.finish(io)) |ns| {
4720 comp.mutex.lockUncancelable(io);
4721 defer comp.mutex.unlock(io);
4722 comp.time_report.?.stats.real_ns_files = ns;
4723 };
4724
4725 const gpa = comp.gpa;
4726
4727 var astgen_group: Io.Group = .init;
4728 defer astgen_group.cancel(io);
4729
4730 // We cannot reference `zcu.import_table` after we spawn any `workerUpdateFile` jobs,
4731 // because on single-threaded targets the worker will be run eagerly, meaning the
4732 // `import_table` could be mutated, and not even holding `comp.mutex` will save us. So,
4733 // build up a list of the files to update *before* we spawn any jobs.
4734 var astgen_work_items: std.MultiArrayList(struct {
4735 file_index: Zcu.File.Index,
4736 file: *Zcu.File,
4737 }) = .empty;
4738 defer astgen_work_items.deinit(gpa);
4739 // Not every item in `import_table` will need updating, because some are builtin.zig
4740 // files. However, most will, so let's just reserve sufficient capacity upfront.
4741 try astgen_work_items.ensureTotalCapacity(gpa, zcu.import_table.count());
4742 for (zcu.import_table.keys()) |file_index| {
4743 const file = zcu.fileByIndex(file_index);
4744 if (file.is_builtin) {
4745 // This is a `builtin.zig`, so updating is redundant. However, we want to make
4746 // sure the file contents are still correct on disk, since it can improve the
4747 // debugging experience better. That job only needs `file`, so we can kick it
4748 // off right now.
4749 astgen_group.async(io, workerUpdateBuiltinFile, .{ comp, file });
4750 continue;
4751 }
4752 astgen_work_items.appendAssumeCapacity(.{
4753 .file_index = file_index,
4754 .file = file,
4755 });
4756 }
4757
4758 // Now that we're not going to touch `zcu.import_table` again, we can spawn `workerUpdateFile` jobs.
4759 for (astgen_work_items.items(.file_index), astgen_work_items.items(.file)) |file_index, file| {
4760 astgen_group.async(io, workerUpdateFile, .{
4761 comp, file, file_index, zir_prog_node, &astgen_group,
4762 });
4763 }
4764
4765 // On the other hand, it's fine to directly iterate `zcu.embed_table.keys()` here
4766 // because `workerUpdateEmbedFile` can't invalidate it. The different here is that one
4767 // `@embedFile` can't trigger analysis of a new `@embedFile`!
4768 for (0.., zcu.embed_table.keys()) |ef_index_usize, ef| {
4769 const ef_index: Zcu.EmbedFile.Index = @enumFromInt(ef_index_usize);
4770 astgen_group.async(io, workerUpdateEmbedFile, .{
4771 comp, ef_index, ef,
4772 });
4773 }
4774
4775 try astgen_group.await(io);
4776 }
4777
4508 defer if (comp.zcu) |zcu| zcu.codegen_task_pool.cancel(zcu);
47784509 if (comp.zcu) |zcu| {
47794510 const pt: Zcu.PerThread = .activate(zcu, .main);
4780 defer pt.deactivate();
4781
4782 const gpa = zcu.gpa;
4783
4784 // On an incremental update, a source file might become "dead", in that all imports of
4785 // the file were removed. This could even change what module the file belongs to! As such,
4786 // we do a traversal over the files, to figure out which ones are alive and the modules
4787 // they belong to.
4788 const any_fatal_files = try pt.computeAliveFiles();
4789
4790 // If the cache mode is `whole`, add every alive source file to the manifest.
4791 switch (comp.cache_use) {
4792 .whole => |whole| if (whole.cache_manifest) |man| {
4793 for (zcu.alive_files.keys()) |file_index| {
4794 const file = zcu.fileByIndex(file_index);
4795
4796 switch (file.status) {
4797 .never_loaded => unreachable, // AstGen tried to load it
4798 .retryable_failure => continue, // the file cannot be read; this is a guaranteed error
4799 .astgen_failure, .success => {}, // the file was read successfully
4800 }
4801
4802 const path = try file.path.toAbsolute(comp.dirs, gpa);
4803 defer gpa.free(path);
4804
4805 const result = res: {
4806 try whole.cache_manifest_mutex.lock(io);
4807 defer whole.cache_manifest_mutex.unlock(io);
4808 if (file.source) |source| {
4809 break :res man.addFilePostContents(path, source, file.stat);
4810 } else {
4811 break :res man.addFilePost(path);
4812 }
4813 };
4814 result catch |err| switch (err) {
4815 error.OutOfMemory => |e| return e,
4816 else => {
4817 try pt.reportRetryableFileError(file_index, "unable to update cache: {s}", .{@errorName(err)});
4818 continue;
4819 },
4820 };
4821 }
4822 },
4823 .none, .incremental => {},
4824 }
4825
4826 if (any_fatal_files or
4827 zcu.multi_module_err != null or
4828 zcu.failed_imports.items.len > 0 or
4829 comp.alloc_failure_occurred)
4830 {
4831 // We give up right now! No updating of ZIR refs, no nothing. The idea is that this prevents
4832 // us from invalidating lots of incremental dependencies due to files with e.g. parse errors.
4833 // However, this means our analysis data is invalid, so we want to omit all analysis errors.
4834 zcu.skip_analysis_this_update = true;
4835 // Since we're skipping analysis, there are no ZCU link tasks.
4836 comp.link_queue.finishZcuQueue(comp);
4837 // Let other compilation work finish to collect as many errors as possible.
4838 try misc_group.await(io);
4839 comp.link_queue.wait(io);
4840 return;
4841 }
4842
4843 if (comp.time_report) |*tr| {
4844 tr.stats.n_reachable_files = @intCast(zcu.alive_files.count());
4845 }
4846
4847 if (comp.config.incremental) {
4848 const update_zir_refs_node = main_progress_node.start("Update ZIR References", 0);
4849 defer update_zir_refs_node.end();
4850 try pt.updateZirRefs();
4851 }
4852 try zcu.flushRetryableFailures();
4853
4854 // It's analysis time! Queue up our initial analysis.
4855 for (zcu.analysisRoots()) |mod| {
4856 try comp.queueJob(.{ .analyze_mod = mod });
4857 }
4858
4859 zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
4860 if (comp.bin_file != null) {
4861 zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0);
4862 }
4863 // We increment `pending_codegen_jobs` so that it doesn't reach 0 until after analysis finishes.
4864 // That prevents the "Code Generation" node from constantly disappearing and reappearing when
4865 // we're probably going to analyze more functions at some point.
4866 assert(zcu.pending_codegen_jobs.swap(1, .monotonic) == 0); // don't let this become 0 until analysis finishes
4867 }
4868 // When analysis ends, delete the progress nodes for "Semantic Analysis" and possibly "Code Generation".
4869 defer if (comp.zcu) |zcu| {
4870 zcu.sema_prog_node.end();
4871 zcu.sema_prog_node = .none;
4872 if (zcu.pending_codegen_jobs.fetchSub(1, .monotonic) == 1) {
4873 // Decremented to 0, so all done.
4874 zcu.codegen_prog_node.end();
4875 zcu.codegen_prog_node = .none;
4876 }
4877 };
4878
4879 if (comp.zcu) |zcu| {
4880 if (!zcu.backendSupportsFeature(.separate_thread)) {
4881 // Close the ZCU task queue. Prelink may still be running, but the closed
4882 // queue will cause the linker task to exit once prelink finishes. The
4883 // closed queue also communicates to `enqueueZcu` that it should wait for
4884 // the linker task to finish and then run ZCU tasks serially.
4885 comp.link_queue.finishZcuQueue(comp);
4511 defer {
4512 pt.deactivate();
4513 // Regardless of errors, `comp.zcu` needs to update its generation number.
4514 zcu.generation += 1;
48864515 }
4516 try pt.update(main_progress_node, &decl_work_timer);
48874517 }
48884518
4889 if (comp.zcu != null) {
4890 // Start the timer for the "decls" part of the pipeline (Sema, CodeGen, link).
4891 decl_work_timer = comp.startTimer();
4892 }
4519 comp.link_queue.finishZcuQueue(comp);
48934520
4894 work: while (true) {
4895 for (&comp.work_queues) |*work_queue| if (work_queue.popFront()) |job| {
4896 try processOneJob(.main, comp, job);
4897 continue :work;
4521 // This has to happen after the main semantic analysis loop because it is possible for Sema to
4522 // call `addLinkLib` and hence add more items to `comp.windows_libs`.
4523 for (comp.windows_libs.keys()[comp.windows_libs_num_done..]) |link_lib| {
4524 mingw.buildImportLib(comp, link_lib) catch |err| {
4525 // TODO Surface more error details.
4526 comp.lockAndSetMiscFailure(
4527 .windows_import_lib,
4528 "unable to generate DLL import .lib file for {s}: {t}",
4529 .{ link_lib, err },
4530 );
48984531 };
4899 if (comp.zcu) |zcu| {
4900 // If there's no work queued, check if there's anything outdated
4901 // which we need to work on, and queue it if so.
4902 if (try zcu.findOutdatedToAnalyze()) |outdated| {
4903 try comp.queueJob(switch (outdated.unwrap()) {
4904 .func => |f| .{ .analyze_func = f },
4905 .memoized_state,
4906 .@"comptime",
4907 .nav_ty,
4908 .nav_val,
4909 .type,
4910 => .{ .analyze_comptime_unit = outdated },
4911 });
4912 continue;
4913 }
4914 zcu.sema_prog_node.end();
4915 zcu.sema_prog_node = .none;
4916 }
4917 break;
49184532 }
4919
4920 comp.link_queue.finishZcuQueue(comp);
4533 comp.windows_libs_num_done = @intCast(comp.windows_libs.count());
49214534
49224535 // Main thread work is all done, now just wait for all async work.
49234536 try misc_group.await(io);
......@@ -5148,172 +4761,6 @@ fn dispatchPrelinkWork(comp: *Compilation, main_progress_node: std.Progress.Node
51484761 };
51494762}
51504763
5151const JobError = Allocator.Error || Io.Cancelable;
5152
5153pub fn queueJob(comp: *Compilation, job: Job) !void {
5154 try comp.work_queues[Job.stage(job)].pushBack(comp.gpa, job);
5155}
5156
5157pub fn queueJobs(comp: *Compilation, jobs: []const Job) !void {
5158 for (jobs) |job| try comp.queueJob(job);
5159}
5160
5161fn processOneJob(tid: Zcu.PerThread.Id, comp: *Compilation, job: Job) JobError!void {
5162 switch (job) {
5163 .codegen_func => |func| {
5164 const zcu = comp.zcu.?;
5165 const gpa = zcu.gpa;
5166 var owned_air: ?Air = func.air;
5167 defer if (owned_air) |*air| air.deinit(gpa);
5168
5169 if (!owned_air.?.typesFullyResolved(zcu)) {
5170 // Type resolution failed in a way which affects this function. This is a transitive
5171 // failure, but it doesn't need recording, because this function semantically depends
5172 // on the failed type, so when it is changed the function is updated.
5173 zcu.codegen_prog_node.completeOne();
5174 comp.link_prog_node.completeOne();
5175 return;
5176 }
5177
5178 // Some linkers need to refer to the AIR. In that case, the linker is not running
5179 // concurrently, so we'll just keep ownership of the AIR for ourselves instead of
5180 // letting the codegen job destroy it.
5181 const disown_air = zcu.backendSupportsFeature(.separate_thread);
5182
5183 // Begin the codegen task. If the codegen/link queue is backed up, this might
5184 // block until the linker is able to process some tasks.
5185 const codegen_task = try zcu.codegen_task_pool.start(zcu, func.func, &owned_air.?, disown_air);
5186 if (disown_air) owned_air = null;
5187
5188 try comp.link_queue.enqueueZcu(comp, tid, .{ .link_func = codegen_task });
5189 },
5190 .link_nav => |nav_index| {
5191 const zcu = comp.zcu.?;
5192 const nav = zcu.intern_pool.getNav(nav_index);
5193 if (nav.analysis != null) {
5194 const unit: InternPool.AnalUnit = .wrap(.{ .nav_val = nav_index });
5195 if (zcu.failed_analysis.contains(unit) or zcu.transitive_failed_analysis.contains(unit)) {
5196 comp.link_prog_node.completeOne();
5197 return;
5198 }
5199 }
5200 assert(nav.status == .fully_resolved);
5201 if (!Air.valFullyResolved(zcu.navValue(nav_index), zcu)) {
5202 // Type resolution failed in a way which affects this `Nav`. This is a transitive
5203 // failure, but it doesn't need recording, because this `Nav` semantically depends
5204 // on the failed type, so when it is changed the `Nav` will be updated.
5205 comp.link_prog_node.completeOne();
5206 return;
5207 }
5208 try comp.link_queue.enqueueZcu(comp, tid, .{ .link_nav = nav_index });
5209 },
5210 .link_type => |ty| {
5211 const zcu = comp.zcu.?;
5212 if (zcu.failed_types.fetchSwapRemove(ty)) |*entry| entry.value.deinit(zcu.gpa);
5213 if (!Air.typeFullyResolved(.fromInterned(ty), zcu)) {
5214 // Type resolution failed in a way which affects this type. This is a transitive
5215 // failure, but it doesn't need recording, because this type semantically depends
5216 // on the failed type, so when that is changed, this type will be updated.
5217 comp.link_prog_node.completeOne();
5218 return;
5219 }
5220 try comp.link_queue.enqueueZcu(comp, tid, .{ .link_type = ty });
5221 },
5222 .update_line_number => |tracked_inst| {
5223 try comp.link_queue.enqueueZcu(comp, tid, .{ .update_line_number = tracked_inst });
5224 },
5225 .analyze_func => |func| {
5226 const tracy_trace = traceNamed(@src(), "analyze_func");
5227 defer tracy_trace.end();
5228
5229 const pt: Zcu.PerThread = .activate(comp.zcu.?, tid);
5230 defer pt.deactivate();
5231
5232 pt.ensureFuncBodyUpToDate(func) catch |err| switch (err) {
5233 error.OutOfMemory => |e| return e,
5234 error.Canceled => |e| return e,
5235 error.AnalysisFail => return,
5236 };
5237 },
5238 .analyze_comptime_unit => |unit| {
5239 const tracy_trace = traceNamed(@src(), "analyze_comptime_unit");
5240 defer tracy_trace.end();
5241
5242 const pt: Zcu.PerThread = .activate(comp.zcu.?, tid);
5243 defer pt.deactivate();
5244
5245 const maybe_err: Zcu.SemaError!void = switch (unit.unwrap()) {
5246 .@"comptime" => |cu| pt.ensureComptimeUnitUpToDate(cu),
5247 .nav_ty => |nav| pt.ensureNavTypeUpToDate(nav),
5248 .nav_val => |nav| pt.ensureNavValUpToDate(nav),
5249 .type => |ty| if (pt.ensureTypeUpToDate(ty)) |_| {} else |err| err,
5250 .memoized_state => |stage| pt.ensureMemoizedStateUpToDate(stage),
5251 .func => unreachable,
5252 };
5253 maybe_err catch |err| switch (err) {
5254 error.OutOfMemory => |e| return e,
5255 error.Canceled => |e| return e,
5256 error.AnalysisFail => return,
5257 };
5258
5259 queue_test_analysis: {
5260 if (!comp.config.is_test) break :queue_test_analysis;
5261 const nav = switch (unit.unwrap()) {
5262 .nav_val => |nav| nav,
5263 else => break :queue_test_analysis,
5264 };
5265
5266 // Check if this is a test function.
5267 const ip = &pt.zcu.intern_pool;
5268 if (!pt.zcu.test_functions.contains(nav)) {
5269 break :queue_test_analysis;
5270 }
5271
5272 // Tests are always emitted in test binaries. The decl_refs are created by
5273 // Zcu.populateTestFunctions, but this will not queue body analysis, so do
5274 // that now.
5275 try pt.zcu.ensureFuncBodyAnalysisQueued(ip.getNav(nav).status.fully_resolved.val);
5276 }
5277 },
5278 .resolve_type_fully => |ty| {
5279 const tracy_trace = traceNamed(@src(), "resolve_type_fully");
5280 defer tracy_trace.end();
5281
5282 const pt: Zcu.PerThread = .activate(comp.zcu.?, tid);
5283 defer pt.deactivate();
5284 Type.fromInterned(ty).resolveFully(pt) catch |err| switch (err) {
5285 error.OutOfMemory, error.Canceled => |e| return e,
5286 error.AnalysisFail => return,
5287 };
5288 },
5289 .analyze_mod => |mod| {
5290 const tracy_trace = traceNamed(@src(), "analyze_mod");
5291 defer tracy_trace.end();
5292
5293 const pt: Zcu.PerThread = .activate(comp.zcu.?, tid);
5294 defer pt.deactivate();
5295 pt.semaMod(mod) catch |err| switch (err) {
5296 error.OutOfMemory, error.Canceled => |e| return e,
5297 error.AnalysisFail => return,
5298 };
5299 },
5300 .windows_import_lib => |index| {
5301 const tracy_trace = traceNamed(@src(), "windows_import_lib");
5302 defer tracy_trace.end();
5303
5304 const link_lib = comp.windows_libs.keys()[index];
5305 mingw.buildImportLib(comp, link_lib) catch |err| {
5306 // TODO Surface more error details.
5307 comp.lockAndSetMiscFailure(
5308 .windows_import_lib,
5309 "unable to generate DLL import .lib file for {s}: {t}",
5310 .{ link_lib, err },
5311 );
5312 };
5313 },
5314 }
5315}
5316
53174764fn createDepFile(comp: *Compilation, dep_file: []const u8, bin_file: Cache.Path) anyerror!void {
53184765 const io = comp.io;
53194766
......@@ -5641,112 +5088,6 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU
56415088 };
56425089}
56435090
5644fn workerUpdateFile(
5645 comp: *Compilation,
5646 file: *Zcu.File,
5647 file_index: Zcu.File.Index,
5648 prog_node: std.Progress.Node,
5649 group: *Io.Group,
5650) void {
5651 const io = comp.io;
5652 const tid: Zcu.PerThread.Id = .acquire(io);
5653 defer tid.release(io);
5654
5655 const child_prog_node = prog_node.start(fs.path.basename(file.path.sub_path), 0);
5656 defer child_prog_node.end();
5657
5658 const pt: Zcu.PerThread = .activate(comp.zcu.?, tid);
5659 defer pt.deactivate();
5660 pt.updateFile(file_index, file) catch |err| {
5661 pt.reportRetryableFileError(file_index, "unable to load '{s}': {s}", .{ fs.path.basename(file.path.sub_path), @errorName(err) }) catch |oom| switch (oom) {
5662 error.OutOfMemory => {
5663 comp.mutex.lockUncancelable(io);
5664 defer comp.mutex.unlock(io);
5665 comp.setAllocFailure();
5666 },
5667 };
5668 return;
5669 };
5670
5671 switch (file.getMode()) {
5672 .zig => {}, // continue to logic below
5673 .zon => return, // ZON can't import anything so we're done
5674 }
5675
5676 // Discover all imports in the file. Imports of modules we ignore for now since we don't
5677 // know which module we're in, but imports of file paths might need us to queue up other
5678 // AstGen jobs.
5679 const imports_index = file.zir.?.extra[@intFromEnum(Zir.ExtraIndex.imports)];
5680 if (imports_index != 0) {
5681 const extra = file.zir.?.extraData(Zir.Inst.Imports, imports_index);
5682 var import_i: u32 = 0;
5683 var extra_index = extra.end;
5684
5685 while (import_i < extra.data.imports_len) : (import_i += 1) {
5686 const item = file.zir.?.extraData(Zir.Inst.Imports.Item, extra_index);
5687 extra_index = item.end;
5688
5689 const import_path = file.zir.?.nullTerminatedString(item.data.name);
5690
5691 if (pt.discoverImport(file.path, import_path)) |res| switch (res) {
5692 .module, .existing_file => {},
5693 .new_file => |new| {
5694 group.async(io, workerUpdateFile, .{
5695 comp, new.file, new.index, prog_node, group,
5696 });
5697 },
5698 } else |err| switch (err) {
5699 error.OutOfMemory => {
5700 comp.mutex.lockUncancelable(io);
5701 defer comp.mutex.unlock(io);
5702 comp.setAllocFailure();
5703 },
5704 }
5705 }
5706 }
5707}
5708
5709fn workerUpdateBuiltinFile(comp: *Compilation, file: *Zcu.File) void {
5710 Builtin.updateFileOnDisk(file, comp) catch |err| comp.lockAndSetMiscFailure(
5711 .write_builtin_zig,
5712 "unable to write '{f}': {s}",
5713 .{ file.path.fmt(comp), @errorName(err) },
5714 );
5715}
5716
5717fn workerUpdateEmbedFile(comp: *Compilation, ef_index: Zcu.EmbedFile.Index, ef: *Zcu.EmbedFile) void {
5718 const io = comp.io;
5719 const tid: Zcu.PerThread.Id = .acquire(io);
5720 defer tid.release(io);
5721 comp.detectEmbedFileUpdate(tid, ef_index, ef) catch |err| switch (err) {
5722 error.OutOfMemory => {
5723 comp.mutex.lockUncancelable(io);
5724 defer comp.mutex.unlock(io);
5725 comp.setAllocFailure();
5726 },
5727 };
5728}
5729
5730fn detectEmbedFileUpdate(comp: *Compilation, tid: Zcu.PerThread.Id, ef_index: Zcu.EmbedFile.Index, ef: *Zcu.EmbedFile) !void {
5731 const io = comp.io;
5732 const zcu = comp.zcu.?;
5733 const pt: Zcu.PerThread = .activate(zcu, tid);
5734 defer pt.deactivate();
5735
5736 const old_val = ef.val;
5737 const old_err = ef.err;
5738
5739 try pt.updateEmbedFile(ef, null);
5740
5741 if (ef.val != .none and ef.val == old_val) return; // success, value unchanged
5742 if (ef.val == .none and old_val == .none and ef.err == old_err) return; // failure, error unchanged
5743
5744 comp.mutex.lockUncancelable(io);
5745 defer comp.mutex.unlock(io);
5746
5747 try zcu.markDependeeOutdated(.not_marked_po, .{ .embed_file = ef_index });
5748}
5749
57505091pub fn obtainCObjectCacheManifest(
57515092 comp: *const Compilation,
57525093 owner_mod: *Package.Module,
......@@ -8375,12 +7716,10 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void {
83757716 // If we haven't seen this library yet and we're targeting Windows, we need
83767717 // to queue up a work item to produce the DLL import library for this.
83777718 const gop = try comp.windows_libs.getOrPut(comp.gpa, lib_name);
8378 if (gop.found_existing) return;
8379 {
7719 if (!gop.found_existing) {
83807720 errdefer _ = comp.windows_libs.pop();
83817721 gop.key_ptr.* = try comp.gpa.dupe(u8, lib_name);
83827722 }
8383 try comp.queueJob(.{ .windows_import_lib = gop.index });
83847723}
83857724
83867725/// This decides the optimization mode for all zig-provided libraries, including
src/IncrementalDebugServer.zig+6-8
......@@ -306,12 +306,8 @@ fn handleCommand(zcu: *Zcu, w: *Io.Writer, cmd_str: []const u8, arg_str: []const
306306 try w.print("[{d}] ", .{i});
307307 switch (dependee) {
308308 .src_hash, .namespace, .namespace_name, .zon_file, .embed_file => try w.print("{f}", .{zcu.fmtDependee(dependee)}),
309 .nav_val, .nav_ty => |nav| try w.print("{s} {d}", .{ @tagName(dependee), @intFromEnum(nav) }),
310 .interned => |ip_index| switch (ip.indexToKey(ip_index)) {
311 .struct_type, .union_type, .enum_type => try w.print("type {d}", .{@intFromEnum(ip_index)}),
312 .func => try w.print("func {d}", .{@intFromEnum(ip_index)}),
313 else => unreachable,
314 },
309 .nav_val, .nav_ty => |nav| try w.print("{t} {d}", .{ dependee, @intFromEnum(nav) }),
310 .type_layout, .struct_defaults, .func_ies => |ip_index| try w.print("{t} {d}", .{ dependee, @intFromEnum(ip_index) }),
315311 .memoized_state => |stage| try w.print("memoized_state {s}", .{@tagName(stage)}),
316312 }
317313 try w.writeByte('\n');
......@@ -376,8 +372,10 @@ fn parseAnalUnit(str: []const u8) ?AnalUnit {
376372 return .wrap(.{ .nav_val = @enumFromInt(parseIndex(idx_str) orelse return null) });
377373 } else if (std.mem.eql(u8, kind, "nav_ty")) {
378374 return .wrap(.{ .nav_ty = @enumFromInt(parseIndex(idx_str) orelse return null) });
379 } else if (std.mem.eql(u8, kind, "type")) {
380 return .wrap(.{ .type = @enumFromInt(parseIndex(idx_str) orelse return null) });
375 } else if (std.mem.eql(u8, kind, "type_layout")) {
376 return .wrap(.{ .type_layout = @enumFromInt(parseIndex(idx_str) orelse return null) });
377 } else if (std.mem.eql(u8, kind, "struct_defaults")) {
378 return .wrap(.{ .struct_defaults = @enumFromInt(parseIndex(idx_str) orelse return null) });
381379 } else if (std.mem.eql(u8, kind, "func")) {
382380 return .wrap(.{ .func = @enumFromInt(parseIndex(idx_str) orelse return null) });
383381 } else if (std.mem.eql(u8, kind, "memoized_state")) {
src/InternPool.zig+2670-2835
......@@ -17,6 +17,7 @@ const Hash = std.hash.Wyhash;
1717const Zir = std.zig.Zir;
1818
1919const Zcu = @import("Zcu.zig");
20const TypeClass = @import("Type.zig").Class;
2021
2122/// One item per thread, indexed by `tid`, which is dense and unique per thread.
2223locals: []Local,
......@@ -47,11 +48,15 @@ nav_val_deps: std.AutoArrayHashMapUnmanaged(Nav.Index, DepEntry.Index),
4748/// Dependencies on the type of a Nav.
4849/// Value is index into `dep_entries` of the first dependency on this Nav value.
4950nav_ty_deps: std.AutoArrayHashMapUnmanaged(Nav.Index, DepEntry.Index),
50/// Dependencies on an interned value, either:
51/// * a runtime function (invalidated when its IES changes)
52/// * a container type requiring resolution (invalidated when the type must be recreated at a new index)
53/// Value is index into `dep_entries` of the first dependency on this interned value.
54interned_deps: std.AutoArrayHashMapUnmanaged(Index, DepEntry.Index),
51/// Dependencies on a function's inferred error set. Key is the function body, not the IES.
52/// Value is index into `dep_entries` of the first dependency on this function's IES.
53func_ies_deps: std.AutoArrayHashMapUnmanaged(Index, DepEntry.Index),
54/// Dependencies on the resolved layout of a `struct`, `union`, or `enum` type.
55/// Value is index into `dep_entries` of the first dependency on this type's layout.
56type_layout_deps: std.AutoArrayHashMapUnmanaged(Index, DepEntry.Index),
57/// Dependencies on the resolved default field values of a `struct` type.
58/// Value is index into `dep_entries` of the first dependency on this type's inits.
59struct_defaults_deps: std.AutoArrayHashMapUnmanaged(Index, DepEntry.Index),
5560/// Dependencies on a ZON file. Triggered by `@import` of ZON.
5661/// Value is index into `dep_entries` of the first dependency on this ZON file.
5762zon_file_deps: std.AutoArrayHashMapUnmanaged(FileIndex, DepEntry.Index),
......@@ -104,7 +109,9 @@ pub const empty: InternPool = .{
104109 .src_hash_deps = .empty,
105110 .nav_val_deps = .empty,
106111 .nav_ty_deps = .empty,
107 .interned_deps = .empty,
112 .func_ies_deps = .empty,
113 .type_layout_deps = .empty,
114 .struct_defaults_deps = .empty,
108115 .zon_file_deps = .empty,
109116 .embed_file_deps = .empty,
110117 .namespace_deps = .empty,
......@@ -415,7 +422,8 @@ pub const AnalUnit = packed struct(u64) {
415422 @"comptime",
416423 nav_val,
417424 nav_ty,
418 type,
425 type_layout,
426 struct_defaults,
419427 func,
420428 memoized_state,
421429 };
......@@ -427,9 +435,10 @@ pub const AnalUnit = packed struct(u64) {
427435 nav_val: Nav.Index,
428436 /// This `AnalUnit` resolves the type of the given `Nav`.
429437 nav_ty: Nav.Index,
430 /// This `AnalUnit` resolves the given `struct`/`union`/`enum` type.
431 /// Generated tag enums are never used here (they do not undergo type resolution).
432 type: InternPool.Index,
438 /// This `AnalUnit` resolves the layout of the given `struct`, `union`, or `enum` type.
439 type_layout: InternPool.Index,
440 /// This `AnalUnit` resolves the default field values of the given `struct` type.
441 struct_defaults: InternPool.Index,
433442 /// This `AnalUnit` analyzes the body of the given runtime function.
434443 func: InternPool.Index,
435444 /// This `AnalUnit` resolves all state which is memoized in fields on `Zcu`.
......@@ -538,6 +547,8 @@ pub const Nav = struct {
538547 analysis: ?struct {
539548 namespace: NamespaceIndex,
540549 zir_index: TrackedInst.Index,
550 /// Initially `false`. Set to `true` by `setWantNavAnalysis`.
551 wanted: bool,
541552 },
542553 status: union(enum) {
543554 /// This `Nav` is pending semantic analysis.
......@@ -735,7 +746,7 @@ pub const Nav = struct {
735746 const Repr = struct {
736747 name: NullTerminatedString,
737748 fqn: NullTerminatedString,
738 // The following 1 fields are either both populated, or both `.none`.
749 // The following 2 fields are either both populated, or both `.none`.
739750 analysis_namespace: OptionalNamespaceIndex,
740751 analysis_zir_index: TrackedInst.Index.Optional,
741752 /// Populated only if `bits.status != .unresolved`.
......@@ -754,7 +765,7 @@ pub const Nav = struct {
754765 @"addrspace": std.builtin.AddressSpace,
755766 /// Populated only if `bits.status == .type_resolved`.
756767 is_threadlocal: bool,
757 _: u1 = 0,
768 want_analysis: bool,
758769 };
759770
760771 fn unpack(repr: Repr) Nav {
......@@ -764,6 +775,7 @@ pub const Nav = struct {
764775 .analysis = if (repr.analysis_namespace.unwrap()) |namespace| .{
765776 .namespace = namespace,
766777 .zir_index = repr.analysis_zir_index.unwrap().?,
778 .wanted = repr.bits.want_analysis,
767779 } else a: {
768780 assert(repr.analysis_zir_index == .none);
769781 break :a null;
......@@ -816,6 +828,7 @@ pub const Nav = struct {
816828 .alignment = .none,
817829 .@"addrspace" = .generic,
818830 .is_threadlocal = false,
831 .want_analysis = if (nav.analysis) |a| a.wanted else false,
819832 },
820833 .type_resolved => |r| .{
821834 .status = if (r.is_extern_decl) .type_resolved_extern_decl else .type_resolved,
......@@ -823,6 +836,7 @@ pub const Nav = struct {
823836 .alignment = r.alignment,
824837 .@"addrspace" = r.@"addrspace",
825838 .is_threadlocal = r.is_threadlocal,
839 .want_analysis = if (nav.analysis) |a| a.wanted else false,
826840 },
827841 .fully_resolved => |r| .{
828842 .status = .fully_resolved,
......@@ -830,6 +844,7 @@ pub const Nav = struct {
830844 .alignment = r.alignment,
831845 .@"addrspace" = r.@"addrspace",
832846 .is_threadlocal = false,
847 .want_analysis = if (nav.analysis) |a| a.wanted else false,
833848 },
834849 },
835850 };
......@@ -840,7 +855,10 @@ pub const Dependee = union(enum) {
840855 src_hash: TrackedInst.Index,
841856 nav_val: Nav.Index,
842857 nav_ty: Nav.Index,
843 interned: Index,
858 /// Index is the function, not its IES.
859 func_ies: Index,
860 type_layout: Index,
861 struct_defaults: Index,
844862 zon_file: FileIndex,
845863 embed_file: Zcu.EmbedFile.Index,
846864 namespace: TrackedInst.Index,
......@@ -892,7 +910,9 @@ pub fn dependencyIterator(ip: *const InternPool, dependee: Dependee) DependencyI
892910 .src_hash => |x| ip.src_hash_deps.get(x),
893911 .nav_val => |x| ip.nav_val_deps.get(x),
894912 .nav_ty => |x| ip.nav_ty_deps.get(x),
895 .interned => |x| ip.interned_deps.get(x),
913 .func_ies => |x| ip.func_ies_deps.get(x),
914 .type_layout => |x| ip.type_layout_deps.get(x),
915 .struct_defaults => |x| ip.struct_defaults_deps.get(x),
896916 .zon_file => |x| ip.zon_file_deps.get(x),
897917 .embed_file => |x| ip.embed_file_deps.get(x),
898918 .namespace => |x| ip.namespace_deps.get(x),
......@@ -965,7 +985,9 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalUnit, depend
965985 .src_hash => ip.src_hash_deps,
966986 .nav_val => ip.nav_val_deps,
967987 .nav_ty => ip.nav_ty_deps,
968 .interned => ip.interned_deps,
988 .func_ies => ip.func_ies_deps,
989 .type_layout => ip.type_layout_deps,
990 .struct_defaults => ip.struct_defaults_deps,
969991 .zon_file => ip.zon_file_deps,
970992 .embed_file => ip.embed_file_deps,
971993 .namespace => ip.namespace_deps,
......@@ -2065,15 +2087,15 @@ pub const Key = union(enum) {
20652087 simple_type: SimpleType,
20662088 /// This represents a struct that has been explicitly declared in source code,
20672089 /// or was created with `@Struct`. It is unique and based on a declaration.
2068 struct_type: NamespaceType,
2090 struct_type: ContainerType,
20692091 /// This is a tuple type. Tuples are logically similar to structs, but have some
20702092 /// important differences in semantics; they do not undergo staged type resolution,
20712093 /// so cannot be self-referential, and they are not considered container/namespace
20722094 /// types, so cannot have declarations and have structural equality properties.
20732095 tuple_type: TupleType,
2074 union_type: NamespaceType,
2075 opaque_type: NamespaceType,
2076 enum_type: NamespaceType,
2096 union_type: ContainerType,
2097 opaque_type: ContainerType,
2098 enum_type: ContainerType,
20772099 func_type: FuncType,
20782100 error_set_type: ErrorSetType,
20792101 /// The payload is the function body, either a `func_decl` or `func_instance`.
......@@ -2092,10 +2114,6 @@ pub const Key = union(enum) {
20922114 enum_literal: NullTerminatedString,
20932115 /// A specific enum tag, indicated by the integer tag value.
20942116 enum_tag: EnumTag,
2095 /// An empty enum or union. TODO: this value's existence is strange, because such a type in
2096 /// reality has no values. See #15909.
2097 /// Payload is the type for which we are an empty value.
2098 empty_enum_value: Index,
20992117 float: Float,
21002118 ptr: Ptr,
21012119 slice: Slice,
......@@ -2109,6 +2127,8 @@ pub const Key = union(enum) {
21092127 aggregate: Aggregate,
21102128 /// An instance of a union.
21112129 un: Union,
2130 /// An instance of a `packed struct` or `packed union`.
2131 bitpack: Bitpack,
21122132
21132133 /// A comptime function call with a memoized result.
21142134 memoized_call: Key.MemoizedCall,
......@@ -2211,16 +2231,10 @@ pub const Key = union(enum) {
22112231 /// * `loadUnionType`
22122232 /// * `loadEnumType`
22132233 /// * `loadOpaqueType`
2214 pub const NamespaceType = union(enum) {
2234 pub const ContainerType = union(enum) {
22152235 /// This type corresponds to an actual source declaration, e.g. `struct { ... }`.
22162236 /// It is hashed based on its ZIR instruction index and set of captures.
22172237 declared: Declared,
2218 /// This type is an automatically-generated enum tag type for a union.
2219 /// It is hashed based on the index of the union type it corresponds to.
2220 generated_tag: struct {
2221 /// The union for which this is a tag type.
2222 union_type: Index,
2223 },
22242238 /// This type originates from a reification via `@Enum`, `@Struct`, `@Union` or from an anonymous initialization.
22252239 /// It is hashed based on its ZIR instruction index and fields, attributes, etc.
22262240 /// To avoid making this key overly complex, the type-specific data is hashed by Sema.
......@@ -2231,6 +2245,9 @@ pub const Key = union(enum) {
22312245 /// A hash of this type's attributes, fields, etc, generated by Sema.
22322246 type_hash: u64,
22332247 },
2248 /// This type is an automatically-generated enum tag type for this union type.
2249 /// It is hashed based on the index of the union type it corresponds to.
2250 generated_union_tag: Index,
22342251
22352252 pub const Declared = struct {
22362253 /// A `struct_decl`, `union_decl`, `enum_decl`, or `opaque_decl` instruction.
......@@ -2254,7 +2271,6 @@ pub const Key = union(enum) {
22542271 noalias_bits: u32,
22552272 cc: std.builtin.CallingConvention,
22562273 is_var_args: bool,
2257 is_generic: bool,
22582274 is_noinline: bool,
22592275
22602276 pub fn paramIsComptime(self: @This(), i: u5) bool {
......@@ -2273,7 +2289,6 @@ pub const Key = union(enum) {
22732289 a.comptime_bits == b.comptime_bits and
22742290 a.noalias_bits == b.noalias_bits and
22752291 a.is_var_args == b.is_var_args and
2276 a.is_generic == b.is_generic and
22772292 a.is_noinline == b.is_noinline and
22782293 std.meta.eql(a.cc, b.cc);
22792294 }
......@@ -2287,7 +2302,6 @@ pub const Key = union(enum) {
22872302 std.hash.autoHash(hasher, self.noalias_bits);
22882303 std.hash.autoHash(hasher, self.cc);
22892304 std.hash.autoHash(hasher, self.is_var_args);
2290 std.hash.autoHash(hasher, self.is_generic);
22912305 std.hash.autoHash(hasher, self.is_noinline);
22922306 }
22932307 };
......@@ -2403,17 +2417,6 @@ pub const Key = union(enum) {
24032417 @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);
24042418 }
24052419
2406 pub fn setAnalyzed(func: Func, ip: *InternPool, io: Io) void {
2407 const extra_mutex = &ip.getLocal(func.tid).mutate.extra.mutex;
2408 extra_mutex.lockUncancelable(io);
2409 defer extra_mutex.unlock(io);
2410
2411 const analysis_ptr = func.analysisPtr(ip);
2412 var analysis = analysis_ptr.*;
2413 analysis.is_analyzed = true;
2414 @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release);
2415 }
2416
24172420 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
24182421 fn zirBodyInstPtr(func: Func, ip: *const InternPool) *TrackedInst.Index {
24192422 const extra = ip.getLocalShared(func.tid).extra.acquire();
......@@ -2471,8 +2474,6 @@ pub const Key = union(enum) {
24712474 u64: u64,
24722475 i64: i64,
24732476 big_int: BigIntConst,
2474 lazy_align: Index,
2475 lazy_size: Index,
24762477
24772478 /// Big enough to fit any non-BigInt value
24782479 pub const BigIntSpace = struct {
......@@ -2485,7 +2486,6 @@ pub const Key = union(enum) {
24852486 return switch (storage) {
24862487 .big_int => |x| x,
24872488 inline .u64, .i64 => |x| BigIntMutable.init(&space.limbs, x).toConst(),
2488 .lazy_align, .lazy_size => unreachable,
24892489 };
24902490 }
24912491 };
......@@ -2680,6 +2680,15 @@ pub const Key = union(enum) {
26802680 };
26812681 };
26822682
2683 /// As well as a key, this type doubles as the payload in `extra` for `Tag.bitpack`.
2684 pub const Bitpack = struct {
2685 /// The `packed struct` or `packed union` type.
2686 ty: Index,
2687 /// The contents of the bitpack, represented as the backing integer value. The type of this
2688 /// value is the same as the backing integer type of `ty`.
2689 backing_int_val: Index,
2690 };
2691
26832692 pub const MemoizedCall = struct {
26842693 func: Index,
26852694 arg_values: []const Index,
......@@ -2710,7 +2719,6 @@ pub const Key = union(enum) {
27102719 .err,
27112720 .enum_literal,
27122721 .enum_tag,
2713 .empty_enum_value,
27142722 .inferred_error_set_type,
27152723 .un,
27162724 => |x| Hash.hash(seed, asBytes(&x)),
......@@ -2742,13 +2750,13 @@ pub const Key = union(enum) {
27422750 std.hash.autoHash(&hasher, cv);
27432751 }
27442752 },
2745 .generated_tag => |generated_tag| {
2746 std.hash.autoHash(&hasher, generated_tag.union_type);
2747 },
27482753 .reified => |reified| {
27492754 std.hash.autoHash(&hasher, reified.zir_index);
27502755 std.hash.autoHash(&hasher, reified.type_hash);
27512756 },
2757 .generated_union_tag => |union_type| {
2758 std.hash.autoHash(&hasher, union_type);
2759 },
27522760 }
27532761 return hasher.final();
27542762 },
......@@ -2756,23 +2764,12 @@ pub const Key = union(enum) {
27562764 .int => |int| {
27572765 var hasher = Hash.init(seed);
27582766 // Canonicalize all integers by converting them to BigIntConst.
2759 switch (int.storage) {
2760 .u64, .i64, .big_int => {
2761 var buffer: Key.Int.Storage.BigIntSpace = undefined;
2762 const big_int = int.storage.toBigInt(&buffer);
2763
2764 std.hash.autoHash(&hasher, int.ty);
2765 std.hash.autoHash(&hasher, big_int.positive);
2766 for (big_int.limbs) |limb| std.hash.autoHash(&hasher, limb);
2767 },
2768 .lazy_align, .lazy_size => |lazy_ty| {
2769 std.hash.autoHash(
2770 &hasher,
2771 @as(@typeInfo(Key.Int.Storage).@"union".tag_type.?, int.storage),
2772 );
2773 std.hash.autoHash(&hasher, lazy_ty);
2774 },
2775 }
2767 var buffer: Key.Int.Storage.BigIntSpace = undefined;
2768 const big_int = int.storage.toBigInt(&buffer);
2769
2770 std.hash.autoHash(&hasher, int.ty);
2771 std.hash.autoHash(&hasher, big_int.positive);
2772 for (big_int.limbs) |limb| std.hash.autoHash(&hasher, limb);
27762773 return hasher.final();
27772774 },
27782775
......@@ -2929,6 +2926,8 @@ pub const Key = union(enum) {
29292926 asBytes(&e.relocation) ++
29302927 asBytes(&e.is_const) ++ asBytes(&e.alignment) ++ asBytes(&e.@"addrspace") ++
29312928 asBytes(&e.zir_index) ++ &[1]u8{@intFromEnum(e.source)}),
2929
2930 .bitpack => |bitpack| Hash.hash(seed, asBytes(&bitpack.ty) ++ asBytes(&bitpack.backing_int_val)),
29322931 };
29332932 }
29342933
......@@ -3002,9 +3001,9 @@ pub const Key = union(enum) {
30023001 const b_info = b.enum_tag;
30033002 return std.meta.eql(a_info, b_info);
30043003 },
3005 .empty_enum_value => |a_info| {
3006 const b_info = b.empty_enum_value;
3007 return a_info == b_info;
3004 .bitpack => |a_info| {
3005 const b_info = b.bitpack;
3006 return a_info.ty == b_info.ty and a_info.backing_int_val == b_info.backing_int_val;
30083007 },
30093008
30103009 .variable => |a_info| {
......@@ -3102,27 +3101,16 @@ pub const Key = union(enum) {
31023101 .u64 => |bb| aa == bb,
31033102 .i64 => |bb| aa == bb,
31043103 .big_int => |bb| bb.orderAgainstScalar(aa) == .eq,
3105 .lazy_align, .lazy_size => false,
31063104 },
31073105 .i64 => |aa| switch (b_info.storage) {
31083106 .u64 => |bb| aa == bb,
31093107 .i64 => |bb| aa == bb,
31103108 .big_int => |bb| bb.orderAgainstScalar(aa) == .eq,
3111 .lazy_align, .lazy_size => false,
31123109 },
31133110 .big_int => |aa| switch (b_info.storage) {
31143111 .u64 => |bb| aa.orderAgainstScalar(bb) == .eq,
31153112 .i64 => |bb| aa.orderAgainstScalar(bb) == .eq,
31163113 .big_int => |bb| aa.eql(bb),
3117 .lazy_align, .lazy_size => false,
3118 },
3119 .lazy_align => |aa| switch (b_info.storage) {
3120 .u64, .i64, .big_int, .lazy_size => false,
3121 .lazy_align => |bb| aa == bb,
3122 },
3123 .lazy_size => |aa| switch (b_info.storage) {
3124 .u64, .i64, .big_int, .lazy_align => false,
3125 .lazy_size => |bb| aa == bb,
31263114 },
31273115 };
31283116 },
......@@ -3175,12 +3163,12 @@ pub const Key = union(enum) {
31753163 };
31763164 return std.mem.eql(u32, @ptrCast(a_captures), @ptrCast(b_captures));
31773165 },
3178 .generated_tag => |a_gt| return a_gt.union_type == b_info.generated_tag.union_type,
31793166 .reified => |a_r| {
31803167 const b_r = b_info.reified;
31813168 return a_r.zir_index == b_r.zir_index and
31823169 a_r.type_hash == b_r.type_hash;
31833170 },
3171 .generated_union_tag => |a_union_ty| return a_union_ty == b_info.generated_union_tag,
31843172 }
31853173 },
31863174 .aggregate => |a_info| {
......@@ -3292,19 +3280,17 @@ pub const Key = union(enum) {
32923280 .enum_tag,
32933281 .aggregate,
32943282 .un,
3283 .bitpack,
32953284 => |x| x.ty,
32963285
32973286 .enum_literal => .enum_literal_type,
32983287
32993288 .undef => |x| x,
3300 .empty_enum_value => |x| x,
33013289
33023290 .simple_value => |s| switch (s) {
3303 .undefined => .undefined_type,
33043291 .void => .void_type,
33053292 .null => .null_type,
33063293 .false, .true => .bool_type,
3307 .empty_tuple => .empty_tuple_type,
33083294 .@"unreachable" => .noreturn_type,
33093295 },
33103296
......@@ -3313,374 +3299,53 @@ pub const Key = union(enum) {
33133299 }
33143300};
33153301
3316pub const RequiresComptime = enum(u2) { no, yes, unknown, wip };
3317
3318// Unlike `Tag.TypeUnion` which is an encoding, and `Key.UnionType` which is a
3319// minimal hashmap key, this type is a convenience type that contains info
3320// needed by semantic analysis.
3321pub const LoadedUnionType = struct {
3322 tid: Zcu.PerThread.Id,
3323 /// The index of the `Tag.TypeUnion` payload.
3324 extra_index: u32,
3325 // TODO: the non-fqn will be needed by the new dwarf structure
3326 /// The name of this union type.
3327 name: NullTerminatedString,
3328 /// Represents the declarations inside this union.
3329 namespace: NamespaceIndex,
3330 /// If this is a declared type with the `.parent` name strategy, this is the `Nav` it was named after.
3331 /// Otherwise, this is `.none`.
3332 name_nav: Nav.Index.Optional,
3333 /// The enum tag type.
3334 enum_tag_ty: Index,
3335 /// List of field types in declaration order.
3336 /// These are `none` until `status` is `have_field_types` or `have_layout`.
3337 field_types: Index.Slice,
3338 /// List of field alignments in declaration order.
3339 /// `none` means the ABI alignment of the type.
3340 /// If this slice has length 0 it means all elements are `none`.
3341 field_aligns: Alignment.Slice,
3342 /// Index of the union_decl or reify ZIR instruction.
3302pub const LoadedStructType = struct {
3303 /// Index of the `struct_decl` or `reify` ZIR instruction.
33433304 zir_index: TrackedInst.Index,
33443305 captures: CaptureValue.Slice,
3306 is_reified: bool,
33453307
3346 pub const RuntimeTag = enum(u2) {
3347 none,
3348 safety,
3349 tagged,
3350
3351 pub fn hasTag(self: RuntimeTag) bool {
3352 return switch (self) {
3353 .none => false,
3354 .tagged, .safety => true,
3355 };
3356 }
3357 };
3358
3359 pub const Status = enum(u3) {
3360 none,
3361 field_types_wip,
3362 have_field_types,
3363 layout_wip,
3364 have_layout,
3365 fully_resolved_wip,
3366 /// The types and all its fields have had their layout resolved.
3367 /// Even through pointer, which `have_layout` does not ensure.
3368 fully_resolved,
3369
3370 pub fn haveFieldTypes(status: Status) bool {
3371 return switch (status) {
3372 .none,
3373 .field_types_wip,
3374 => false,
3375 .have_field_types,
3376 .layout_wip,
3377 .have_layout,
3378 .fully_resolved_wip,
3379 .fully_resolved,
3380 => true,
3381 };
3382 }
3383
3384 pub fn haveLayout(status: Status) bool {
3385 return switch (status) {
3386 .none,
3387 .field_types_wip,
3388 .have_field_types,
3389 .layout_wip,
3390 => false,
3391 .have_layout,
3392 .fully_resolved_wip,
3393 .fully_resolved,
3394 => true,
3395 };
3396 }
3397 };
3398
3399 pub fn loadTagType(self: LoadedUnionType, ip: *const InternPool) LoadedEnumType {
3400 return ip.loadEnumType(self.enum_tag_ty);
3401 }
3402
3403 /// Pointer to an enum type which is used for the tag of the union.
3404 /// This type is created even for untagged unions, even when the memory
3405 /// layout does not store the tag.
3406 /// Whether zig chooses this type or the user specifies it, it is stored here.
3407 /// This will be set to the null type until status is `have_field_types`.
3408 /// This accessor is provided so that the tag type can be mutated, and so that
3409 /// when it is mutated, the mutations are observed.
3410 /// The returned pointer expires with any addition to the `InternPool`.
3411 fn tagTypePtr(self: LoadedUnionType, ip: *const InternPool) *Index {
3412 const extra = ip.getLocalShared(self.tid).extra.acquire();
3413 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "tag_ty").?;
3414 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + field_index]);
3415 }
3416
3417 pub fn tagTypeUnordered(u: LoadedUnionType, ip: *const InternPool) Index {
3418 return @atomicLoad(Index, u.tagTypePtr(ip), .unordered);
3419 }
3420
3421 pub fn setTagType(u: LoadedUnionType, ip: *InternPool, io: Io, tag_type: Index) void {
3422 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
3423 extra_mutex.lockUncancelable(io);
3424 defer extra_mutex.unlock(io);
3425
3426 @atomicStore(Index, u.tagTypePtr(ip), tag_type, .release);
3427 }
3428
3429 /// The returned pointer expires with any addition to the `InternPool`.
3430 fn flagsPtr(self: LoadedUnionType, ip: *const InternPool) *Tag.TypeUnion.Flags {
3431 const extra = ip.getLocalShared(self.tid).extra.acquire();
3432 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "flags").?;
3433 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + field_index]);
3434 }
3435
3436 pub fn flagsUnordered(u: LoadedUnionType, ip: *const InternPool) Tag.TypeUnion.Flags {
3437 return @atomicLoad(Tag.TypeUnion.Flags, u.flagsPtr(ip), .unordered);
3438 }
3439
3440 pub fn setStatus(u: LoadedUnionType, ip: *InternPool, io: Io, status: Status) void {
3441 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
3442 extra_mutex.lockUncancelable(io);
3443 defer extra_mutex.unlock(io);
3444
3445 const flags_ptr = u.flagsPtr(ip);
3446 var flags = flags_ptr.*;
3447 flags.status = status;
3448 @atomicStore(Tag.TypeUnion.Flags, flags_ptr, flags, .release);
3449 }
3450
3451 pub fn setStatusIfLayoutWip(u: LoadedUnionType, ip: *InternPool, io: Io, status: Status) void {
3452 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
3453 extra_mutex.lockUncancelable(io);
3454 defer extra_mutex.unlock(io);
3455
3456 const flags_ptr = u.flagsPtr(ip);
3457 var flags = flags_ptr.*;
3458 if (flags.status == .layout_wip) flags.status = status;
3459 @atomicStore(Tag.TypeUnion.Flags, flags_ptr, flags, .release);
3460 }
3461
3462 pub fn setAlignment(u: LoadedUnionType, ip: *InternPool, io: Io, alignment: Alignment) void {
3463 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
3464 extra_mutex.lockUncancelable(io);
3465 defer extra_mutex.unlock(io);
3466
3467 const flags_ptr = u.flagsPtr(ip);
3468 var flags = flags_ptr.*;
3469 flags.alignment = alignment;
3470 @atomicStore(Tag.TypeUnion.Flags, flags_ptr, flags, .release);
3471 }
3472
3473 pub fn assumeRuntimeBitsIfFieldTypesWip(u: LoadedUnionType, ip: *InternPool, io: Io) bool {
3474 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
3475 extra_mutex.lockUncancelable(io);
3476 defer extra_mutex.unlock(io);
3477
3478 const flags_ptr = u.flagsPtr(ip);
3479 var flags = flags_ptr.*;
3480 defer if (flags.status == .field_types_wip) {
3481 flags.assumed_runtime_bits = true;
3482 @atomicStore(Tag.TypeUnion.Flags, flags_ptr, flags, .release);
3483 };
3484 return flags.status == .field_types_wip;
3485 }
3486
3487 pub fn requiresComptime(u: LoadedUnionType, ip: *const InternPool) RequiresComptime {
3488 return u.flagsUnordered(ip).requires_comptime;
3489 }
3490
3491 pub fn setRequiresComptimeWip(u: LoadedUnionType, ip: *InternPool, io: Io) RequiresComptime {
3492 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
3493 extra_mutex.lockUncancelable(io);
3494 defer extra_mutex.unlock(io);
3495
3496 const flags_ptr = u.flagsPtr(ip);
3497 var flags = flags_ptr.*;
3498 defer if (flags.requires_comptime == .unknown) {
3499 flags.requires_comptime = .wip;
3500 @atomicStore(Tag.TypeUnion.Flags, flags_ptr, flags, .release);
3501 };
3502 return flags.requires_comptime;
3503 }
3504
3505 pub fn setRequiresComptime(u: LoadedUnionType, ip: *InternPool, io: Io, requires_comptime: RequiresComptime) void {
3506 assert(requires_comptime != .wip); // see setRequiresComptimeWip
3507
3508 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
3509 extra_mutex.lockUncancelable(io);
3510 defer extra_mutex.unlock(io);
3511
3512 const flags_ptr = u.flagsPtr(ip);
3513 var flags = flags_ptr.*;
3514 flags.requires_comptime = requires_comptime;
3515 @atomicStore(Tag.TypeUnion.Flags, flags_ptr, flags, .release);
3516 }
3517
3518 pub fn assumePointerAlignedIfFieldTypesWip(u: LoadedUnionType, ip: *InternPool, io: Io, ptr_align: Alignment) bool {
3519 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
3520 extra_mutex.lockUncancelable(io);
3521 defer extra_mutex.unlock(io);
3522
3523 const flags_ptr = u.flagsPtr(ip);
3524 var flags = flags_ptr.*;
3525 defer if (flags.status == .field_types_wip) {
3526 flags.alignment = ptr_align;
3527 flags.assumed_pointer_aligned = true;
3528 @atomicStore(Tag.TypeUnion.Flags, flags_ptr, flags, .release);
3529 };
3530 return flags.status == .field_types_wip;
3531 }
3532
3533 /// The returned pointer expires with any addition to the `InternPool`.
3534 fn sizePtr(self: LoadedUnionType, ip: *const InternPool) *u32 {
3535 const extra = ip.getLocalShared(self.tid).extra.acquire();
3536 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "size").?;
3537 return &extra.view().items(.@"0")[self.extra_index + field_index];
3538 }
3539
3540 pub fn sizeUnordered(u: LoadedUnionType, ip: *const InternPool) u32 {
3541 return @atomicLoad(u32, u.sizePtr(ip), .unordered);
3542 }
3543
3544 /// The returned pointer expires with any addition to the `InternPool`.
3545 fn paddingPtr(self: LoadedUnionType, ip: *const InternPool) *u32 {
3546 const extra = ip.getLocalShared(self.tid).extra.acquire();
3547 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "padding").?;
3548 return &extra.view().items(.@"0")[self.extra_index + field_index];
3549 }
3550
3551 pub fn paddingUnordered(u: LoadedUnionType, ip: *const InternPool) u32 {
3552 return @atomicLoad(u32, u.paddingPtr(ip), .unordered);
3553 }
3554
3555 pub fn hasTag(self: LoadedUnionType, ip: *const InternPool) bool {
3556 return self.flagsUnordered(ip).runtime_tag.hasTag();
3557 }
3558
3559 pub fn haveFieldTypes(self: LoadedUnionType, ip: *const InternPool) bool {
3560 return self.flagsUnordered(ip).status.haveFieldTypes();
3561 }
3562
3563 pub fn haveLayout(self: LoadedUnionType, ip: *const InternPool) bool {
3564 return self.flagsUnordered(ip).status.haveLayout();
3565 }
3566
3567 pub fn setHaveLayout(u: LoadedUnionType, ip: *InternPool, io: Io, size: u32, padding: u32, alignment: Alignment) void {
3568 const extra_mutex = &ip.getLocal(u.tid).mutate.extra.mutex;
3569 extra_mutex.lockUncancelable(io);
3570 defer extra_mutex.unlock(io);
3571
3572 @atomicStore(u32, u.sizePtr(ip), size, .unordered);
3573 @atomicStore(u32, u.paddingPtr(ip), padding, .unordered);
3574 const flags_ptr = u.flagsPtr(ip);
3575 var flags = flags_ptr.*;
3576 flags.alignment = alignment;
3577 flags.status = .have_layout;
3578 @atomicStore(Tag.TypeUnion.Flags, flags_ptr, flags, .release);
3579 }
3580
3581 pub fn fieldAlign(self: LoadedUnionType, ip: *const InternPool, field_index: usize) Alignment {
3582 if (self.field_aligns.len == 0) return .none;
3583 return self.field_aligns.get(ip)[field_index];
3584 }
3585
3586 /// This does not mutate the field of LoadedUnionType.
3587 pub fn setZirIndex(self: LoadedUnionType, ip: *InternPool, new_zir_index: TrackedInst.Index.Optional) void {
3588 const flags_field_index = std.meta.fieldIndex(Tag.TypeUnion, "flags").?;
3589 const zir_index_field_index = std.meta.fieldIndex(Tag.TypeUnion, "zir_index").?;
3590 const ptr: *TrackedInst.Index.Optional =
3591 @ptrCast(&ip.extra_.items[self.flags_index - flags_field_index + zir_index_field_index]);
3592 ptr.* = new_zir_index;
3593 }
3594
3595 pub fn setFieldTypes(self: LoadedUnionType, ip: *const InternPool, types: []const Index) void {
3596 @memcpy(self.field_types.get(ip), types);
3597 }
3598
3599 pub fn setFieldAligns(self: LoadedUnionType, ip: *const InternPool, aligns: []const Alignment) void {
3600 if (aligns.len == 0) return;
3601 assert(self.flagsUnordered(ip).any_aligned_fields);
3602 @memcpy(self.field_aligns.get(ip), aligns);
3603 }
3604};
3605
3606pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
3607 const unwrapped_index = index.unwrap(ip);
3608 const extra_list = unwrapped_index.getExtra(ip);
3609 const data = unwrapped_index.getData(ip);
3610 const type_union = extraDataTrail(extra_list, Tag.TypeUnion, data);
3611 const fields_len = type_union.data.fields_len;
3612
3613 var extra_index = type_union.end;
3614 const captures_len = if (type_union.data.flags.any_captures) c: {
3615 const len = extra_list.view().items(.@"0")[extra_index];
3616 extra_index += 1;
3617 break :c len;
3618 } else 0;
3619
3620 const captures: CaptureValue.Slice = .{
3621 .tid = unwrapped_index.tid,
3622 .start = extra_index,
3623 .len = captures_len,
3624 };
3625 extra_index += captures_len;
3626 if (type_union.data.flags.is_reified) {
3627 extra_index += 2; // PackedU64
3628 }
3629
3630 const field_types: Index.Slice = .{
3631 .tid = unwrapped_index.tid,
3632 .start = extra_index,
3633 .len = fields_len,
3634 };
3635 extra_index += fields_len;
3636
3637 const field_aligns = if (type_union.data.flags.any_aligned_fields) a: {
3638 const a: Alignment.Slice = .{
3639 .tid = unwrapped_index.tid,
3640 .start = extra_index,
3641 .len = fields_len,
3642 };
3643 extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable;
3644 break :a a;
3645 } else Alignment.Slice.empty;
3646
3647 return .{
3648 .tid = unwrapped_index.tid,
3649 .extra_index = data,
3650 .name = type_union.data.name,
3651 .name_nav = type_union.data.name_nav,
3652 .namespace = type_union.data.namespace,
3653 .enum_tag_ty = type_union.data.tag_ty,
3654 .field_types = field_types,
3655 .field_aligns = field_aligns,
3656 .zir_index = type_union.data.zir_index,
3657 .captures = captures,
3658 };
3659}
3660
3661pub const LoadedStructType = struct {
3662 tid: Zcu.PerThread.Id,
3663 /// The index of the `Tag.TypeStruct` or `Tag.TypeStructPacked` payload.
3664 extra_index: u32,
36653308 // TODO: the non-fqn will be needed by the new dwarf structure
36663309 /// The name of this struct type.
36673310 name: NullTerminatedString,
3668 namespace: NamespaceIndex,
36693311 /// If this is a declared type with the `.parent` name strategy, this is the `Nav` it was named after.
36703312 /// Otherwise, or if this is a file's root struct type, this is `.none`.
36713313 name_nav: Nav.Index.Optional,
3672 /// Index of the `struct_decl` or `reify` ZIR instruction.
3673 zir_index: TrackedInst.Index,
3314 namespace: NamespaceIndex,
3315
36743316 layout: std.builtin.Type.ContainerLayout,
3317 /// May be `undefined` if `layout != .@"packed"`.
3318 packed_backing_mode: BackingTypeMode,
3319
3320 /// Initially `false`, and set to `true` once any dependency on or reference to the struct's
3321 /// layout is encountered, after which it is never reset to `false`, even across incremental
3322 /// updates.
3323 ///
3324 /// This field is purely an optimization to avoid resolving the layout of types whose layouts
3325 /// are never demanded. If this field is `true` but the layout is not actually needed, the
3326 /// compiler frontend resolves this by traversing the reference graph at the end of each update
3327 /// with `Zcu.resolveReferences` and hiding compile errors which arise from this analysis.
3328 want_layout: bool,
3329
3330 // The remaining fields are only valid once the struct's layout is resolved.
3331 field_name_map: MapIndex,
36753332 field_names: NullTerminatedString.Slice,
36763333 field_types: Index.Slice,
3677 field_inits: Index.Slice,
3334 field_defaults: Index.Slice,
36783335 field_aligns: Alignment.Slice,
3679 runtime_order: RuntimeOrder.Slice,
3680 comptime_bits: ComptimeBits,
3681 offsets: Offsets,
3682 names_map: OptionalMapIndex,
3683 captures: CaptureValue.Slice,
3336 field_is_comptime_bits: ComptimeBits,
3337 /// If `layout` is `.@"packed"`, this is `.empty`.
3338 field_runtime_order: RuntimeOrder.Slice,
3339 /// If `layout` is `.@"packed"`, this is `.empty`.
3340 field_offsets: Offsets,
3341 /// Only valid if `layout` is `.@"packed"`.
3342 packed_backing_int_type: Index,
3343 /// Only valid if `layout` is *not* `.@"packed"`.
3344 class: TypeClass,
3345 /// Only valid if `layout` is *not* `.@"packed"`.
3346 size: u32,
3347 /// Only valid if `layout` is *not* `.@"packed"`.
3348 alignment: Alignment,
36843349
36853350 pub const ComptimeBits = struct {
36863351 tid: Zcu.PerThread.Id,
......@@ -3690,22 +3355,14 @@ pub const LoadedStructType = struct {
36903355
36913356 pub const empty: ComptimeBits = .{ .tid = .main, .start = 0, .len = 0 };
36923357
3693 pub fn get(this: ComptimeBits, ip: *const InternPool) []u32 {
3358 pub fn getAll(this: ComptimeBits, ip: *const InternPool) []u32 {
36943359 const extra = ip.getLocalShared(this.tid).extra.acquire();
36953360 return extra.view().items(.@"0")[this.start..][0..this.len];
36963361 }
36973362
3698 pub fn getBit(this: ComptimeBits, ip: *const InternPool, i: usize) bool {
3363 pub fn get(this: ComptimeBits, ip: *const InternPool, i: usize) bool {
36993364 if (this.len == 0) return false;
3700 return @as(u1, @truncate(this.get(ip)[i / 32] >> @intCast(i % 32))) != 0;
3701 }
3702
3703 pub fn setBit(this: ComptimeBits, ip: *const InternPool, i: usize) void {
3704 this.get(ip)[i / 32] |= @as(u32, 1) << @intCast(i % 32);
3705 }
3706
3707 pub fn clearBit(this: ComptimeBits, ip: *const InternPool, i: usize) void {
3708 this.get(ip)[i / 32] &= ~(@as(u32, 1) << @intCast(i % 32));
3365 return @as(u1, @truncate(this.getAll(ip)[i / 32] >> @intCast(i % 32))) != 0;
37093366 }
37103367 };
37113368
......@@ -3753,865 +3410,602 @@ pub const LoadedStructType = struct {
37533410
37543411 /// Look up field index based on field name.
37553412 pub fn nameIndex(s: LoadedStructType, ip: *const InternPool, name: NullTerminatedString) ?u32 {
3756 const names_map = s.names_map.unwrap() orelse {
3757 const i = name.toUnsigned(ip) orelse return null;
3758 if (i >= s.field_types.len) return null;
3759 return i;
3760 };
3761 const map = names_map.get(ip);
3413 const map = s.field_name_map.get(ip);
37623414 const adapter: NullTerminatedString.Adapter = .{ .strings = s.field_names.get(ip) };
37633415 const field_index = map.getIndexAdapted(name, adapter) orelse return null;
37643416 return @intCast(field_index);
37653417 }
37663418
3767 /// Returns the already-existing field with the same name, if any.
3768 pub fn addFieldName(
3769 s: LoadedStructType,
3770 ip: *InternPool,
3771 name: NullTerminatedString,
3772 ) ?u32 {
3773 const extra = ip.getLocalShared(s.tid).extra.acquire();
3774 return ip.addFieldName(extra, s.names_map.unwrap().?, s.field_names.start, name);
3419 /// Iterates over non-comptime fields in the order they are laid out in memory at runtime.
3420 /// May or may not include zero-bit fields.
3421 /// Asserts the struct is not packed.
3422 pub fn iterateRuntimeOrder(s: *const LoadedStructType, ip: *const InternPool) RuntimeOrderIterator {
3423 switch (s.layout) {
3424 .auto => {
3425 const ro = std.mem.sliceTo(s.field_runtime_order.get(ip), .omitted);
3426 return .{
3427 .runtime_order = ro,
3428 .fields_len = @intCast(ro.len),
3429 .next_index = 0,
3430 };
3431 },
3432 .@"extern" => return .{
3433 .runtime_order = null,
3434 .fields_len = s.field_names.len,
3435 .next_index = 0,
3436 },
3437 .@"packed" => unreachable,
3438 }
37753439 }
3440 pub const RuntimeOrderIterator = struct {
3441 runtime_order: ?[]const RuntimeOrder,
3442 fields_len: u32,
3443 next_index: u32,
3444 pub fn next(it: *RuntimeOrderIterator) ?u32 {
3445 const i = it.next_index;
3446 if (i == it.fields_len) return null;
3447 it.next_index = i + 1;
3448 const ro = it.runtime_order orelse return i;
3449 return ro[i].toInt().?;
3450 }
3451 };
37763452
3777 pub fn fieldAlign(s: LoadedStructType, ip: *const InternPool, i: usize) Alignment {
3778 if (s.field_aligns.len == 0) return .none;
3779 return s.field_aligns.get(ip)[i];
3453 pub fn iterateRuntimeOrderReverse(s: *const LoadedStructType, ip: *InternPool) ReverseRuntimeOrderIterator {
3454 switch (s.layout) {
3455 .auto => {
3456 const ro = std.mem.sliceTo(s.field_runtime_order.get(ip), .omitted);
3457 return .{
3458 .runtime_order = ro,
3459 .last_index = @intCast(ro.len),
3460 };
3461 },
3462 .@"extern" => return .{
3463 .runtime_order = null,
3464 .last_index = s.field_names.len,
3465 },
3466 .@"packed" => unreachable,
3467 }
37803468 }
3469 pub const ReverseRuntimeOrderIterator = struct {
3470 runtime_order: ?[]const RuntimeOrder,
3471 last_index: u32,
3472 pub fn next(it: *ReverseRuntimeOrderIterator) ?u32 {
3473 if (it.last_index == 0) return null;
3474 const i = it.last_index - 1;
3475 it.last_index = i;
3476 const ro = it.runtime_order orelse return i;
3477 return ro[i].toInt().?;
3478 }
3479 };
3480};
37813481
3782 pub fn fieldInit(s: LoadedStructType, ip: *const InternPool, i: usize) Index {
3783 if (s.field_inits.len == 0) return .none;
3784 assert(s.haveFieldInits(ip));
3785 return s.field_inits.get(ip)[i];
3786 }
3482/// Unlike `Tag.TypeUnion` which is an encoding, and `Key.UnionType` which is a
3483/// minimal hashmap key, this type is a convenience type that contains info
3484/// needed by semantic analysis.
3485pub const LoadedUnionType = struct {
3486 /// Index of the `union_decl` or `reify` ZIR instruction.
3487 zir_index: TrackedInst.Index,
3488 captures: CaptureValue.Slice,
3489 is_reified: bool,
37873490
3788 pub fn fieldName(s: LoadedStructType, ip: *const InternPool, i: usize) NullTerminatedString {
3789 return s.field_names.get(ip)[i];
3790 }
3491 // TODO: the non-fqn will be needed by the new dwarf structure
3492 /// The name of this union type.
3493 name: NullTerminatedString,
3494 /// If this is a declared type with the `.parent` name strategy, this is the `Nav` it was named after.
3495 /// Otherwise, this is `.none`.
3496 name_nav: Nav.Index.Optional,
3497 namespace: NamespaceIndex,
37913498
3792 pub fn fieldIsComptime(s: LoadedStructType, ip: *const InternPool, i: usize) bool {
3793 return s.comptime_bits.getBit(ip, i);
3794 }
3499 layout: std.builtin.Type.ContainerLayout,
3500 enum_tag_mode: BackingTypeMode,
3501 /// May be `undefined` if `layout != .@"packed"`.
3502 packed_backing_mode: BackingTypeMode,
3503
3504 /// Only reified unions store field names; typically they should be loaded from `enum_tag_type`
3505 /// instead. Reified unions store them because type resolution needs them in order to validate
3506 /// or populate `enum_tag_type`.
3507 reified_field_names: NullTerminatedString.Slice,
3508
3509 /// Initially `false`, and set to `true` once any dependency on or reference to the struct's
3510 /// layout is encountered, after which it is never reset to `false`, even across incremental
3511 /// updates.
3512 ///
3513 /// This field is purely an optimization to avoid resolving the layout of types whose layouts
3514 /// are never demanded. If this field is `true` but the layout is not actually needed, the
3515 /// compiler frontend resolves this by traversing the reference graph at the end of each update
3516 /// with `Zcu.resolveReferences` and hiding compile errors which arise from this analysis.
3517 want_layout: bool,
37953518
3796 pub fn setFieldComptime(s: LoadedStructType, ip: *InternPool, i: usize) void {
3797 s.comptime_bits.setBit(ip, i);
3798 }
3519 // The remaining fields are only valid once the union's layout is resolved.
3520 field_types: Index.Slice,
3521 field_aligns: Alignment.Slice,
3522 tag_usage: TagUsage,
3523 /// While `tag_usage` indicates whether the union should logically contain a tag, it may be
3524 /// omitted if the union layout is resolved as OPV or NPV. This field is `true` iff there is an
3525 /// actual runtime tag, with one or more runtime bits, in the union layout. It is always `false`
3526 /// if `layout` is not `.auto`.
3527 has_runtime_tag: bool,
3528 /// Even if `tag_usage == .none` and `has_runtime_tag == false`, this is still populated with
3529 /// the union's "hypothetical" tag type.
3530 enum_tag_type: Index,
3531 /// Only valid if `layout` is `.@"packed"`.
3532 packed_backing_int_type: Index,
3533 /// Not valid if `layout` is `.@"packed"`.
3534 class: TypeClass,
3535 /// Not valid if `layout` is `.@"packed"`.
3536 size: u32,
3537 /// Not valid if `layout` is `.@"packed"`.
3538 padding: u32,
3539 /// Not valid if `layout` is `.@"packed"`.
3540 alignment: Alignment,
3541
3542 pub const TagUsage = enum(u2) {
3543 none,
3544 safety,
3545 tagged,
3546 };
3547};
37993548
3800 /// The returned pointer expires with any addition to the `InternPool`.
3801 /// Asserts the struct is not packed.
3802 fn flagsPtr(s: LoadedStructType, ip: *const InternPool) *Tag.TypeStruct.Flags {
3803 assert(s.layout != .@"packed");
3804 const extra = ip.getLocalShared(s.tid).extra.acquire();
3805 const flags_field_index = std.meta.fieldIndex(Tag.TypeStruct, "flags").?;
3806 return @ptrCast(&extra.view().items(.@"0")[s.extra_index + flags_field_index]);
3807 }
3549pub const LoadedEnumType = struct {
3550 /// This is `none` iff this is a generated tag type.
3551 /// Otherwise, index of the `enum_decl` or `reify` ZIR instruction.
3552 zir_index: TrackedInst.Index.Optional,
3553 captures: CaptureValue.Slice,
3554 /// If `zir_index` is `.none`, this is the union type for which this enum is the tag type.
3555 owner_union: Index,
3556 is_reified: bool,
38083557
3809 pub fn flagsUnordered(s: LoadedStructType, ip: *const InternPool) Tag.TypeStruct.Flags {
3810 return @atomicLoad(Tag.TypeStruct.Flags, s.flagsPtr(ip), .unordered);
3811 }
3558 // TODO: the non-fqn will be needed by the new dwarf structure
3559 /// The name of this enum type.
3560 name: NullTerminatedString,
3561 /// If this is a declared type with the `.parent` name strategy, this is the `Nav` it was named after.
3562 /// Otherwise, this is `.none`.
3563 name_nav: Nav.Index.Optional,
3564 namespace: NamespaceIndex,
38123565
3813 /// The returned pointer expires with any addition to the `InternPool`.
3814 /// Asserts that the struct is packed.
3815 fn packedFlagsPtr(s: LoadedStructType, ip: *const InternPool) *Tag.TypeStructPacked.Flags {
3816 assert(s.layout == .@"packed");
3817 const extra = ip.getLocalShared(s.tid).extra.acquire();
3818 const flags_field_index = std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?;
3819 return @ptrCast(&extra.view().items(.@"0")[s.extra_index + flags_field_index]);
3820 }
3566 int_tag_mode: BackingTypeMode,
3567 nonexhaustive: bool,
38213568
3822 pub fn packedFlagsUnordered(s: LoadedStructType, ip: *const InternPool) Tag.TypeStructPacked.Flags {
3823 return @atomicLoad(Tag.TypeStructPacked.Flags, s.packedFlagsPtr(ip), .unordered);
3824 }
3569 /// Initially `false`, and set to `true` once any dependency on or reference to the struct's
3570 /// layout is encountered, after which it is never reset to `false`, even across incremental
3571 /// updates.
3572 ///
3573 /// This field is purely an optimization to avoid resolving the layout of types whose layouts
3574 /// are never demanded. If this field is `true` but the layout is not actually needed, the
3575 /// compiler frontend resolves this by traversing the reference graph at the end of each update
3576 /// with `Zcu.resolveReferences` and hiding compile errors which arise from this analysis.
3577 want_layout: bool,
38253578
3826 /// Reads the non-opv flag calculated during AstGen. Used to short-circuit more
3827 /// complicated logic.
3828 pub fn knownNonOpv(s: LoadedStructType, ip: *const InternPool) bool {
3829 return switch (s.layout) {
3830 .@"packed" => false,
3831 .auto, .@"extern" => s.flagsUnordered(ip).known_non_opv,
3832 };
3833 }
3579 // The remaining fields are only valid once the enum's layout is resolved.
3580 int_tag_type: Index,
3581 field_name_map: MapIndex,
3582 field_names: NullTerminatedString.Slice,
3583 field_value_map: OptionalMapIndex,
3584 field_values: Index.Slice,
38343585
3835 pub fn requiresComptime(s: LoadedStructType, ip: *const InternPool) RequiresComptime {
3836 return s.flagsUnordered(ip).requires_comptime;
3586 /// Look up field index based on field name.
3587 pub fn nameIndex(e: LoadedEnumType, ip: *const InternPool, name: NullTerminatedString) ?u32 {
3588 const map = e.field_name_map.get(ip);
3589 const adapter: NullTerminatedString.Adapter = .{ .strings = e.field_names.get(ip) };
3590 const field_index = map.getIndexAdapted(name, adapter) orelse return null;
3591 return @intCast(field_index);
38373592 }
38383593
3839 pub fn setRequiresComptimeWip(s: LoadedStructType, ip: *InternPool, io: Io) RequiresComptime {
3840 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3841 extra_mutex.lockUncancelable(io);
3842 defer extra_mutex.unlock(io);
3843
3844 const flags_ptr = s.flagsPtr(ip);
3845 var flags = flags_ptr.*;
3846 defer if (flags.requires_comptime == .unknown) {
3847 flags.requires_comptime = .wip;
3848 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3594 /// Look up field index based on integer tag value.
3595 /// Asserts that the type of `tag_val` is `enum_obj.int_tag_type`.
3596 /// Asserts that `tag_val` is not `undefined`.
3597 pub fn tagValueIndex(e: LoadedEnumType, ip: *const InternPool, tag_val: Index) ?u32 {
3598 assert(ip.typeOf(tag_val) == e.int_tag_type);
3599 assert(ip.indexToKey(tag_val) == .int);
3600 if (e.field_value_map.unwrap()) |field_value_map| {
3601 const map = field_value_map.get(ip);
3602 const adapter: Index.Adapter = .{ .indexes = e.field_values.get(ip) };
3603 const field_index = map.getIndexAdapted(tag_val, adapter) orelse return null;
3604 return @intCast(field_index);
3605 }
3606 // Auto-numbered enum, so convert `tag_val` to field index
3607 const field_index = switch (ip.indexToKey(tag_val).int.storage) {
3608 inline .u64, .i64 => |x| std.math.cast(u32, x) orelse return null,
3609 .big_int => |x| x.toInt(u32) catch return null,
38493610 };
3850 return flags.requires_comptime;
3611 return if (field_index < e.field_names.len) field_index else null;
38513612 }
3613};
38523614
3853 pub fn setRequiresComptime(s: LoadedStructType, ip: *InternPool, io: Io, requires_comptime: RequiresComptime) void {
3854 assert(requires_comptime != .wip); // see setRequiresComptimeWip
3615pub const LoadedOpaqueType = struct {
3616 /// Index of the `opaque_decl` instruction.
3617 zir_index: TrackedInst.Index,
3618 captures: CaptureValue.Slice,
38553619
3856 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3857 extra_mutex.lockUncancelable(io);
3858 defer extra_mutex.unlock(io);
3859
3860 const flags_ptr = s.flagsPtr(ip);
3861 var flags = flags_ptr.*;
3862 flags.requires_comptime = requires_comptime;
3863 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3864 }
3865
3866 pub fn assumeRuntimeBitsIfFieldTypesWip(s: LoadedStructType, ip: *InternPool, io: Io) bool {
3867 if (s.layout == .@"packed") return false;
3868
3869 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3870 extra_mutex.lockUncancelable(io);
3871 defer extra_mutex.unlock(io);
3872
3873 const flags_ptr = s.flagsPtr(ip);
3874 var flags = flags_ptr.*;
3875 defer if (flags.field_types_wip) {
3876 flags.assumed_runtime_bits = true;
3877 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3878 };
3879 return flags.field_types_wip;
3880 }
3881
3882 pub fn setFieldTypesWip(s: LoadedStructType, ip: *InternPool, io: Io) bool {
3883 if (s.layout == .@"packed") return false;
3884
3885 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3886 extra_mutex.lockUncancelable(io);
3887 defer extra_mutex.unlock(io);
3888
3889 const flags_ptr = s.flagsPtr(ip);
3890 var flags = flags_ptr.*;
3891 defer {
3892 flags.field_types_wip = true;
3893 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3894 }
3895 return flags.field_types_wip;
3896 }
3897
3898 pub fn clearFieldTypesWip(s: LoadedStructType, ip: *InternPool, io: Io) void {
3899 if (s.layout == .@"packed") return;
3900
3901 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3902 extra_mutex.lockUncancelable(io);
3903 defer extra_mutex.unlock(io);
3904
3905 const flags_ptr = s.flagsPtr(ip);
3906 var flags = flags_ptr.*;
3907 flags.field_types_wip = false;
3908 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3909 }
3910
3911 pub fn setLayoutWip(s: LoadedStructType, ip: *InternPool, io: Io) bool {
3912 if (s.layout == .@"packed") return false;
3913
3914 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3915 extra_mutex.lockUncancelable(io);
3916 defer extra_mutex.unlock(io);
3917
3918 const flags_ptr = s.flagsPtr(ip);
3919 var flags = flags_ptr.*;
3920 defer {
3921 flags.layout_wip = true;
3922 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3923 }
3924 return flags.layout_wip;
3925 }
3926
3927 pub fn clearLayoutWip(s: LoadedStructType, ip: *InternPool, io: Io) void {
3928 if (s.layout == .@"packed") return;
3929
3930 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3931 extra_mutex.lockUncancelable(io);
3932 defer extra_mutex.unlock(io);
3933
3934 const flags_ptr = s.flagsPtr(ip);
3935 var flags = flags_ptr.*;
3936 flags.layout_wip = false;
3937 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3938 }
3939
3940 pub fn setAlignment(s: LoadedStructType, ip: *InternPool, io: Io, alignment: Alignment) void {
3941 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3942 extra_mutex.lockUncancelable(io);
3943 defer extra_mutex.unlock(io);
3944
3945 const flags_ptr = s.flagsPtr(ip);
3946 var flags = flags_ptr.*;
3947 flags.alignment = alignment;
3948 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3949 }
3950
3951 pub fn assumePointerAlignedIfFieldTypesWip(s: LoadedStructType, ip: *InternPool, io: Io, ptr_align: Alignment) bool {
3952 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3953 extra_mutex.lockUncancelable(io);
3954 defer extra_mutex.unlock(io);
3955
3956 const flags_ptr = s.flagsPtr(ip);
3957 var flags = flags_ptr.*;
3958 defer if (flags.field_types_wip) {
3959 flags.alignment = ptr_align;
3960 flags.assumed_pointer_aligned = true;
3961 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3962 };
3963 return flags.field_types_wip;
3964 }
3965
3966 pub fn assumePointerAlignedIfWip(s: LoadedStructType, ip: *InternPool, io: Io, ptr_align: Alignment) bool {
3967 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3968 extra_mutex.lockUncancelable(io);
3969 defer extra_mutex.unlock(io);
3970
3971 const flags_ptr = s.flagsPtr(ip);
3972 var flags = flags_ptr.*;
3973 defer {
3974 if (flags.alignment_wip) {
3975 flags.alignment = ptr_align;
3976 flags.assumed_pointer_aligned = true;
3977 } else flags.alignment_wip = true;
3978 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3979 }
3980 return flags.alignment_wip;
3981 }
3982
3983 pub fn clearAlignmentWip(s: LoadedStructType, ip: *InternPool, io: Io) void {
3984 if (s.layout == .@"packed") return;
3985
3986 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3987 extra_mutex.lockUncancelable(io);
3988 defer extra_mutex.unlock(io);
3989
3990 const flags_ptr = s.flagsPtr(ip);
3991 var flags = flags_ptr.*;
3992 flags.alignment_wip = false;
3993 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
3994 }
3995
3996 pub fn setInitsWip(s: LoadedStructType, ip: *InternPool, io: Io) bool {
3997 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
3998 extra_mutex.lockUncancelable(io);
3999 defer extra_mutex.unlock(io);
4000
4001 switch (s.layout) {
4002 .@"packed" => {
4003 const flags_ptr = s.packedFlagsPtr(ip);
4004 var flags = flags_ptr.*;
4005 defer {
4006 flags.field_inits_wip = true;
4007 @atomicStore(Tag.TypeStructPacked.Flags, flags_ptr, flags, .release);
4008 }
4009 return flags.field_inits_wip;
4010 },
4011 .auto, .@"extern" => {
4012 const flags_ptr = s.flagsPtr(ip);
4013 var flags = flags_ptr.*;
4014 defer {
4015 flags.field_inits_wip = true;
4016 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
4017 }
4018 return flags.field_inits_wip;
4019 },
4020 }
4021 }
4022
4023 pub fn clearInitsWip(s: LoadedStructType, ip: *InternPool, io: Io) void {
4024 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
4025 extra_mutex.lockUncancelable(io);
4026 defer extra_mutex.unlock(io);
4027
4028 switch (s.layout) {
4029 .@"packed" => {
4030 const flags_ptr = s.packedFlagsPtr(ip);
4031 var flags = flags_ptr.*;
4032 flags.field_inits_wip = false;
4033 @atomicStore(Tag.TypeStructPacked.Flags, flags_ptr, flags, .release);
4034 },
4035 .auto, .@"extern" => {
4036 const flags_ptr = s.flagsPtr(ip);
4037 var flags = flags_ptr.*;
4038 flags.field_inits_wip = false;
4039 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
4040 },
4041 }
4042 }
4043
4044 pub fn setFullyResolved(s: LoadedStructType, ip: *InternPool, io: Io) bool {
4045 if (s.layout == .@"packed") return true;
4046
4047 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
4048 extra_mutex.lockUncancelable(io);
4049 defer extra_mutex.unlock(io);
4050
4051 const flags_ptr = s.flagsPtr(ip);
4052 var flags = flags_ptr.*;
4053 defer {
4054 flags.fully_resolved = true;
4055 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
4056 }
4057 return flags.fully_resolved;
4058 }
4059
4060 pub fn clearFullyResolved(s: LoadedStructType, ip: *InternPool, io: Io) void {
4061 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
4062 extra_mutex.lockUncancelable(io);
4063 defer extra_mutex.unlock(io);
4064
4065 const flags_ptr = s.flagsPtr(ip);
4066 var flags = flags_ptr.*;
4067 flags.fully_resolved = false;
4068 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
4069 }
4070
4071 /// The returned pointer expires with any addition to the `InternPool`.
4072 /// Asserts the struct is not packed.
4073 fn sizePtr(s: LoadedStructType, ip: *const InternPool) *u32 {
4074 assert(s.layout != .@"packed");
4075 const extra = ip.getLocalShared(s.tid).extra.acquire();
4076 const size_field_index = std.meta.fieldIndex(Tag.TypeStruct, "size").?;
4077 return @ptrCast(&extra.view().items(.@"0")[s.extra_index + size_field_index]);
4078 }
4079
4080 pub fn sizeUnordered(s: LoadedStructType, ip: *const InternPool) u32 {
4081 return @atomicLoad(u32, s.sizePtr(ip), .unordered);
4082 }
4083
4084 /// The backing integer type of the packed struct. Whether zig chooses
4085 /// this type or the user specifies it, it is stored here. This will be
4086 /// set to `none` until the layout is resolved.
4087 /// Asserts the struct is packed.
4088 fn backingIntTypePtr(s: LoadedStructType, ip: *const InternPool) *Index {
4089 assert(s.layout == .@"packed");
4090 const extra = ip.getLocalShared(s.tid).extra.acquire();
4091 const field_index = std.meta.fieldIndex(Tag.TypeStructPacked, "backing_int_ty").?;
4092 return @ptrCast(&extra.view().items(.@"0")[s.extra_index + field_index]);
4093 }
4094
4095 pub fn backingIntTypeUnordered(s: LoadedStructType, ip: *const InternPool) Index {
4096 return @atomicLoad(Index, s.backingIntTypePtr(ip), .unordered);
4097 }
4098
4099 pub fn setBackingIntType(s: LoadedStructType, ip: *InternPool, io: Io, backing_int_ty: Index) void {
4100 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
4101 extra_mutex.lockUncancelable(io);
4102 defer extra_mutex.unlock(io);
4103
4104 @atomicStore(Index, s.backingIntTypePtr(ip), backing_int_ty, .release);
4105 }
4106
4107 /// Asserts the struct is not packed.
4108 pub fn setZirIndex(s: LoadedStructType, ip: *InternPool, new_zir_index: TrackedInst.Index.Optional) void {
4109 assert(s.layout != .@"packed");
4110 const field_index = std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?;
4111 ip.extra_.items[s.extra_index + field_index] = @intFromEnum(new_zir_index);
4112 }
4113
4114 pub fn haveFieldTypes(s: LoadedStructType, ip: *const InternPool) bool {
4115 const types = s.field_types.get(ip);
4116 return types.len == 0 or types[types.len - 1] != .none;
4117 }
4118
4119 pub fn haveFieldInits(s: LoadedStructType, ip: *const InternPool) bool {
4120 return switch (s.layout) {
4121 .@"packed" => s.packedFlagsUnordered(ip).inits_resolved,
4122 .auto, .@"extern" => s.flagsUnordered(ip).inits_resolved,
4123 };
4124 }
4125
4126 pub fn setHaveFieldInits(s: LoadedStructType, ip: *InternPool, io: Io) void {
4127 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
4128 extra_mutex.lockUncancelable(io);
4129 defer extra_mutex.unlock(io);
4130
4131 switch (s.layout) {
4132 .@"packed" => {
4133 const flags_ptr = s.packedFlagsPtr(ip);
4134 var flags = flags_ptr.*;
4135 flags.inits_resolved = true;
4136 @atomicStore(Tag.TypeStructPacked.Flags, flags_ptr, flags, .release);
4137 },
4138 .auto, .@"extern" => {
4139 const flags_ptr = s.flagsPtr(ip);
4140 var flags = flags_ptr.*;
4141 flags.inits_resolved = true;
4142 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
4143 },
4144 }
4145 }
4146
4147 pub fn haveLayout(s: LoadedStructType, ip: *const InternPool) bool {
4148 return switch (s.layout) {
4149 .@"packed" => s.backingIntTypeUnordered(ip) != .none,
4150 .auto, .@"extern" => s.flagsUnordered(ip).layout_resolved,
4151 };
4152 }
4153
4154 pub fn setLayoutResolved(s: LoadedStructType, ip: *InternPool, io: Io, size: u32, alignment: Alignment) void {
4155 const extra_mutex = &ip.getLocal(s.tid).mutate.extra.mutex;
4156 extra_mutex.lockUncancelable(io);
4157 defer extra_mutex.unlock(io);
4158
4159 @atomicStore(u32, s.sizePtr(ip), size, .unordered);
4160 const flags_ptr = s.flagsPtr(ip);
4161 var flags = flags_ptr.*;
4162 flags.alignment = alignment;
4163 flags.layout_resolved = true;
4164 @atomicStore(Tag.TypeStruct.Flags, flags_ptr, flags, .release);
4165 }
4166
4167 pub fn hasReorderedFields(s: LoadedStructType) bool {
4168 return s.layout == .auto;
4169 }
4170
4171 pub const RuntimeOrderIterator = struct {
4172 ip: *InternPool,
4173 field_index: u32,
4174 struct_type: InternPool.LoadedStructType,
4175
4176 pub fn next(it: *@This()) ?u32 {
4177 var i = it.field_index;
4178
4179 if (i >= it.struct_type.field_types.len)
4180 return null;
4181
4182 if (it.struct_type.hasReorderedFields()) {
4183 it.field_index += 1;
4184 return it.struct_type.runtime_order.get(it.ip)[i].toInt();
4185 }
4186
4187 while (it.struct_type.fieldIsComptime(it.ip, i)) {
4188 i += 1;
4189 if (i >= it.struct_type.field_types.len)
4190 return null;
4191 }
4192
4193 it.field_index = i + 1;
4194 return i;
4195 }
4196 };
4197
4198 /// Iterates over non-comptime fields in the order they are laid out in memory at runtime.
4199 /// May or may not include zero-bit fields.
4200 /// Asserts the struct is not packed.
4201 pub fn iterateRuntimeOrder(s: LoadedStructType, ip: *InternPool) RuntimeOrderIterator {
4202 assert(s.layout != .@"packed");
4203 return .{
4204 .ip = ip,
4205 .field_index = 0,
4206 .struct_type = s,
4207 };
4208 }
4209
4210 pub const ReverseRuntimeOrderIterator = struct {
4211 ip: *InternPool,
4212 last_index: u32,
4213 struct_type: InternPool.LoadedStructType,
4214
4215 pub fn next(it: *@This()) ?u32 {
4216 if (it.last_index == 0)
4217 return null;
4218
4219 if (it.struct_type.hasReorderedFields()) {
4220 it.last_index -= 1;
4221 const order = it.struct_type.runtime_order.get(it.ip);
4222 while (order[it.last_index] == .omitted) {
4223 it.last_index -= 1;
4224 if (it.last_index == 0)
4225 return null;
4226 }
4227 return order[it.last_index].toInt();
4228 }
4229
4230 it.last_index -= 1;
4231 while (it.struct_type.fieldIsComptime(it.ip, it.last_index)) {
4232 it.last_index -= 1;
4233 if (it.last_index == 0)
4234 return null;
4235 }
4236
4237 return it.last_index;
4238 }
4239 };
4240
4241 pub fn iterateRuntimeOrderReverse(s: LoadedStructType, ip: *InternPool) ReverseRuntimeOrderIterator {
4242 assert(s.layout != .@"packed");
4243 return .{
4244 .ip = ip,
4245 .last_index = s.field_types.len,
4246 .struct_type = s,
4247 };
4248 }
4249};
3620 // TODO: the non-fqn will be needed by the new dwarf structure
3621 /// The name of this opaque type.
3622 name: NullTerminatedString,
3623 /// If this is a declared type with the `.parent` name strategy, this is the `Nav` it was named after.
3624 /// Otherwise, this is `.none`.
3625 name_nav: Nav.Index.Optional,
3626 namespace: NamespaceIndex,
3627};
42503628
42513629pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
42523630 const unwrapped_index = index.unwrap(ip);
42533631 const extra_list = unwrapped_index.getExtra(ip);
42543632 const extra_items = extra_list.view().items(.@"0");
42553633 const item = unwrapped_index.getItem(ip);
4256 switch (item.tag) {
3634 // Exiting this `switch` means this is a `packed struct`.
3635 const backing_mode: BackingTypeMode, const any_defaults: bool = switch (item.tag) {
3636 .type_struct_packed_auto => .{ .auto, false },
3637 .type_struct_packed_explicit => .{ .explicit, false },
3638 .type_struct_packed_auto_defaults => .{ .auto, true },
3639 .type_struct_packed_explicit_defaults => .{ .explicit, true },
42573640 .type_struct => {
4258 const name: NullTerminatedString = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "name").?]);
4259 const name_nav: Nav.Index.Optional = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "name_nav").?]);
4260 const namespace: NamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "namespace").?]);
4261 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);
4262 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "fields_len").?];
4263 const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .unordered));
4264 var extra_index = item.data + @as(u32, @typeInfo(Tag.TypeStruct).@"struct".fields.len);
4265 const captures_len = if (flags.any_captures) c: {
4266 const len = extra_list.view().items(.@"0")[extra_index];
4267 extra_index += 1;
4268 break :c len;
4269 } else 0;
4270 const captures: CaptureValue.Slice = .{
3641 const extra = extraDataTrail(extra_list, Tag.TypeStruct, item.data);
3642 var extra_index = extra.end;
3643 const captures: CaptureValue.Slice = switch (extra.data.flags.any_captures) {
3644 .reified => captures: {
3645 extra_index += 2; // type_hash: PackedU64
3646 break :captures .empty;
3647 },
3648 .false => .empty,
3649 .true => captures: {
3650 const len = extra_items[extra_index];
3651 extra_index += 1;
3652 break :captures .{
3653 .tid = unwrapped_index.tid,
3654 .start = extra_index,
3655 .len = len,
3656 };
3657 },
3658 };
3659 extra_index += captures.len;
3660 const field_names: NullTerminatedString.Slice = .{
42713661 .tid = unwrapped_index.tid,
42723662 .start = extra_index,
4273 .len = captures_len,
3663 .len = extra.data.fields_len,
42743664 };
4275 extra_index += captures_len;
4276 if (flags.is_reified) {
4277 extra_index += 2; // type_hash: PackedU64
4278 }
3665 extra_index += field_names.len;
42793666 const field_types: Index.Slice = .{
42803667 .tid = unwrapped_index.tid,
42813668 .start = extra_index,
4282 .len = fields_len,
3669 .len = extra.data.fields_len,
42833670 };
4284 extra_index += fields_len;
4285 const names_map: OptionalMapIndex, const names = n: {
4286 const names_map: OptionalMapIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
4287 extra_index += 1;
4288 const names: NullTerminatedString.Slice = .{
4289 .tid = unwrapped_index.tid,
4290 .start = extra_index,
4291 .len = fields_len,
4292 };
4293 extra_index += fields_len;
4294 break :n .{ names_map, names };
4295 };
4296 const inits: Index.Slice = if (flags.any_default_inits) i: {
4297 const inits: Index.Slice = .{
4298 .tid = unwrapped_index.tid,
4299 .start = extra_index,
4300 .len = fields_len,
4301 };
4302 extra_index += fields_len;
4303 break :i inits;
4304 } else Index.Slice.empty;
4305 const aligns: Alignment.Slice = if (flags.any_aligned_fields) a: {
4306 const a: Alignment.Slice = .{
4307 .tid = unwrapped_index.tid,
4308 .start = extra_index,
4309 .len = fields_len,
4310 };
4311 extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable;
4312 break :a a;
4313 } else Alignment.Slice.empty;
4314 const comptime_bits: LoadedStructType.ComptimeBits = if (flags.any_comptime_fields) c: {
4315 const len = std.math.divCeil(u32, fields_len, 32) catch unreachable;
4316 const c: LoadedStructType.ComptimeBits = .{
4317 .tid = unwrapped_index.tid,
4318 .start = extra_index,
4319 .len = len,
4320 };
4321 extra_index += len;
4322 break :c c;
4323 } else LoadedStructType.ComptimeBits.empty;
4324 const runtime_order: LoadedStructType.RuntimeOrder.Slice = if (!flags.is_extern) ro: {
4325 const ro: LoadedStructType.RuntimeOrder.Slice = .{
4326 .tid = unwrapped_index.tid,
4327 .start = extra_index,
4328 .len = fields_len,
4329 };
4330 extra_index += fields_len;
4331 break :ro ro;
4332 } else LoadedStructType.RuntimeOrder.Slice.empty;
4333 const offsets: LoadedStructType.Offsets = o: {
4334 const o: LoadedStructType.Offsets = .{
4335 .tid = unwrapped_index.tid,
4336 .start = extra_index,
4337 .len = fields_len,
4338 };
4339 extra_index += fields_len;
4340 break :o o;
4341 };
4342 return .{
3671 extra_index += field_types.len;
3672 const field_defaults: Index.Slice = if (extra.data.flags.any_field_defaults) .{
43433673 .tid = unwrapped_index.tid,
4344 .extra_index = item.data,
4345 .name = name,
4346 .name_nav = name_nav,
4347 .namespace = namespace,
4348 .zir_index = zir_index,
4349 .layout = if (flags.is_extern) .@"extern" else .auto,
4350 .field_names = names,
4351 .field_types = field_types,
4352 .field_inits = inits,
4353 .field_aligns = aligns,
4354 .runtime_order = runtime_order,
4355 .comptime_bits = comptime_bits,
4356 .offsets = offsets,
4357 .names_map = names_map,
4358 .captures = captures,
4359 };
4360 },
4361 .type_struct_packed, .type_struct_packed_inits => {
4362 const name: NullTerminatedString = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "name").?]);
4363 const name_nav: Nav.Index.Optional = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "name_nav").?]);
4364 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]);
4365 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "fields_len").?];
4366 const namespace: NamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?]);
4367 const names_map: MapIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "names_map").?]);
4368 const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .unordered));
4369 var extra_index = item.data + @as(u32, @typeInfo(Tag.TypeStructPacked).@"struct".fields.len);
4370 const has_inits = item.tag == .type_struct_packed_inits;
4371 const captures_len = if (flags.any_captures) c: {
4372 const len = extra_list.view().items(.@"0")[extra_index];
4373 extra_index += 1;
4374 break :c len;
4375 } else 0;
4376 const captures: CaptureValue.Slice = .{
3674 .start = extra_index,
3675 .len = extra.data.fields_len,
3676 } else .empty;
3677 extra_index += field_defaults.len;
3678 const field_aligns: Alignment.Slice = if (extra.data.flags.any_field_aligns) .{
43773679 .tid = unwrapped_index.tid,
43783680 .start = extra_index,
4379 .len = captures_len,
4380 };
4381 extra_index += captures_len;
4382 if (flags.is_reified) {
4383 extra_index += 2; // PackedU64
4384 }
4385 const field_types: Index.Slice = .{
3681 .len = extra.data.fields_len,
3682 } else .empty;
3683 extra_index += std.math.divCeil(u32, field_aligns.len, 4) catch unreachable;
3684 const field_is_comptime_bits: LoadedStructType.ComptimeBits = if (extra.data.flags.any_comptime_fields) .{
43863685 .tid = unwrapped_index.tid,
43873686 .start = extra_index,
4388 .len = fields_len,
4389 };
4390 extra_index += fields_len;
4391 const field_names: NullTerminatedString.Slice = .{
3687 .len = std.math.divCeil(u32, extra.data.fields_len, 32) catch unreachable,
3688 } else .empty;
3689 extra_index += field_is_comptime_bits.len;
3690 const field_runtime_order: LoadedStructType.RuntimeOrder.Slice = if (extra.data.flags.layout == .auto) .{
43923691 .tid = unwrapped_index.tid,
43933692 .start = extra_index,
4394 .len = fields_len,
3693 .len = extra.data.fields_len,
3694 } else .empty;
3695 extra_index += field_runtime_order.len;
3696 const field_offsets: LoadedStructType.Offsets = .{
3697 .tid = unwrapped_index.tid,
3698 .start = extra_index,
3699 .len = extra.data.fields_len,
43953700 };
4396 extra_index += fields_len;
4397 const field_inits: Index.Slice = if (has_inits) inits: {
4398 const i: Index.Slice = .{
4399 .tid = unwrapped_index.tid,
4400 .start = extra_index,
4401 .len = fields_len,
4402 };
4403 extra_index += fields_len;
4404 break :inits i;
4405 } else Index.Slice.empty;
3701 extra_index += field_offsets.len;
3702
44063703 return .{
4407 .tid = unwrapped_index.tid,
4408 .extra_index = item.data,
4409 .name = name,
4410 .name_nav = name_nav,
4411 .namespace = namespace,
4412 .zir_index = zir_index,
4413 .layout = .@"packed",
3704 .zir_index = extra.data.zir_index,
3705 .captures = captures,
3706 .is_reified = extra.data.flags.any_captures == .reified,
3707 .name = extra.data.name,
3708 .name_nav = extra.data.name_nav,
3709 .namespace = extra.data.namespace,
3710 .layout = switch (extra.data.flags.layout) {
3711 .auto => .auto,
3712 .@"extern" => .@"extern",
3713 },
3714 .packed_backing_mode = undefined,
3715
3716 .want_layout = extra.data.flags.want_layout,
3717
3718 .field_name_map = extra.data.field_name_map,
44143719 .field_names = field_names,
44153720 .field_types = field_types,
4416 .field_inits = field_inits,
4417 .field_aligns = Alignment.Slice.empty,
4418 .runtime_order = LoadedStructType.RuntimeOrder.Slice.empty,
4419 .comptime_bits = LoadedStructType.ComptimeBits.empty,
4420 .offsets = LoadedStructType.Offsets.empty,
4421 .names_map = names_map.toOptional(),
4422 .captures = captures,
3721 .field_defaults = field_defaults,
3722 .field_aligns = field_aligns,
3723 .field_is_comptime_bits = field_is_comptime_bits,
3724 .field_runtime_order = field_runtime_order,
3725 .field_offsets = field_offsets,
3726 .packed_backing_int_type = .none,
3727 .class = extra.data.flags.class,
3728 .size = extra.data.size,
3729 .alignment = extra.data.flags.alignment,
44233730 };
44243731 },
44253732 else => unreachable,
4426 }
4427}
4428
4429pub const LoadedEnumType = struct {
4430 // TODO: the non-fqn will be needed by the new dwarf structure
4431 /// The name of this enum type.
4432 name: NullTerminatedString,
4433 /// Represents the declarations inside this enum.
4434 namespace: NamespaceIndex,
4435 /// If this is a declared type with the `.parent` name strategy, this is the `Nav` it was named after.
4436 /// Otherwise, this is `.none`.
4437 name_nav: Nav.Index.Optional,
4438 /// An integer type which is used for the numerical value of the enum.
4439 /// This field is present regardless of whether the enum has an
4440 /// explicitly provided tag type or auto-numbered.
4441 tag_ty: Index,
4442 /// Set of field names in declaration order.
4443 names: NullTerminatedString.Slice,
4444 /// Maps integer tag value to field index.
4445 /// Entries are in declaration order, same as `fields`.
4446 /// If this is empty, it means the enum tags are auto-numbered.
4447 values: Index.Slice,
4448 tag_mode: TagMode,
4449 names_map: MapIndex,
4450 /// This is guaranteed to not be `.none` if explicit values are provided.
4451 values_map: OptionalMapIndex,
4452 /// This is `none` only if this is a generated tag type.
4453 zir_index: TrackedInst.Index.Optional,
4454 captures: CaptureValue.Slice,
4455
4456 pub const TagMode = enum {
4457 /// The integer tag type was auto-numbered by zig.
4458 auto,
4459 /// The integer tag type was provided by the enum declaration, and the enum
4460 /// is exhaustive.
4461 explicit,
4462 /// The integer tag type was provided by the enum declaration, and the enum
4463 /// is non-exhaustive.
4464 nonexhaustive,
44653733 };
3734 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, item.data);
3735 var extra_index = extra.end;
3736 const captures: CaptureValue.Slice = switch (extra.data.bits.captures_len) {
3737 .reified => captures: {
3738 extra_index += 2; // type_hash: PackedU64
3739 break :captures .empty;
3740 },
3741 _ => |n| .{
3742 .tid = unwrapped_index.tid,
3743 .start = extra_index,
3744 .len = @intFromEnum(n),
3745 },
3746 };
3747 extra_index += captures.len;
3748 const field_names: NullTerminatedString.Slice = .{
3749 .tid = unwrapped_index.tid,
3750 .start = extra_index,
3751 .len = extra.data.fields_len,
3752 };
3753 extra_index += field_names.len;
3754 const field_types: Index.Slice = .{
3755 .tid = unwrapped_index.tid,
3756 .start = extra_index,
3757 .len = extra.data.fields_len,
3758 };
3759 extra_index += field_types.len;
3760 const field_defaults: Index.Slice = if (any_defaults) .{
3761 .tid = unwrapped_index.tid,
3762 .start = extra_index,
3763 .len = extra.data.fields_len,
3764 } else .empty;
3765 extra_index += field_defaults.len;
3766 return .{
3767 .zir_index = extra.data.zir_index,
3768 .captures = captures,
3769 .is_reified = extra.data.bits.captures_len == .reified,
3770 .name = extra.data.name,
3771 .name_nav = extra.data.name_nav,
3772 .namespace = extra.data.namespace,
3773 .layout = .@"packed",
3774 .packed_backing_mode = backing_mode,
44663775
4467 /// Look up field index based on field name.
4468 pub fn nameIndex(self: LoadedEnumType, ip: *const InternPool, name: NullTerminatedString) ?u32 {
4469 const map = self.names_map.get(ip);
4470 const adapter: NullTerminatedString.Adapter = .{ .strings = self.names.get(ip) };
4471 const field_index = map.getIndexAdapted(name, adapter) orelse return null;
4472 return @intCast(field_index);
4473 }
3776 .want_layout = extra.data.bits.want_layout,
44743777
4475 /// Look up field index based on tag value.
4476 /// Asserts that `values_map` is not `none`.
4477 /// This function returns `null` when `tag_val` does not have the
4478 /// integer tag type of the enum.
4479 pub fn tagValueIndex(self: LoadedEnumType, ip: *const InternPool, tag_val: Index) ?u32 {
4480 assert(tag_val != .none);
4481 // TODO: we should probably decide a single interface for this function, but currently
4482 // it's being called with both tag values and underlying ints. Fix this!
4483 const int_tag_val = switch (ip.indexToKey(tag_val)) {
4484 .enum_tag => |enum_tag| enum_tag.int,
4485 .int => tag_val,
4486 else => unreachable,
4487 };
4488 if (self.values_map.unwrap()) |values_map| {
4489 const map = values_map.get(ip);
4490 const adapter: Index.Adapter = .{ .indexes = self.values.get(ip) };
4491 const field_index = map.getIndexAdapted(int_tag_val, adapter) orelse return null;
4492 return @intCast(field_index);
4493 }
4494 // Auto-numbered enum. Convert `int_tag_val` to field index.
4495 const field_index = switch (ip.indexToKey(int_tag_val).int.storage) {
4496 inline .u64, .i64 => |x| std.math.cast(u32, x) orelse return null,
4497 .big_int => |x| x.toInt(u32) catch return null,
4498 .lazy_align, .lazy_size => unreachable,
4499 };
4500 return if (field_index < self.names.len) field_index else null;
4501 }
4502};
3778 .field_name_map = extra.data.field_name_map,
3779 .field_names = field_names,
3780 .field_types = field_types,
3781 .field_defaults = field_defaults,
3782 .field_aligns = .empty,
3783 .field_is_comptime_bits = .empty,
3784 .field_runtime_order = .empty,
3785 .field_offsets = .empty,
3786 .packed_backing_int_type = extra.data.backing_int_type,
3787 .class = undefined,
3788 .size = undefined,
3789 .alignment = undefined,
3790 };
3791}
45033792
4504pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
3793pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
45053794 const unwrapped_index = index.unwrap(ip);
45063795 const extra_list = unwrapped_index.getExtra(ip);
3796 const extra_items = extra_list.view().items(.@"0");
45073797 const item = unwrapped_index.getItem(ip);
4508 const tag_mode: LoadedEnumType.TagMode = switch (item.tag) {
4509 .type_enum_auto => {
4510 const extra = extraDataTrail(extra_list, EnumAuto, item.data);
4511 var extra_index: u32 = @intCast(extra.end);
4512 if (extra.data.zir_index == .none) {
4513 extra_index += 1; // owner_union
4514 }
4515 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: {
4516 extra_index += 2; // type_hash: PackedU64
4517 break :c 0;
4518 } else extra.data.captures_len;
3798 // Exiting this `switch` means this is a `packed union`.
3799 const backing_mode: BackingTypeMode = switch (item.tag) {
3800 .type_union_packed_auto => .auto,
3801 .type_union_packed_explicit => .explicit,
3802 .type_union => {
3803 const extra = extraDataTrail(extra_list, Tag.TypeUnion, item.data);
3804 var extra_index = extra.end;
3805 const captures: CaptureValue.Slice = switch (extra.data.flags.any_captures) {
3806 .reified => captures: {
3807 extra_index += 2; // type_hash: PackedU64
3808 break :captures .empty;
3809 },
3810 .false => .empty,
3811 .true => captures: {
3812 const len = extra_items[extra_index];
3813 extra_index += 1;
3814 break :captures .{
3815 .tid = unwrapped_index.tid,
3816 .start = extra_index,
3817 .len = len,
3818 };
3819 },
3820 };
3821 extra_index += captures.len;
3822 const reified_field_names: NullTerminatedString.Slice = if (extra.data.flags.any_captures == .reified) .{
3823 .tid = unwrapped_index.tid,
3824 .start = extra_index,
3825 .len = extra.data.fields_len,
3826 } else .empty;
3827 extra_index += reified_field_names.len;
3828 const field_types: Index.Slice = .{
3829 .tid = unwrapped_index.tid,
3830 .start = extra_index,
3831 .len = extra.data.fields_len,
3832 };
3833 extra_index += field_types.len;
3834 const field_aligns: Alignment.Slice = if (extra.data.flags.any_field_aligns) .{
3835 .tid = unwrapped_index.tid,
3836 .start = extra_index,
3837 .len = extra.data.fields_len,
3838 } else .empty;
3839 extra_index += std.math.divCeil(u32, field_aligns.len, 4) catch unreachable;
3840
45193841 return .{
3842 .zir_index = extra.data.zir_index,
3843 .captures = captures,
3844 .is_reified = extra.data.flags.any_captures == .reified,
45203845 .name = extra.data.name,
45213846 .name_nav = extra.data.name_nav,
45223847 .namespace = extra.data.namespace,
4523 .tag_ty = extra.data.int_tag_type,
4524 .names = .{
4525 .tid = unwrapped_index.tid,
4526 .start = extra_index + captures_len,
4527 .len = extra.data.fields_len,
4528 },
4529 .values = Index.Slice.empty,
4530 .tag_mode = .auto,
4531 .names_map = extra.data.names_map,
4532 .values_map = .none,
4533 .zir_index = extra.data.zir_index,
4534 .captures = .{
4535 .tid = unwrapped_index.tid,
4536 .start = extra_index,
4537 .len = captures_len,
3848 .layout = switch (extra.data.flags.layout) {
3849 .auto => .auto,
3850 .@"extern" => .@"extern",
45383851 },
3852 .tag_usage = extra.data.flags.tag_usage,
3853 .enum_tag_mode = extra.data.flags.enum_tag_mode,
3854 .enum_tag_type = extra.data.enum_tag_type,
3855 .packed_backing_mode = undefined,
3856 .packed_backing_int_type = undefined,
3857 .reified_field_names = reified_field_names,
3858 .want_layout = extra.data.flags.want_layout,
3859 .field_types = field_types,
3860 .field_aligns = field_aligns,
3861 .has_runtime_tag = extra.data.flags.has_runtime_tag,
3862 .class = extra.data.flags.class,
3863 .size = extra.data.size,
3864 .padding = extra.data.padding,
3865 .alignment = extra.data.flags.alignment,
45393866 };
45403867 },
4541 .type_enum_explicit => .explicit,
4542 .type_enum_nonexhaustive => .nonexhaustive,
45433868 else => unreachable,
45443869 };
4545 const extra = extraDataTrail(extra_list, EnumExplicit, item.data);
4546 var extra_index: u32 = @intCast(extra.end);
4547 if (extra.data.zir_index == .none) {
4548 extra_index += 1; // owner_union
4549 }
4550 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32)) c: {
4551 extra_index += 2; // type_hash: PackedU64
4552 break :c 0;
4553 } else extra.data.captures_len;
4554 return .{
4555 .name = extra.data.name,
4556 .name_nav = extra.data.name_nav,
4557 .namespace = extra.data.namespace,
4558 .tag_ty = extra.data.int_tag_type,
4559 .names = .{
4560 .tid = unwrapped_index.tid,
4561 .start = extra_index + captures_len,
4562 .len = extra.data.fields_len,
3870 const extra = extraDataTrail(extra_list, Tag.TypeUnionPacked, item.data);
3871 var extra_index = extra.end;
3872 const captures: CaptureValue.Slice = switch (extra.data.bits.captures_len) {
3873 .reified => captures: {
3874 extra_index += 2; // type_hash: PackedU64
3875 break :captures .empty;
45633876 },
4564 .values = .{
4565 .tid = unwrapped_index.tid,
4566 .start = extra_index + captures_len + extra.data.fields_len,
4567 .len = if (extra.data.values_map != .none) extra.data.fields_len else 0,
4568 },
4569 .tag_mode = tag_mode,
4570 .names_map = extra.data.names_map,
4571 .values_map = extra.data.values_map,
4572 .zir_index = extra.data.zir_index,
4573 .captures = .{
3877 _ => |n| .{
45743878 .tid = unwrapped_index.tid,
45753879 .start = extra_index,
4576 .len = captures_len,
3880 .len = @intFromEnum(n),
45773881 },
45783882 };
3883 extra_index += captures.len;
3884 const reified_field_names: NullTerminatedString.Slice = if (extra.data.bits.captures_len == .reified) .{
3885 .tid = unwrapped_index.tid,
3886 .start = extra_index,
3887 .len = extra.data.fields_len,
3888 } else .empty;
3889 extra_index += reified_field_names.len;
3890 const field_types: Index.Slice = .{
3891 .tid = unwrapped_index.tid,
3892 .start = extra_index,
3893 .len = extra.data.fields_len,
3894 };
3895 extra_index += field_types.len;
3896 return .{
3897 .zir_index = extra.data.zir_index,
3898 .captures = captures,
3899 .is_reified = extra.data.bits.captures_len == .reified,
3900 .name = extra.data.name,
3901 .name_nav = extra.data.name_nav,
3902 .namespace = extra.data.namespace,
3903 .layout = .@"packed",
3904 .tag_usage = .none,
3905 .enum_tag_mode = .auto,
3906 .enum_tag_type = extra.data.enum_tag_type,
3907 .packed_backing_mode = backing_mode,
3908 .packed_backing_int_type = extra.data.backing_int_type,
3909 .reified_field_names = reified_field_names,
3910 .want_layout = extra.data.bits.want_layout,
3911 .field_types = field_types,
3912 .field_aligns = .empty,
3913 .has_runtime_tag = false,
3914 .class = undefined,
3915 .size = undefined,
3916 .padding = undefined,
3917 .alignment = undefined,
3918 };
45793919}
45803920
4581/// Note that this type doubles as the payload for `Tag.type_opaque`.
4582pub const LoadedOpaqueType = struct {
4583 /// Contains the declarations inside this opaque.
4584 namespace: NamespaceIndex,
4585 // TODO: the non-fqn will be needed by the new dwarf structure
4586 /// The name of this opaque type.
4587 name: NullTerminatedString,
4588 /// If this is a declared type with the `.parent` name strategy, this is the `Nav` it was named after.
4589 /// Otherwise, this is `.none`.
4590 name_nav: Nav.Index.Optional,
4591 /// Index of the `opaque_decl` or `reify` instruction.
4592 zir_index: TrackedInst.Index,
4593 captures: CaptureValue.Slice,
4594};
3921pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
3922 const unwrapped_index = index.unwrap(ip);
3923 const extra_list = unwrapped_index.getExtra(ip);
3924 const extra_items = extra_list.view().items(.@"0");
3925 const item = unwrapped_index.getItem(ip);
3926 const explicit_int_tag: bool, const nonexhaustive: bool = switch (item.tag) {
3927 .type_enum_auto => .{ false, false },
3928 .type_enum_explicit => .{ true, false },
3929 .type_enum_nonexhaustive => .{ true, true },
3930 else => unreachable,
3931 };
3932 const extra = extraDataTrail(extra_list, Tag.TypeEnum, item.data);
3933 var extra_index: u32 = @intCast(extra.end);
3934 const zir_index: TrackedInst.Index.Optional, const captures: CaptureValue.Slice, const owner_union: Index = switch (extra.data.bits.captures_len) {
3935 .reified => info: {
3936 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[extra_index]);
3937 extra_index += 1;
3938 extra_index += 2; // type_hash: PackedU64
3939 break :info .{ zir_index.toOptional(), .empty, .none };
3940 },
3941 .generated_union_tag => info: {
3942 const owner_union: Index = @enumFromInt(extra_items[extra_index]);
3943 extra_index += 1;
3944 break :info .{ .none, .empty, owner_union };
3945 },
3946 _ => |n| info: {
3947 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[extra_index]);
3948 extra_index += 1;
3949 const captures: CaptureValue.Slice = .{
3950 .tid = unwrapped_index.tid,
3951 .start = extra_index,
3952 .len = @intFromEnum(n),
3953 };
3954 extra_index += captures.len;
3955 break :info .{ zir_index.toOptional(), captures, .none };
3956 },
3957 };
3958 const field_value_map: OptionalMapIndex = if (explicit_int_tag) m: {
3959 const map: MapIndex = @enumFromInt(extra_items[extra_index]);
3960 extra_index += 1;
3961 break :m map.toOptional();
3962 } else .none;
3963 const field_names: NullTerminatedString.Slice = .{
3964 .tid = unwrapped_index.tid,
3965 .start = extra_index,
3966 .len = extra.data.fields_len,
3967 };
3968 extra_index += field_names.len;
3969 const field_values: Index.Slice = if (explicit_int_tag) .{
3970 .tid = unwrapped_index.tid,
3971 .start = extra_index,
3972 .len = extra.data.fields_len,
3973 } else .empty;
3974 extra_index += field_values.len;
3975 return .{
3976 .zir_index = zir_index,
3977 .captures = captures,
3978 .is_reified = extra.data.bits.captures_len == .reified,
3979 .owner_union = owner_union,
3980 .name = extra.data.name,
3981 .name_nav = extra.data.name_nav,
3982 .namespace = extra.data.namespace,
3983 .int_tag_type = extra.data.int_tag_type,
3984 .int_tag_mode = if (explicit_int_tag) .explicit else .auto,
3985 .nonexhaustive = nonexhaustive,
3986 .want_layout = extra.data.bits.want_layout,
3987 .field_name_map = extra.data.field_name_map,
3988 .field_value_map = field_value_map,
3989 .field_names = field_names,
3990 .field_values = field_values,
3991 };
3992}
45953993
45963994pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {
45973995 const unwrapped_index = index.unwrap(ip);
45983996 const item = unwrapped_index.getItem(ip);
45993997 assert(item.tag == .type_opaque);
46003998 const extra = extraDataTrail(unwrapped_index.getExtra(ip), Tag.TypeOpaque, item.data);
4601 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32))
4602 0
4603 else
4604 extra.data.captures_len;
46053999 return .{
4606 .name = extra.data.name,
4607 .name_nav = extra.data.name_nav,
4608 .namespace = extra.data.namespace,
46094000 .zir_index = extra.data.zir_index,
46104001 .captures = .{
46114002 .tid = unwrapped_index.tid,
46124003 .start = extra.end,
4613 .len = captures_len,
4004 .len = extra.data.captures_len,
46144005 },
4006 .name = extra.data.name,
4007 .name_nav = extra.data.name_nav,
4008 .namespace = extra.data.namespace,
46154009 };
46164010}
46174011
......@@ -4816,6 +4210,13 @@ pub const Index = enum(u32) {
48164210 const extra = ip.getLocalShared(slice.tid).extra.acquire();
48174211 return @ptrCast(extra.view().items(.@"0")[slice.start..][0..slice.len]);
48184212 }
4213
4214 /// If `slice` is empty (`slice.len == 0`), returns `.none`.
4215 /// Otherwise, asserts that `index < slice.len`, and returns the value at `index`.
4216 pub fn getOrNone(slice: Slice, ip: *const InternPool, index: usize) Index {
4217 if (slice.len == 0) return .none;
4218 return slice.get(ip)[index];
4219 }
48194220 };
48204221
48214222 /// Used for a map of `Index` values to the index within a list of `Index` values.
......@@ -4891,26 +4292,6 @@ pub const Index = enum(u32) {
48914292 /// Tag to encoding mapping to facilitate fancy debug printing for this type.
48924293 fn dbHelper(self: *Index, tag_to_encoding_map: *struct {
48934294 const DataIsIndex = struct { data: Index };
4894 const DataIsExtraIndexOfEnumExplicit = struct {
4895 const @"data.fields_len" = opaque {};
4896 data: *EnumExplicit,
4897 @"trailing.names.len": *@"data.fields_len",
4898 @"trailing.values.len": *@"data.fields_len",
4899 trailing: struct {
4900 names: []NullTerminatedString,
4901 values: []Index,
4902 },
4903 };
4904 const DataIsExtraIndexOfTypeTuple = struct {
4905 const @"data.fields_len" = opaque {};
4906 data: *TypeTuple,
4907 @"trailing.types.len": *@"data.fields_len",
4908 @"trailing.values.len": *@"data.fields_len",
4909 trailing: struct {
4910 types: []Index,
4911 values: []Index,
4912 },
4913 };
49144295
49154296 removed: void,
49164297 type_int_signed: struct { data: u32 },
......@@ -4931,31 +4312,40 @@ pub const Index = enum(u32) {
49314312 trailing: struct { names: []NullTerminatedString },
49324313 },
49334314 type_inferred_error_set: DataIsIndex,
4934 type_enum_auto: struct {
4315 simple_type: void,
4316 type_function: struct {
4317 const @"data.flags.has_comptime_bits" = opaque {};
4318 const @"data.flags.has_noalias_bits" = opaque {};
4319 const @"data.params_len" = opaque {};
4320 data: *Tag.TypeFunction,
4321 @"trailing.comptime_bits.len": *@"data.flags.has_comptime_bits",
4322 @"trailing.noalias_bits.len": *@"data.flags.has_noalias_bits",
4323 @"trailing.param_types.len": *@"data.params_len",
4324 trailing: struct { comptime_bits: []u32, noalias_bits: []u32, param_types: []Index },
4325 },
4326 type_tuple: struct {
49354327 const @"data.fields_len" = opaque {};
4936 data: *EnumAuto,
4937 @"trailing.names.len": *@"data.fields_len",
4938 trailing: struct { names: []NullTerminatedString },
4328 data: *TypeTuple,
4329 @"trailing.types.len": *@"data.fields_len",
4330 @"trailing.values.len": *@"data.fields_len",
4331 trailing: struct {
4332 types: []Index,
4333 values: []Index,
4334 },
49394335 },
4940 type_enum_explicit: DataIsExtraIndexOfEnumExplicit,
4941 type_enum_nonexhaustive: DataIsExtraIndexOfEnumExplicit,
4942 simple_type: void,
4943 type_opaque: struct { data: *Tag.TypeOpaque },
4336
49444337 type_struct: struct { data: *Tag.TypeStruct },
4945 type_struct_packed: struct { data: *Tag.TypeStructPacked },
4946 type_struct_packed_inits: struct { data: *Tag.TypeStructPacked },
4947 type_tuple: DataIsExtraIndexOfTypeTuple,
4338 type_struct_packed_auto: struct { data: *Tag.TypeStructPacked },
4339 type_struct_packed_explicit: struct { data: *Tag.TypeStructPacked },
4340 type_struct_packed_auto_defaults: struct { data: *Tag.TypeStructPacked },
4341 type_struct_packed_explicit_defaults: struct { data: *Tag.TypeStructPacked },
49484342 type_union: struct { data: *Tag.TypeUnion },
4949 type_function: struct {
4950 const @"data.flags.has_comptime_bits" = opaque {};
4951 const @"data.flags.has_noalias_bits" = opaque {};
4952 const @"data.params_len" = opaque {};
4953 data: *Tag.TypeFunction,
4954 @"trailing.comptime_bits.len": *@"data.flags.has_comptime_bits",
4955 @"trailing.noalias_bits.len": *@"data.flags.has_noalias_bits",
4956 @"trailing.param_types.len": *@"data.params_len",
4957 trailing: struct { comptime_bits: []u32, noalias_bits: []u32, param_types: []Index },
4958 },
4343 type_union_packed_auto: struct { data: *Tag.TypeUnionPacked },
4344 type_union_packed_explicit: struct { data: *Tag.TypeUnionPacked },
4345 type_enum_auto: struct { data: *Tag.TypeEnum },
4346 type_enum_explicit: struct { data: *Tag.TypeEnum },
4347 type_enum_nonexhaustive: struct { data: *Tag.TypeEnum },
4348 type_opaque: struct { data: *Tag.TypeOpaque },
49594349
49604350 undef: DataIsIndex,
49614351 simple_value: void,
......@@ -4982,8 +4372,6 @@ pub const Index = enum(u32) {
49824372 int_small: struct { data: *IntSmall },
49834373 int_positive: struct { data: u32 },
49844374 int_negative: struct { data: u32 },
4985 int_lazy_align: struct { data: *IntLazy },
4986 int_lazy_size: struct { data: *IntLazy },
49874375 error_set_error: struct { data: *Key.Error },
49884376 error_union_error: struct { data: *Key.Error },
49894377 error_union_payload: struct { data: *Tag.TypeValue },
......@@ -5027,6 +4415,7 @@ pub const Index = enum(u32) {
50274415 trailing: struct { element_values: []Index },
50284416 },
50294417 repeated: struct { data: *Repeated },
4418 bitpack: struct { data: *Key.Bitpack },
50304419
50314420 memoized_call: struct {
50324421 const @"data.args_len" = opaque {};
......@@ -5037,7 +4426,7 @@ pub const Index = enum(u32) {
50374426 }) void {
50384427 _ = self;
50394428 const map_fields = @typeInfo(@typeInfo(@TypeOf(tag_to_encoding_map)).pointer.child).@"struct".fields;
5040 @setEvalBranchQuota(2_000);
4429 @setEvalBranchQuota(3_000);
50414430 inline for (@typeInfo(Tag).@"enum".fields, 0..) |tag, start| {
50424431 inline for (0..map_fields.len) |offset| {
50434432 if (comptime std.mem.eql(u8, tag.name, map_fields[(start + offset) % map_fields.len].name)) break;
......@@ -5409,7 +4798,7 @@ pub const static_keys: [static_len]Key = .{
54094798 .values = .empty,
54104799 } },
54114800
5412 .{ .simple_value = .undefined },
4801 .{ .undef = .undefined_type },
54134802 .{ .undef = .bool_type },
54144803 .{ .undef = .usize_type },
54154804 .{ .undef = .u1_type },
......@@ -5469,7 +4858,11 @@ pub const static_keys: [static_len]Key = .{
54694858 .{ .simple_value = .null },
54704859 .{ .simple_value = .true },
54714860 .{ .simple_value = .false },
5472 .{ .simple_value = .empty_tuple },
4861
4862 .{ .aggregate = .{
4863 .ty = .empty_tuple_type,
4864 .storage = .{ .elems = &.{} },
4865 } },
54734866};
54744867
54754868/// How many items in the InternPool are statically known.
......@@ -5485,6 +4878,8 @@ pub const Tag = enum(u8) {
54854878 /// assert not this tag. `data` is unused.
54864879 removed,
54874880
4881 /// A type that can be represented with only an enum tag.
4882 simple_type,
54884883 /// An integer type.
54894884 /// data is number of bits
54904885 type_int_signed,
......@@ -5524,41 +4919,68 @@ pub const Tag = enum(u8) {
55244919 /// The inferred error set type of a function.
55254920 /// data is `Index` of a `func_decl` or `func_instance`.
55264921 type_inferred_error_set,
5527 /// An enum type with auto-numbered tag values.
5528 /// The enum is exhaustive.
5529 /// data is payload index to `EnumAuto`.
5530 type_enum_auto,
5531 /// An enum type with an explicitly provided integer tag type.
5532 /// The enum is exhaustive.
5533 /// data is payload index to `EnumExplicit`.
5534 type_enum_explicit,
5535 /// An enum type with an explicitly provided integer tag type.
5536 /// The enum is non-exhaustive.
5537 /// data is payload index to `EnumExplicit`.
5538 type_enum_nonexhaustive,
5539 /// A type that can be represented with only an enum tag.
5540 simple_type,
5541 /// An opaque type.
5542 /// data is index of Tag.TypeOpaque in extra.
5543 type_opaque,
4922 /// A function body type.
4923 /// `data` is extra index to `TypeFunction`.
4924 type_function,
4925 /// A `TupleType`.
4926 /// data is extra index of `TypeTuple`.
4927 type_tuple,
4928
55444929 /// A non-packed struct type.
5545 /// data is 0 or extra index of `TypeStruct`.
4930 /// data is extra index of `TypeStruct`.
55464931 type_struct,
5547 /// A packed struct, no fields have any init values.
4932 /// `packed struct { ... }` with no default field values.
55484933 /// data is extra index of `TypeStructPacked`.
5549 type_struct_packed,
5550 /// A packed struct, one or more fields have init values.
4934 type_struct_packed_auto,
4935 /// `packed struct(T) { ... }` with no default field values.
55514936 /// data is extra index of `TypeStructPacked`.
5552 type_struct_packed_inits,
5553 /// A `TupleType`.
5554 /// data is extra index of `TypeTuple`.
5555 type_tuple,
5556 /// A union type.
5557 /// `data` is extra index of `TypeUnion`.
4937 type_struct_packed_explicit,
4938 /// `packed struct { ... }` with one or more default field values.
4939 /// data is extra index of `TypeStructPacked`.
4940 type_struct_packed_auto_defaults,
4941 /// `packed struct(T) { ... }` with one or more default field values.
4942 /// data is extra index of `TypeStructPacked`.
4943 type_struct_packed_explicit_defaults,
4944
4945 /// A non-packed union type.
4946 /// data is extra index of `TypeUnion`.
55584947 type_union,
5559 /// A function body type.
5560 /// `data` is extra index to `TypeFunction`.
5561 type_function,
4948 /// `packed union { ... }`.
4949 /// data is extra index of `TypeUnionPacked`.
4950 type_union_packed_auto,
4951 /// `packed union(T) { ... }`.
4952 /// data is extra index of `TypeUnionPacked`.
4953 type_union_packed_explicit,
4954
4955 /// An exhaustive enum type *without* an explicit integer tag type. The tag type is inferred.
4956 ///
4957 /// Because the tag type is inferred, there are no explicit field values.
4958 ///
4959 /// May be the generated tag type for a `union(enum)`.
4960 ///
4961 /// data is extra index of `TypeEnum`.
4962 type_enum_auto,
4963 /// An exhaustive enum type *with* an explicit integer tag type.
4964 ///
4965 /// May have explicit field values.
4966 ///
4967 /// May be the generated tag type for a `union(enum(T))`.
4968 ///
4969 /// data is extra index of `TypeEnum`.
4970 type_enum_explicit,
4971 /// An non-exhaustive enum type (with an explicit integer tag type, since it is required for
4972 /// non-exhaustive enums).
4973 ///
4974 /// May have explicit field values.
4975 ///
4976 /// This is *not* a union's generated tag type, because such types are always exhaustive.
4977 ///
4978 /// data is extra index of `TypeEnum`.
4979 type_enum_nonexhaustive,
4980
4981 /// An opaque type.
4982 /// data is extra index of `TypeOpaque`.
4983 type_opaque,
55624984
55634985 /// Typed `undefined`.
55644986 /// `data` is `Index` of the type.
......@@ -5644,12 +5066,6 @@ pub const Tag = enum(u8) {
56445066 /// A negative integer value.
56455067 /// data is a limbs index to `Int`.
56465068 int_negative,
5647 /// The ABI alignment of a lazy type.
5648 /// data is extra index of `IntLazy`.
5649 int_lazy_align,
5650 /// The ABI size of a lazy type.
5651 /// data is extra index of `IntLazy`.
5652 int_lazy_size,
56535069 /// An error value.
56545070 /// data is extra index of `Key.Error`.
56555071 error_set_error,
......@@ -5735,6 +5151,9 @@ pub const Tag = enum(u8) {
57355151 /// An instance of an array or vector with every element being the same value.
57365152 /// data is extra index to `Repeated`.
57375153 repeated,
5154 /// An instance of a `packed struct` or `packed union`.
5155 /// data is extra index to `Key.Bitpack`.
5156 bitpack,
57385157
57395158 /// A memoized comptime function call result.
57405159 /// data is extra index to `MemoizedCall`
......@@ -5747,24 +5166,77 @@ pub const Tag = enum(u8) {
57475166 const Union = Key.Union;
57485167 const TypePointer = Key.PtrType;
57495168
5750 const enum_explicit_encoding = .{
5169 const struct_packed_encoding = .{
5170 .summary = .@"{.payload.name%summary#\"}",
5171 .payload = TypeStructPacked,
5172 .trailing = struct {
5173 type_hash: ?u64,
5174 captures: ?[]CaptureValue,
5175 field_names: []NullTerminatedString,
5176 field_types: []Index,
5177 },
5178 .config = .{
5179 .@"trailing.type_hash.?" = .@"payload.captures_len == .reified",
5180 .@"trailing.captures.?" = .@"payload.captures_len != .reified",
5181 .@"trailing.captures.?.len" = .@"@intFromEnum(payload.captures_len)",
5182 .@"trailing.field_names.len" = .@"payload.fields_len",
5183 .@"trailing.field_types.len" = .@"payload.fields_len",
5184 },
5185 };
5186 const struct_packed_defaults_encoding = .{
5187 .summary = .@"{.payload.name%summary#\"}",
5188 .payload = TypeStructPacked,
5189 .trailing = struct {
5190 type_hash: ?u64,
5191 captures: ?[]CaptureValue,
5192 field_names: []NullTerminatedString,
5193 field_types: []Index,
5194 field_defaults: []Index,
5195 },
5196 .config = .{
5197 .@"trailing.type_hash.?" = .@"payload.captures_len == .reified",
5198 .@"trailing.captures.?" = .@"payload.captures_len != .reified",
5199 .@"trailing.captures.?.len" = .@"@intFromEnum(payload.captures_len)",
5200 .@"trailing.field_names.len" = .@"payload.fields_len",
5201 .@"trailing.field_types.len" = .@"payload.fields_len",
5202 .@"trailing.field_defaults.len" = .@"payload.fields_len",
5203 },
5204 };
5205 const union_packed_encoding = .{
57515206 .summary = .@"{.payload.name%summary#\"}",
5752 .payload = EnumExplicit,
5207 .payload = TypeUnionPacked,
57535208 .trailing = struct {
5754 owner_union: Index,
5209 type_hash: ?u64,
57555210 captures: ?[]CaptureValue,
5211 field_types: []Index,
5212 },
5213 .config = .{
5214 .@"trailing.type_hash.?" = .@"payload.captures_len == .reified",
5215 .@"trailing.captures.?" = .@"payload.captures_len != .reified",
5216 .@"trailing.captures.?.len" = .@"@intFromEnum(payload.captures_len)",
5217 .@"trailing.field_types.len" = .@"payload.fields_len",
5218 },
5219 };
5220 const enum_explicit_encoding = .{
5221 .summary = .@"{.payload.name%summary#\"}",
5222 .payload = TypeEnum,
5223 .trailing = struct {
5224 owner_union: ?Index,
5225 zir_index: ?TrackedInst.Index,
57565226 type_hash: ?u64,
5227 captures: ?[]CaptureValue,
5228 field_value_map: MapIndex,
57575229 field_names: []NullTerminatedString,
5758 tag_values: []Index,
5230 field_values: []Index,
57595231 },
57605232 .config = .{
5761 .@"trailing.owner_union.?" = .@"payload.zir_index == .none",
5762 .@"trailing.cau.?" = .@"payload.zir_index != .none",
5763 .@"trailing.captures.?" = .@"payload.captures_len < 0xffffffff",
5764 .@"trailing.captures.?.len" = .@"payload.captures_len",
5765 .@"trailing.type_hash.?" = .@"payload.captures_len == 0xffffffff",
5233 .@"trailing.owner_union.?" = .@"payload.captures_len == .generated_union_tag",
5234 .@"trailing.zir_index.?" = .@"payload.captures_len != .generated_union_tag",
5235 .@"trailing.type_hash.?" = .@"payload.captures_len == .reified",
5236 .@"trailing.captures.?" = .@"payload.captures_len != .reified and payload.captures_len != .generated_enum_tag",
5237 .@"trailing.captures.?.len" = .@"@intFromEnum(payload.captures_len)",
57665238 .@"trailing.field_names.len" = .@"payload.fields_len",
5767 .@"trailing.tag_values.len" = .@"payload.fields_len",
5239 .@"trailing.field_values.len" = .@"payload.fields_len",
57685240 },
57695241 };
57705242 const encodings = .{
......@@ -5792,153 +5264,121 @@ pub const Tag = enum(u8) {
57925264 .summary = .@"@typeInfo(@typeInfo(@TypeOf({.data%summary})).@\"fn\".return_type.?).error_union.error_set",
57935265 .data = Index,
57945266 },
5795 .type_enum_auto = .{
5796 .summary = .@"{.payload.name%summary#\"}",
5797 .payload = EnumAuto,
5267 .simple_type = .{ .summary = .@"{.index%value#.}", .index = SimpleType },
5268 .type_tuple = .{
5269 .summary = .@"struct {...}",
5270 .payload = TypeTuple,
57985271 .trailing = struct {
5799 owner_union: ?Index,
5800 captures: ?[]CaptureValue,
5801 type_hash: ?u64,
5802 field_names: []NullTerminatedString,
5272 field_types: []Index,
5273 field_values: []Index,
58035274 },
58045275 .config = .{
5805 .@"trailing.owner_union.?" = .@"payload.zir_index == .none",
5806 .@"trailing.cau.?" = .@"payload.zir_index != .none",
5807 .@"trailing.captures.?" = .@"payload.captures_len < 0xffffffff",
5808 .@"trailing.captures.?.len" = .@"payload.captures_len",
5809 .@"trailing.type_hash.?" = .@"payload.captures_len == 0xffffffff",
5810 .@"trailing.field_names.len" = .@"payload.fields_len",
5276 .@"trailing.field_types.len" = .@"payload.fields_len",
5277 .@"trailing.field_values.len" = .@"payload.fields_len",
58115278 },
58125279 },
5813 .type_enum_explicit = enum_explicit_encoding,
5814 .type_enum_nonexhaustive = enum_explicit_encoding,
5815 .simple_type = .{ .summary = .@"{.index%value#.}", .index = SimpleType },
5816 .type_opaque = .{
5817 .summary = .@"{.payload.name%summary#\"}",
5818 .payload = TypeOpaque,
5819 .trailing = struct { captures: []CaptureValue },
5820 .config = .{ .@"trailing.captures.len" = .@"payload.captures_len" },
5280 .type_function = .{
5281 .summary = .@"fn (...) ... {.payload.return_type%summary}",
5282 .payload = TypeFunction,
5283 .trailing = struct {
5284 param_comptime_bits: ?[]u32,
5285 param_noalias_bits: ?[]u32,
5286 param_type: []Index,
5287 },
5288 .config = .{
5289 .@"trailing.param_comptime_bits.?" = .@"payload.flags.has_comptime_bits",
5290 .@"trailing.param_comptime_bits.?.len" = .@"(payload.params_len + 31) / 32",
5291 .@"trailing.param_noalias_bits.?" = .@"payload.flags.has_noalias_bits",
5292 .@"trailing.param_noalias_bits.?.len" = .@"(payload.params_len + 31) / 32",
5293 .@"trailing.param_type.len" = .@"payload.params_len",
5294 },
58215295 },
5296
58225297 .type_struct = .{
58235298 .summary = .@"{.payload.name%summary#\"}",
58245299 .payload = TypeStruct,
58255300 .trailing = struct {
5301 type_hash: ?u64,
58265302 captures_len: ?u32,
58275303 captures: ?[]CaptureValue,
5828 type_hash: ?u64,
5829 field_types: []Index,
5830 field_names_map: OptionalMapIndex,
58315304 field_names: []NullTerminatedString,
5832 field_inits: ?[]Index,
5305 field_types: []Index,
5306 field_defaults: ?[]Index,
58335307 field_aligns: ?[]Alignment,
58345308 field_is_comptime_bits: ?[]u32,
5835 field_index: ?[]LoadedStructType.RuntimeOrder,
5836 field_offset: []u32,
5309 field_runtime_order: ?[]u32,
5310 field_offsets: []u32,
58375311 },
58385312 .config = .{
5839 .@"trailing.captures_len.?" = .@"payload.flags.any_captures",
5840 .@"trailing.captures.?" = .@"payload.flags.any_captures",
5313 .@"trailing.type_hash.?" = .@"payload.flags.any_captures == .reified",
5314 .@"trailing.captures_len.?" = .@"payload.flags.any_captures == .true",
5315 .@"trailing.captures.?" = .@"payload.flags.any_captures == .true",
58415316 .@"trailing.captures.?.len" = .@"trailing.captures_len.?",
5842 .@"trailing.type_hash.?" = .@"payload.flags.is_reified",
5843 .@"trailing.field_types.len" = .@"payload.fields_len",
58445317 .@"trailing.field_names.len" = .@"payload.fields_len",
5845 .@"trailing.field_inits.?" = .@"payload.flags.any_default_inits",
5846 .@"trailing.field_inits.?.len" = .@"payload.fields_len",
5847 .@"trailing.field_aligns.?" = .@"payload.flags.any_aligned_fields",
5318 .@"trailing.field_types.len" = .@"payload.fields_len",
5319 .@"trailing.field_defaults.?" = .@"payload.flags.any_field_defaults",
5320 .@"trailing.field_defaults.?.len" = .@"payload.fields_len",
5321 .@"trailing.field_aligns.?" = .@"payload.flags.any_field_aligns",
58485322 .@"trailing.field_aligns.?.len" = .@"payload.fields_len",
58495323 .@"trailing.field_is_comptime_bits.?" = .@"payload.flags.any_comptime_fields",
58505324 .@"trailing.field_is_comptime_bits.?.len" = .@"(payload.fields_len + 31) / 32",
5851 .@"trailing.field_index.?" = .@"!payload.flags.is_extern",
5852 .@"trailing.field_index.?.len" = .@"payload.fields_len",
5853 .@"trailing.field_offset.len" = .@"payload.fields_len",
5325 .@"trailing.field_runtime_order.?" = .@"payload.flags.layout == .auto",
5326 .@"trailing.field_runtime_order.?.len" = .@"payload.fields_len",
5327 .@"trailing.field_offsets.len" = .@"payload.fields_len",
58545328 },
58555329 },
5856 .type_struct_packed = .{
5330 .type_struct_packed_auto = struct_packed_encoding,
5331 .type_struct_packed_explicit = struct_packed_encoding,
5332 .type_struct_packed_auto_defaults = struct_packed_defaults_encoding,
5333 .type_struct_packed_explicit_defaults = struct_packed_defaults_encoding,
5334 .type_union = .{
58575335 .summary = .@"{.payload.name%summary#\"}",
5858 .payload = TypeStructPacked,
5336 .payload = TypeUnion,
58595337 .trailing = struct {
5338 type_hash: ?u64,
58605339 captures_len: ?u32,
58615340 captures: ?[]CaptureValue,
5862 type_hash: ?u64,
58635341 field_types: []Index,
5864 field_names: []NullTerminatedString,
5342 field_aligns: ?[]Alignment,
58655343 },
58665344 .config = .{
5867 .@"trailing.captures_len.?" = .@"payload.flags.any_captures",
5868 .@"trailing.captures.?" = .@"payload.flags.any_captures",
5345 .@"trailing.type_hash.?" = .@"payload.flags.any_captures == .reified",
5346 .@"trailing.captures_len.?" = .@"payload.flags.any_captures == .true",
5347 .@"trailing.captures.?" = .@"payload.flags.any_captures == .true",
58695348 .@"trailing.captures.?.len" = .@"trailing.captures_len.?",
5870 .@"trailing.type_hash.?" = .@"payload.is_flags.is_reified",
58715349 .@"trailing.field_types.len" = .@"payload.fields_len",
5872 .@"trailing.field_names.len" = .@"payload.fields_len",
5350 .@"trailing.field_aligns.?" = .@"payloads.flags.any_field_aligns",
5351 .@"trailing.field_aligns.?.len" = .@"payload.fields_len",
58735352 },
58745353 },
5875 .type_struct_packed_inits = .{
5354 .type_union_packed_auto = union_packed_encoding,
5355 .type_union_packed_explicit = union_packed_encoding,
5356 .type_enum_auto = .{
58765357 .summary = .@"{.payload.name%summary#\"}",
5877 .payload = TypeStructPacked,
5358 .payload = TypeEnum,
58785359 .trailing = struct {
5879 captures_len: ?u32,
5880 captures: ?[]CaptureValue,
5360 owner_union: ?Index,
5361 zir_index: ?TrackedInst.Index,
58815362 type_hash: ?u64,
5882 field_types: []Index,
5363 captures: ?[]CaptureValue,
58835364 field_names: []NullTerminatedString,
5884 field_inits: []Index,
58855365 },
58865366 .config = .{
5887 .@"trailing.captures_len.?" = .@"payload.flags.any_captures",
5888 .@"trailing.captures.?" = .@"payload.flags.any_captures",
5889 .@"trailing.captures.?.len" = .@"trailing.captures_len.?",
5890 .@"trailing.type_hash.?" = .@"payload.is_flags.is_reified",
5891 .@"trailing.field_types.len" = .@"payload.fields_len",
5367 .@"trailing.owner_union.?" = .@"payload.captures_len == .generated_union_tag",
5368 .@"trailing.zir_index.?" = .@"payload.captures_len != .generated_union_tag",
5369 .@"trailing.type_hash.?" = .@"payload.captures_len == .reified",
5370 .@"trailing.captures.?" = .@"payload.captures_len != .reified and payload.captures_len != .generated_enum_tag",
5371 .@"trailing.captures.?.len" = .@"@intFromEnum(payload.captures_len)",
58925372 .@"trailing.field_names.len" = .@"payload.fields_len",
5893 .@"trailing.field_inits.len" = .@"payload.fields_len",
5894 },
5895 },
5896 .type_tuple = .{
5897 .summary = .@"struct {...}",
5898 .payload = TypeTuple,
5899 .trailing = struct {
5900 field_types: []Index,
5901 field_values: []Index,
5902 },
5903 .config = .{
5904 .@"trailing.field_types.len" = .@"payload.fields_len",
5905 .@"trailing.field_values.len" = .@"payload.fields_len",
59065373 },
59075374 },
5908 .type_union = .{
5375 .type_enum_explicit = enum_explicit_encoding,
5376 .type_enum_nonexhaustive = enum_explicit_encoding,
5377 .type_opaque = .{
59095378 .summary = .@"{.payload.name%summary#\"}",
5910 .payload = TypeUnion,
5911 .trailing = struct {
5912 captures_len: ?u32,
5913 captures: ?[]CaptureValue,
5914 type_hash: ?u64,
5915 field_types: []Index,
5916 field_aligns: []Alignment,
5917 },
5918 .config = .{
5919 .@"trailing.captures_len.?" = .@"payload.flags.any_captures",
5920 .@"trailing.captures.?" = .@"payload.flags.any_captures",
5921 .@"trailing.captures.?.len" = .@"trailing.captures_len.?",
5922 .@"trailing.type_hash.?" = .@"payload.is_flags.is_reified",
5923 .@"trailing.field_types.len" = .@"payload.fields_len",
5924 .@"trailing.field_aligns.len" = .@"payload.fields_len",
5925 },
5926 },
5927 .type_function = .{
5928 .summary = .@"fn (...) ... {.payload.return_type%summary}",
5929 .payload = TypeFunction,
5930 .trailing = struct {
5931 param_comptime_bits: ?[]u32,
5932 param_noalias_bits: ?[]u32,
5933 param_type: []Index,
5934 },
5935 .config = .{
5936 .@"trailing.param_comptime_bits.?" = .@"payload.flags.has_comptime_bits",
5937 .@"trailing.param_comptime_bits.?.len" = .@"(payload.params_len + 31) / 32",
5938 .@"trailing.param_noalias_bits.?" = .@"payload.flags.has_noalias_bits",
5939 .@"trailing.param_noalias_bits.?.len" = .@"(payload.params_len + 31) / 32",
5940 .@"trailing.param_type.len" = .@"payload.params_len",
5941 },
5379 .payload = TypeOpaque,
5380 .trailing = struct { captures: []CaptureValue },
5381 .config = .{ .@"trailing.captures.len" = .@"payload.captures_len" },
59425382 },
59435383
59445384 .undef = .{ .summary = .@"@as({.data%summary}, undefined)", .data = Index },
......@@ -5999,8 +5439,6 @@ pub const Tag = enum(u8) {
59995439 .int_small = .{ .summary = .@"@as({.payload.ty%summary}, {.payload.value%value})", .payload = IntSmall },
60005440 .int_positive = .{},
60015441 .int_negative = .{},
6002 .int_lazy_align = .{ .summary = .@"@as({.payload.ty%summary}, @alignOf({.payload.lazy_ty%summary}))", .payload = IntLazy },
6003 .int_lazy_size = .{ .summary = .@"@as({.payload.ty%summary}, @sizeOf({.payload.lazy_ty%summary}))", .payload = IntLazy },
60045442 .error_set_error = .{ .summary = .@"@as({.payload.ty%summary}, error.@{.payload.name%summary})", .payload = Error },
60055443 .error_union_error = .{ .summary = .@"@as({.payload.ty%summary}, error.@{.payload.name%summary})", .payload = Error },
60065444 .error_union_payload = .{ .summary = .@"@as({.payload.ty%summary}, {.payload.val%summary})", .payload = TypeValue },
......@@ -6049,6 +5487,7 @@ pub const Tag = enum(u8) {
60495487 .config = .{ .@"trailing.elements.len" = .@"payload.ty.payload.fields_len" },
60505488 },
60515489 .repeated = .{ .summary = .@"@as({.payload.ty%summary}, @splat({.payload.elem_val%summary}))", .payload = Repeated },
5490 .bitpack = .{ .summary = .@"@as({.payload.ty%summary}, {})", .payload = Key.Bitpack },
60525491
60535492 .memoized_call = .{
60545493 .summary = .@"@memoize({.payload.func%summary})",
......@@ -6141,194 +5580,288 @@ pub const Tag = enum(u8) {
61415580 generic_owner: Index,
61425581 };
61435582
6144 pub const FuncCoerced = struct {
6145 ty: Index,
6146 func: Index,
6147 };
5583 pub const FuncCoerced = struct {
5584 ty: Index,
5585 func: Index,
5586 };
5587
5588 /// Trailing:
5589 /// 0. name: NullTerminatedString for each names_len
5590 pub const ErrorSet = struct {
5591 names_len: u32,
5592 /// Maps error names to declaration index.
5593 names_map: MapIndex,
5594 };
5595
5596 /// Trailing:
5597 /// 0. comptime_bits: u32, // if has_comptime_bits
5598 /// 1. noalias_bits: u32, // if has_noalias_bits
5599 /// 2. param_type: Index for each params_len
5600 pub const TypeFunction = struct {
5601 params_len: u32,
5602 return_type: Index,
5603 flags: Flags,
5604
5605 pub const Flags = packed struct(u32) {
5606 cc: PackedCallingConvention,
5607 is_var_args: bool,
5608 has_comptime_bits: bool,
5609 has_noalias_bits: bool,
5610 is_noinline: bool,
5611 _: u10 = 0,
5612 };
5613 };
5614
5615 /// At first I thought of storing the denormalized data externally, such as...
5616 ///
5617 /// * runtime field order
5618 /// * calculated field offsets
5619 /// * size and alignment of the struct
5620 ///
5621 /// ...since these can be computed based on the other data here. However,
5622 /// this data does need to be memoized, and therefore stored in memory
5623 /// while the compiler is running, in order to avoid O(N^2) logic in many
5624 /// places. Since the data can be stored compactly in the InternPool
5625 /// representation, it is better for memory usage to store denormalized data
5626 /// here, and potentially also better for performance as well. It's also simpler
5627 /// than coming up with some other scheme for the data.
5628 ///
5629 /// Trailing:
5630 /// 0. type_hash: PackedU64 // if `any_captures == .reified`
5631 /// 1. captures_len: u32 // if `any_captures == .true`
5632 /// 2. capture: CaptureValue // for each `captures_len`
5633 /// 3. field_name: NullTerminatedString // for each `fields_len`
5634 /// 4. field_type: Index // for each `fields_len`
5635 /// 5. field_default: Index // if `any_field_defaults`; for each `fields_len`
5636 /// 6. field_align: Alignment // if `any_field_aligns`; for each `fields_len`
5637 /// 7. field_is_comptime_bits: u32 // if `any_comptime_fields`; minimum `u32` for `fields_len`; LSB is field 0
5638 /// 8. field_runtime_order: RuntimeOrder // if `layout == .auto`; for each `fields_len`
5639 /// 9. field_offset: u32 // for each `fields_len`
5640 pub const TypeStruct = struct {
5641 zir_index: TrackedInst.Index,
5642
5643 name: NullTerminatedString,
5644 name_nav: Nav.Index.Optional,
5645 namespace: NamespaceIndex,
5646
5647 fields_len: u32,
5648 field_name_map: MapIndex,
5649
5650 /// Size in bytes of the whole struct. Always 0 until layout resolved.
5651 size: u32,
5652
5653 flags: Flags,
5654
5655 pub const Flags = packed struct(u32) {
5656 any_captures: enum(u2) { true, false, reified },
5657
5658 /// `packed` layout is represented separately by `TypeStructPacked`.
5659 layout: enum(u1) { auto, @"extern" },
5660
5661 any_comptime_fields: bool,
5662 any_field_defaults: bool,
5663 any_field_aligns: bool,
5664
5665 class: TypeClass,
5666 /// Alignment of the whole struct. Always `.none` until layout resolved.
5667 alignment: Alignment,
5668
5669 want_layout: bool,
61485670
6149 /// Trailing:
6150 /// 0. name: NullTerminatedString for each names_len
6151 pub const ErrorSet = struct {
6152 names_len: u32,
6153 /// Maps error names to declaration index.
6154 names_map: MapIndex,
5671 _: u16 = 0,
5672 };
61555673 };
61565674
61575675 /// Trailing:
6158 /// 0. comptime_bits: u32, // if has_comptime_bits
6159 /// 1. noalias_bits: u32, // if has_noalias_bits
6160 /// 2. param_type: Index for each params_len
6161 pub const TypeFunction = struct {
6162 params_len: u32,
6163 return_type: Index,
6164 flags: Flags,
5676 /// 0. type_hash: PackedU64 // if `captures_len == .reified`
5677 /// 1. capture: CaptureValue // if `captures_len != .reified`; for each `captures_len`
5678 /// 2. field_name: NullTerminatedString // for each `fields_len`
5679 /// 3. field_type: Index // for each `fields_len`
5680 /// 4. field_default: Index // if item tag implies field defaults; for each `fields_len`
5681 pub const TypeStructPacked = struct {
5682 zir_index: TrackedInst.Index,
5683 bits: Bits,
61655684
6166 pub const Flags = packed struct(u32) {
6167 cc: PackedCallingConvention,
6168 is_var_args: bool,
6169 is_generic: bool,
6170 has_comptime_bits: bool,
6171 has_noalias_bits: bool,
6172 is_noinline: bool,
6173 _: u9 = 0,
5685 name: NullTerminatedString,
5686 name_nav: Nav.Index.Optional,
5687 namespace: NamespaceIndex,
5688
5689 /// The corresponding `BackingTypeMode` depends on the item's `Tag`.
5690 backing_int_type: Index,
5691
5692 fields_len: u32,
5693 field_name_map: MapIndex,
5694
5695 const Bits = packed struct(u32) {
5696 captures_len: enum(u31) {
5697 reified = std.math.maxInt(u31),
5698 _,
5699 },
5700 want_layout: bool,
61745701 };
61755702 };
61765703
5704 /// For declared unions, field names are intentionally omitted because they are available in
5705 /// `enum_tag_type`. However, reified unions do store field names, because they are needed by
5706 /// type resolution to create or validate the enum tag type (type resolution for declared unions
5707 /// instead fetches field names from ZIR).
5708 ///
61775709 /// Trailing:
6178 /// 0. captures_len: u32 // if `any_captures`
6179 /// 1. capture: CaptureValue // for each `captures_len`
6180 /// 2. type_hash: PackedU64 // if `is_reified`
6181 /// 3. field type: Index for each field; declaration order
6182 /// 4. field align: Alignment for each field; declaration order
5710 /// 0. type_hash: PackedU64 // if `any_captures == .reified`
5711 /// 1. captures_len: u32 // if `any_captures == .true`
5712 /// 2. capture: CaptureValue // if `any_captures == .true`; for each `captures_len`
5713 /// 3. reified_field_name: NullTerminatedString // if `any_captures == .reified`; for each `fields_len`
5714 /// 4. field_type: Index // for each `fields_len`
5715 /// 5. field_align: Alignment // for each `fields_len` if `any_field_aligns`
61835716 pub const TypeUnion = struct {
5717 zir_index: TrackedInst.Index,
5718
61845719 name: NullTerminatedString,
61855720 name_nav: Nav.Index.Optional,
6186 flags: Flags,
5721 namespace: NamespaceIndex,
5722 /// The enum that provides the list of field names and values.
5723 enum_tag_type: Index,
5724
61875725 /// This could be provided through the tag type, but it is more convenient
61885726 /// to store it directly. This is also necessary for `dumpStatsFallible` to
61895727 /// work on unresolved types.
61905728 fields_len: u32,
6191 /// Only valid after .have_layout
5729
5730 /// Always 0 until layout resolved.
61925731 size: u32,
6193 /// Only valid after .have_layout
5732 /// Always 0 until layout resolved.
61945733 padding: u32,
6195 namespace: NamespaceIndex,
6196 /// The enum that provides the list of field names and values.
6197 tag_ty: Index,
6198 zir_index: TrackedInst.Index,
5734
5735 flags: Flags,
61995736
62005737 pub const Flags = packed struct(u32) {
6201 any_captures: bool,
6202 runtime_tag: LoadedUnionType.RuntimeTag,
6203 /// If false, the field alignment trailing data is omitted.
6204 any_aligned_fields: bool,
6205 layout: std.builtin.Type.ContainerLayout,
6206 status: LoadedUnionType.Status,
6207 requires_comptime: RequiresComptime,
6208 assumed_runtime_bits: bool,
6209 assumed_pointer_aligned: bool,
5738 any_captures: enum(u2) { true, false, reified },
5739
5740 /// Whether `enum_tag_type` was explicitly specified with `union(E)` syntax.
5741 ///
5742 /// For `union(enum(E))` syntax, this is `false`, but the generated enum tag type is
5743 /// considered to have an explicitly specified integer tag type.
5744 enum_tag_mode: BackingTypeMode,
5745
5746 /// `packed` layout is represented separately by `TypeStructPacked`.
5747 layout: enum(u1) { auto, @"extern" },
5748
5749 any_field_aligns: bool,
5750 tag_usage: LoadedUnionType.TagUsage,
5751
5752 class: TypeClass,
5753 has_runtime_tag: bool,
5754
5755 /// Alignment of the whole union. Always `.none` until layout resolved.
62105756 alignment: Alignment,
6211 is_reified: bool,
6212 _: u12 = 0,
5757
5758 want_layout: bool,
5759
5760 _: u14 = 0,
62135761 };
62145762 };
62155763
5764 /// For declared unions, field names are intentionally omitted because they are available in
5765 /// `enum_tag_type`. However, reified unions do store field names, because they are needed by
5766 /// type resolution to create or validate the enum tag type (type resolution for declared unions
5767 /// instead fetches field names from ZIR).
5768 ///
62165769 /// Trailing:
6217 /// 0. captures_len: u32 // if `any_captures`
6218 /// 1. capture: CaptureValue // for each `captures_len`
6219 /// 2. type_hash: PackedU64 // if `is_reified`
6220 /// 3. type: Index for each fields_len
6221 /// 4. name: NullTerminatedString for each fields_len
6222 /// 5. init: Index for each fields_len // if tag is type_struct_packed_inits
6223 pub const TypeStructPacked = struct {
5770 /// 0. type_hash: PackedU64 // if `captures_len == .reified`
5771 /// 1. capture: CaptureValue // if `captures_len != .reified`; for each `captures_len`
5772 /// 2. reified_field_name: NullTerminatedString // if `captures_len == .reified`; for each `fields_len`
5773 /// 3. field_type: Index // for each `fields_len`
5774 pub const TypeUnionPacked = struct {
5775 zir_index: TrackedInst.Index,
5776 bits: Bits,
5777
62245778 name: NullTerminatedString,
62255779 name_nav: Nav.Index.Optional,
6226 zir_index: TrackedInst.Index,
6227 fields_len: u32,
62285780 namespace: NamespaceIndex,
6229 backing_int_ty: Index,
6230 names_map: MapIndex,
6231 flags: Flags,
62325781
6233 pub const Flags = packed struct(u32) {
6234 any_captures: bool = false,
6235 /// Dependency loop detection when resolving field inits.
6236 field_inits_wip: bool = false,
6237 inits_resolved: bool = false,
6238 is_reified: bool = false,
6239 _: u28 = 0,
5782 /// The corresponding `BackingTypeMode` depends on the item's `Tag`.
5783 backing_int_type: Index,
5784 /// Although packed unions do not semantically have a tag type, the compiler still assigns
5785 /// them a "hypothetical" tag type.
5786 enum_tag_type: Index,
5787
5788 /// This could be provided through the tag type, but it is more convenient
5789 /// to store it directly. This is also necessary for `dumpStatsFallible` to
5790 /// work on unresolved types.
5791 fields_len: u32,
5792
5793 const Bits = packed struct(u32) {
5794 captures_len: enum(u31) {
5795 reified = std.math.maxInt(u31),
5796 _,
5797 },
5798 want_layout: bool,
62405799 };
62415800 };
62425801
6243 /// At first I thought of storing the denormalized data externally, such as...
6244 ///
6245 /// * runtime field order
6246 /// * calculated field offsets
6247 /// * size and alignment of the struct
6248 ///
6249 /// ...since these can be computed based on the other data here. However,
6250 /// this data does need to be memoized, and therefore stored in memory
6251 /// while the compiler is running, in order to avoid O(N^2) logic in many
6252 /// places. Since the data can be stored compactly in the InternPool
6253 /// representation, it is better for memory usage to store denormalized data
6254 /// here, and potentially also better for performance as well. It's also simpler
6255 /// than coming up with some other scheme for the data.
6256 ///
62575802 /// Trailing:
6258 /// 0. captures_len: u32 // if `any_captures`
6259 /// 1. capture: CaptureValue // for each `captures_len`
6260 /// 2. type_hash: PackedU64 // if `is_reified`
6261 /// 3. type: Index for each field in declared order
6262 /// 4. if any_default_inits:
6263 /// init: Index // for each field in declared order
6264 /// 5. if any_aligned_fields:
6265 /// align: Alignment // for each field in declared order
6266 /// 6. if any_comptime_fields:
6267 /// field_is_comptime_bits: u32 // minimal number of u32s needed, LSB is field 0
6268 /// 7. if not is_extern:
6269 /// field_index: RuntimeOrder // for each field in runtime order
6270 /// 8. field_offset: u32 // for each field in declared order, undef until layout_resolved
6271 pub const TypeStruct = struct {
5803 /// 0. owner_union: Index // if `captures_len == .generated_union_tag`
5804 /// 1. zir_index: TrackedInst.Index // if `captures_len != .generated_union_tag`
5805 /// 2. type_hash: PackedU64 // if `captures_len == .reified`
5806 /// 3. capture: CaptureValue // if `captures_len` is not a named tag; for each `captures_len`
5807 /// 4. field_value_map: MapIndex // if tag is not `.type_enum_auto`
5808 /// 5. field_name: NullTerminatedString // for each `fields_len`
5809 /// 6. field_value: Index // if tag is not `.type_enum_auto`; for each `fields_len`
5810 pub const TypeEnum = struct {
5811 bits: Bits,
5812
62725813 name: NullTerminatedString,
62735814 name_nav: Nav.Index.Optional,
6274 zir_index: TrackedInst.Index,
62755815 namespace: NamespaceIndex,
5816
5817 /// An integer type which is used for the numerical value of the enum. Whether this was
5818 /// user-provided or inferred by the compiler depends on the tag.
5819 int_tag_type: Index,
5820
62765821 fields_len: u32,
6277 flags: Flags,
6278 size: u32,
5822 field_name_map: MapIndex,
62795823
6280 pub const Flags = packed struct(u32) {
6281 any_captures: bool = false,
6282 is_extern: bool = false,
6283 known_non_opv: bool = false,
6284 requires_comptime: RequiresComptime = @enumFromInt(0),
6285 assumed_runtime_bits: bool = false,
6286 assumed_pointer_aligned: bool = false,
6287 any_comptime_fields: bool = false,
6288 any_default_inits: bool = false,
6289 any_aligned_fields: bool = false,
6290 /// `.none` until layout_resolved
6291 alignment: Alignment = @enumFromInt(0),
6292 /// Dependency loop detection when resolving struct alignment.
6293 alignment_wip: bool = false,
6294 /// Dependency loop detection when resolving field types.
6295 field_types_wip: bool = false,
6296 /// Dependency loop detection when resolving struct layout.
6297 layout_wip: bool = false,
6298 /// Indicates whether `size`, `alignment`, runtime field order, and
6299 /// field offets are populated.
6300 layout_resolved: bool = false,
6301 /// Dependency loop detection when resolving field inits.
6302 field_inits_wip: bool = false,
6303 /// Indicates whether `field_inits` has been resolved.
6304 inits_resolved: bool = false,
6305 // The types and all its fields have had their layout resolved. Even through pointer = false,
6306 // which `layout_resolved` does not ensure.
6307 fully_resolved: bool = false,
6308 is_reified: bool = false,
6309 _: u8 = 0,
5824 const Bits = packed struct(u32) {
5825 captures_len: enum(u31) {
5826 reified = std.math.maxInt(u31),
5827 generated_union_tag = std.math.maxInt(u31) - 1,
5828 _,
5829 },
5830 want_layout: bool,
63105831 };
63115832 };
63125833
63135834 /// Trailing:
63145835 /// 0. capture: CaptureValue // for each `captures_len`
63155836 pub const TypeOpaque = struct {
5837 zir_index: TrackedInst.Index,
5838 captures_len: u32,
5839
63165840 name: NullTerminatedString,
63175841 name_nav: Nav.Index.Optional,
6318 /// Contains the declarations inside this opaque.
63195842 namespace: NamespaceIndex,
6320 /// The index of the `opaque_decl` instruction.
6321 zir_index: TrackedInst.Index,
6322 /// `std.math.maxInt(u32)` indicates this type is reified.
6323 captures_len: u32,
63245843 };
63255844};
63265845
5846/// Differentiates between user-provided and compiler-generated backing types for packed and tagged types.
5847pub const BackingTypeMode = enum(u1) {
5848 /// The backing type was explicitly provided by the user. For instance:
5849 /// union(T)
5850 /// enum(T)
5851 /// packed struct(T)
5852 /// packed union(T)
5853 /// Type layout resolution will evaluate the user-provided expression and validate that type.
5854 explicit,
5855 /// No backing type was explicitly provided by the user. Type layout resolution will populate
5856 /// an inferred/generated type.
5857 auto,
5858};
5859
63275860/// State that is mutable during semantic analysis. This data is not used for
63285861/// equality or hashing, except for `inferred_error_set` which is considered
63295862/// to be part of the type of the function.
63305863pub const FuncAnalysis = packed struct(u32) {
6331 is_analyzed: bool,
5864 want_runtime_analysis: bool,
63325865 branch_hint: std.builtin.BranchHint,
63335866 is_noinline: bool,
63345867 has_error_trace: bool,
......@@ -6399,13 +5932,9 @@ pub const SimpleType = enum(u32) {
63995932};
64005933
64015934pub const SimpleValue = enum(u32) {
6402 /// This is untyped `undefined`.
6403 undefined = @intFromEnum(Index.undef),
64045935 void = @intFromEnum(Index.void_value),
64055936 /// This is untyped `null`.
64065937 null = @intFromEnum(Index.null_value),
6407 /// This is the untyped empty struct/array literal: `.{}`
6408 empty_tuple = @intFromEnum(Index.empty_tuple),
64095938 true = @intFromEnum(Index.bool_true),
64105939 false = @intFromEnum(Index.bool_false),
64115940 @"unreachable" = @intFromEnum(Index.unreachable_value),
......@@ -6536,12 +6065,17 @@ pub const Alignment = enum(u6) {
65366065 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };
65376066
65386067 pub fn get(slice: Slice, ip: *const InternPool) []Alignment {
6539 // TODO: implement @ptrCast between slices changing the length
65406068 const extra = ip.getLocalShared(slice.tid).extra.acquire();
6541 //const bytes: []u8 = @ptrCast(extra.view().items(.@"0")[slice.start..]);
6542 const bytes: []u8 = std.mem.sliceAsBytes(extra.view().items(.@"0")[slice.start..]);
6069 const bytes: []u8 = @ptrCast(extra.view().items(.@"0")[slice.start..]);
65436070 return @ptrCast(bytes[0..slice.len]);
65446071 }
6072
6073 /// If `slice` is empty (`slice.len == 0`), returns `.none`.
6074 /// Otherwise, asserts that `index < slice.len`, and returns the value at `index`.
6075 pub fn getOrNone(slice: Slice, ip: *const InternPool, index: usize) Alignment {
6076 if (slice.len == 0) return .none;
6077 return slice.get(ip)[index];
6078 }
65456079 };
65466080
65476081 pub fn toRelaxedCompareUnits(a: Alignment) u8 {
......@@ -6596,55 +6130,6 @@ pub const Array = struct {
65966130 }
65976131};
65986132
6599/// Trailing:
6600/// 0. owner_union: Index // if `zir_index == .none`
6601/// 1. capture: CaptureValue // for each `captures_len`
6602/// 2. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`)
6603/// 3. field name: NullTerminatedString for each fields_len; declaration order
6604/// 4. tag value: Index for each fields_len; declaration order
6605pub const EnumExplicit = struct {
6606 name: NullTerminatedString,
6607 name_nav: Nav.Index.Optional,
6608 /// `std.math.maxInt(u32)` indicates this type is reified.
6609 captures_len: u32,
6610 namespace: NamespaceIndex,
6611 /// An integer type which is used for the numerical value of the enum, which
6612 /// has been explicitly provided by the enum declaration.
6613 int_tag_type: Index,
6614 fields_len: u32,
6615 /// Maps field names to declaration index.
6616 names_map: MapIndex,
6617 /// Maps field values to declaration index.
6618 /// If this is `none`, it means the trailing tag values are absent because
6619 /// they are auto-numbered.
6620 values_map: OptionalMapIndex,
6621 /// `none` means this is a generated tag type.
6622 /// There will be a trailing union type for which this is a tag.
6623 zir_index: TrackedInst.Index.Optional,
6624};
6625
6626/// Trailing:
6627/// 0. owner_union: Index // if `zir_index == .none`
6628/// 1. capture: CaptureValue // for each `captures_len`
6629/// 2. type_hash: PackedU64 // if reified (`captures_len == std.math.maxInt(u32)`)
6630/// 3. field name: NullTerminatedString for each fields_len; declaration order
6631pub const EnumAuto = struct {
6632 name: NullTerminatedString,
6633 name_nav: Nav.Index.Optional,
6634 /// `std.math.maxInt(u32)` indicates this type is reified.
6635 captures_len: u32,
6636 namespace: NamespaceIndex,
6637 /// An integer type which is used for the numerical value of the enum, which
6638 /// was inferred by Zig based on the number of tags.
6639 int_tag_type: Index,
6640 fields_len: u32,
6641 /// Maps field names to declaration index.
6642 names_map: MapIndex,
6643 /// `none` means this is a generated tag type.
6644 /// There will be a trailing union type for which this is a tag.
6645 zir_index: TrackedInst.Index.Optional,
6646};
6647
66486133pub const PackedU64 = packed struct(u64) {
66496134 a: u32,
66506135 b: u32,
......@@ -6827,11 +6312,6 @@ pub const IntSmall = struct {
68276312 value: u32,
68286313};
68296314
6830pub const IntLazy = struct {
6831 ty: Index,
6832 lazy_ty: Index,
6833};
6834
68356315/// A f64 value, broken up into 2 u32 parts.
68366316pub const Float64 = struct {
68376317 piece0: u32,
......@@ -6994,7 +6474,9 @@ pub fn deinit(ip: *InternPool, gpa: Allocator, io: Io) void {
69946474 ip.src_hash_deps.deinit(gpa);
69956475 ip.nav_val_deps.deinit(gpa);
69966476 ip.nav_ty_deps.deinit(gpa);
6997 ip.interned_deps.deinit(gpa);
6477 ip.func_ies_deps.deinit(gpa);
6478 ip.type_layout_deps.deinit(gpa);
6479 ip.struct_defaults_deps.deinit(gpa);
69986480 ip.zon_file_deps.deinit(gpa);
69996481 ip.embed_file_deps.deinit(gpa);
70006482 ip.namespace_deps.deinit(gpa);
......@@ -7130,132 +6612,118 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
71306612 .type_inferred_error_set => .{
71316613 .inferred_error_set_type = @enumFromInt(data),
71326614 },
7133
7134 .type_opaque => .{ .opaque_type = ns: {
7135 const extra = extraDataTrail(unwrapped_index.getExtra(ip), Tag.TypeOpaque, data);
7136 if (extra.data.captures_len == std.math.maxInt(u32)) {
7137 break :ns .{ .reified = .{
7138 .zir_index = extra.data.zir_index,
7139 .type_hash = 0,
7140 } };
7141 }
7142 break :ns .{ .declared = .{
7143 .zir_index = extra.data.zir_index,
7144 .captures = .{ .owned = .{
7145 .tid = unwrapped_index.tid,
7146 .start = extra.end,
7147 .len = extra.data.captures_len,
7148 } },
7149 } };
7150 } },
6615 .type_function => .{ .func_type = extraFuncType(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
6616 .type_tuple => .{ .tuple_type = extraTypeTuple(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
71516617
71526618 .type_struct => .{ .struct_type = ns: {
71536619 const extra_list = unwrapped_index.getExtra(ip);
7154 const extra_items = extra_list.view().items(.@"0");
7155 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);
7156 const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .unordered));
7157 const end_extra_index = data + @as(u32, @typeInfo(Tag.TypeStruct).@"struct".fields.len);
7158 if (flags.is_reified) {
7159 assert(!flags.any_captures);
7160 break :ns .{ .reified = .{
7161 .zir_index = zir_index,
7162 .type_hash = extraData(extra_list, PackedU64, end_extra_index).get(),
7163 } };
7164 }
7165 break :ns .{ .declared = .{
7166 .zir_index = zir_index,
7167 .captures = .{ .owned = if (flags.any_captures) .{
7168 .tid = unwrapped_index.tid,
7169 .start = end_extra_index + 1,
7170 .len = extra_list.view().items(.@"0")[end_extra_index],
7171 } else CaptureValue.Slice.empty },
7172 } };
6620 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);
6621 break :ns switch (extra.data.flags.any_captures) {
6622 .reified => .{ .reified = .{
6623 .zir_index = extra.data.zir_index,
6624 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
6625 } },
6626 .false => .{ .declared = .{
6627 .zir_index = extra.data.zir_index,
6628 .captures = .{ .owned = .empty },
6629 } },
6630 .true => .{ .declared = .{
6631 .zir_index = extra.data.zir_index,
6632 .captures = .{ .owned = .{
6633 .tid = unwrapped_index.tid,
6634 .start = extra.end + 1,
6635 .len = extra_list.view().items(.@"0")[extra.end],
6636 } },
6637 } },
6638 };
71736639 } },
7174
7175 .type_struct_packed, .type_struct_packed_inits => .{ .struct_type = ns: {
6640 .type_struct_packed_auto,
6641 .type_struct_packed_explicit,
6642 .type_struct_packed_auto_defaults,
6643 .type_struct_packed_explicit_defaults,
6644 => .{ .struct_type = ns: {
71766645 const extra_list = unwrapped_index.getExtra(ip);
7177 const extra_items = extra_list.view().items(.@"0");
7178 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]);
7179 const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .unordered));
7180 const end_extra_index = data + @as(u32, @typeInfo(Tag.TypeStructPacked).@"struct".fields.len);
7181 if (flags.is_reified) {
7182 assert(!flags.any_captures);
7183 break :ns .{ .reified = .{
7184 .zir_index = zir_index,
7185 .type_hash = extraData(extra_list, PackedU64, end_extra_index).get(),
7186 } };
7187 }
7188 break :ns .{ .declared = .{
7189 .zir_index = zir_index,
7190 .captures = .{ .owned = if (flags.any_captures) .{
7191 .tid = unwrapped_index.tid,
7192 .start = end_extra_index + 1,
7193 .len = extra_items[end_extra_index],
7194 } else CaptureValue.Slice.empty },
7195 } };
6646 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
6647 break :ns switch (extra.data.bits.captures_len) {
6648 .reified => .{ .reified = .{
6649 .zir_index = extra.data.zir_index,
6650 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
6651 } },
6652 _ => |len| .{ .declared = .{
6653 .zir_index = extra.data.zir_index,
6654 .captures = .{ .owned = .{
6655 .tid = unwrapped_index.tid,
6656 .start = extra.end,
6657 .len = @intFromEnum(len),
6658 } },
6659 } },
6660 };
71966661 } },
7197 .type_tuple => .{ .tuple_type = extraTypeTuple(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
71986662 .type_union => .{ .union_type = ns: {
71996663 const extra_list = unwrapped_index.getExtra(ip);
72006664 const extra = extraDataTrail(extra_list, Tag.TypeUnion, data);
7201 if (extra.data.flags.is_reified) {
7202 assert(!extra.data.flags.any_captures);
7203 break :ns .{ .reified = .{
6665 break :ns switch (extra.data.flags.any_captures) {
6666 .reified => .{ .reified = .{
72046667 .zir_index = extra.data.zir_index,
72056668 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
7206 } };
7207 }
7208 break :ns .{ .declared = .{
7209 .zir_index = extra.data.zir_index,
7210 .captures = .{ .owned = if (extra.data.flags.any_captures) .{
7211 .tid = unwrapped_index.tid,
7212 .start = extra.end + 1,
7213 .len = extra_list.view().items(.@"0")[extra.end],
7214 } else CaptureValue.Slice.empty },
7215 } };
6669 } },
6670 .false => .{ .declared = .{
6671 .zir_index = extra.data.zir_index,
6672 .captures = .{ .owned = .empty },
6673 } },
6674 .true => .{ .declared = .{
6675 .zir_index = extra.data.zir_index,
6676 .captures = .{ .owned = .{
6677 .tid = unwrapped_index.tid,
6678 .start = extra.end + 1,
6679 .len = extra_list.view().items(.@"0")[extra.end],
6680 } },
6681 } },
6682 };
72166683 } },
7217
7218 .type_enum_auto => .{ .enum_type = ns: {
6684 .type_union_packed_auto, .type_union_packed_explicit => .{ .union_type = ns: {
72196685 const extra_list = unwrapped_index.getExtra(ip);
7220 const extra = extraDataTrail(extra_list, EnumAuto, data);
7221 const zir_index = extra.data.zir_index.unwrap() orelse {
7222 assert(extra.data.captures_len == 0);
7223 break :ns .{ .generated_tag = .{
7224 .union_type = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),
7225 } };
7226 };
7227 if (extra.data.captures_len == std.math.maxInt(u32)) {
7228 break :ns .{ .reified = .{
7229 .zir_index = zir_index,
6686 const extra = extraDataTrail(extra_list, Tag.TypeUnionPacked, data);
6687 break :ns switch (extra.data.bits.captures_len) {
6688 .reified => .{ .reified = .{
6689 .zir_index = extra.data.zir_index,
72306690 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
7231 } };
7232 }
7233 break :ns .{ .declared = .{
7234 .zir_index = zir_index,
7235 .captures = .{ .owned = .{
7236 .tid = unwrapped_index.tid,
7237 .start = extra.end,
7238 .len = extra.data.captures_len,
72396691 } },
7240 } };
6692 _ => |len| .{ .declared = .{
6693 .zir_index = extra.data.zir_index,
6694 .captures = .{ .owned = .{
6695 .tid = unwrapped_index.tid,
6696 .start = extra.end,
6697 .len = @intFromEnum(len),
6698 } },
6699 } },
6700 };
72416701 } },
7242 .type_enum_explicit, .type_enum_nonexhaustive => .{ .enum_type = ns: {
6702 .type_enum_auto, .type_enum_explicit, .type_enum_nonexhaustive => .{ .enum_type = ns: {
72436703 const extra_list = unwrapped_index.getExtra(ip);
7244 const extra = extraDataTrail(extra_list, EnumExplicit, data);
7245 const zir_index = extra.data.zir_index.unwrap() orelse {
7246 assert(extra.data.captures_len == 0);
7247 break :ns .{ .generated_tag = .{
7248 .union_type = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),
7249 } };
6704 const extra = extraDataTrail(extra_list, Tag.TypeEnum, data);
6705 break :ns switch (extra.data.bits.captures_len) {
6706 .reified => .{ .reified = .{
6707 .zir_index = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),
6708 .type_hash = extraData(extra_list, PackedU64, extra.end + 1).get(),
6709 } },
6710 .generated_union_tag => .{ .generated_union_tag = owner_union: {
6711 break :owner_union @enumFromInt(extra_list.view().items(.@"0")[extra.end]);
6712 } },
6713 _ => |len| .{ .declared = .{
6714 .zir_index = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),
6715 .captures = .{ .owned = .{
6716 .tid = unwrapped_index.tid,
6717 .start = extra.end + 1,
6718 .len = @intFromEnum(len),
6719 } },
6720 } },
72506721 };
7251 if (extra.data.captures_len == std.math.maxInt(u32)) {
7252 break :ns .{ .reified = .{
7253 .zir_index = zir_index,
7254 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
7255 } };
7256 }
6722 } },
6723 .type_opaque => .{ .opaque_type = ns: {
6724 const extra = extraDataTrail(unwrapped_index.getExtra(ip), Tag.TypeOpaque, data);
72576725 break :ns .{ .declared = .{
7258 .zir_index = zir_index,
6726 .zir_index = extra.data.zir_index,
72596727 .captures = .{ .owned = .{
72606728 .tid = unwrapped_index.tid,
72616729 .start = extra.end,
......@@ -7263,7 +6731,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
72636731 } },
72646732 } };
72656733 } },
7266 .type_function => .{ .func_type = extraFuncType(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
72676734
72686735 .undef => .{ .undef = @enumFromInt(data) },
72696736 .opt_null => .{ .opt = .{
......@@ -7390,17 +6857,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
73906857 .storage = .{ .u64 = info.value },
73916858 } };
73926859 },
7393 .int_lazy_align, .int_lazy_size => |tag| {
7394 const info = extraData(unwrapped_index.getExtra(ip), IntLazy, data);
7395 return .{ .int = .{
7396 .ty = info.ty,
7397 .storage = switch (tag) {
7398 .int_lazy_align => .{ .lazy_align = info.lazy_ty },
7399 .int_lazy_size => .{ .lazy_size = info.lazy_ty },
7400 else => unreachable,
7401 },
7402 } };
7403 },
74046860 .float_f16 => .{ .float = .{
74056861 .ty = .f16_type,
74066862 .storage = .{ .f16 = @bitCast(@as(u16, @intCast(data))) },
......@@ -7488,7 +6944,8 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
74886944 },
74896945 .type_array_small,
74906946 .type_vector,
7491 .type_struct_packed,
6947 .type_struct_packed_auto,
6948 .type_struct_packed_explicit,
74926949 => .{ .aggregate = .{
74936950 .ty = ty,
74946951 .storage = .{ .elems = &.{} },
......@@ -7496,11 +6953,14 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
74966953
74976954 // There is only one possible value precisely due to the
74986955 // fact that this values slice is fully populated!
7499 .type_struct, .type_struct_packed_inits => {
6956 .type_struct,
6957 .type_struct_packed_auto_defaults,
6958 .type_struct_packed_explicit_defaults,
6959 => {
75006960 const info = loadStructType(ip, ty);
75016961 return .{ .aggregate = .{
75026962 .ty = ty,
7503 .storage = .{ .elems = @ptrCast(info.field_inits.get(ip)) },
6963 .storage = .{ .elems = @ptrCast(info.field_defaults.get(ip)) },
75046964 } };
75056965 },
75066966
......@@ -7516,11 +6976,6 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
75166976 } };
75176977 },
75186978
7519 .type_enum_auto,
7520 .type_enum_explicit,
7521 .type_union,
7522 => .{ .empty_enum_value = ty },
7523
75246979 else => unreachable,
75256980 };
75266981 },
......@@ -7566,6 +7021,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
75667021 },
75677022 .enum_literal => .{ .enum_literal = @enumFromInt(data) },
75687023 .enum_tag => .{ .enum_tag = extraData(unwrapped_index.getExtra(ip), Tag.EnumTag, data) },
7024 .bitpack => .{ .bitpack = extraData(unwrapped_index.getExtra(ip), Key.Bitpack, data) },
75697025
75707026 .memoized_call => {
75717027 const extra_list = unwrapped_index.getExtra(ip);
......@@ -7634,7 +7090,6 @@ fn extraFuncType(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke
76347090 .cc = type_function.data.flags.cc.unpack(),
76357091 .is_var_args = type_function.data.flags.is_var_args,
76367092 .is_noinline = type_function.data.flags.is_noinline,
7637 .is_generic = type_function.data.flags.is_generic,
76387093 };
76397094}
76407095
......@@ -7893,45 +7348,6 @@ fn getOrPutKeyEnsuringAdditionalCapacity(
78937348 .map_index = map_index,
78947349 } };
78957350}
7896/// Like `getOrPutKey`, but asserts that the key already exists, and prepares to replace
7897/// its shard entry with a new `Index` anyway. After finalizing this, the old index remains
7898/// valid (in that `indexToKey` and similar queries will behave as before), but it will
7899/// never be returned from a lookup (`getOrPutKey` etc).
7900/// This is used by incremental compilation when an existing container type is outdated. In
7901/// this case, the type must be recreated at a new `InternPool.Index`, but the old index must
7902/// remain valid since now-unreferenced `AnalUnit`s may retain references to it. The old index
7903/// will be cleaned up when the `Zcu` undergoes garbage collection.
7904fn putKeyReplace(
7905 ip: *InternPool,
7906 io: Io,
7907 tid: Zcu.PerThread.Id,
7908 key: Key,
7909) GetOrPutKey {
7910 const full_hash = key.hash64(ip);
7911 const hash: u32 = @truncate(full_hash >> 32);
7912 const shard = &ip.shards[@intCast(full_hash & (ip.shards.len - 1))];
7913 shard.mutate.map.mutex.lock(io, tid);
7914 errdefer shard.mutate.map.mutex.unlock(io);
7915 const map = shard.shared.map;
7916 const map_mask = map.header().mask();
7917 var map_index = hash;
7918 while (true) : (map_index += 1) {
7919 map_index &= map_mask;
7920 const entry = &map.entries[map_index];
7921 const index = entry.value;
7922 assert(index != .none); // key not present
7923 if (entry.hash == hash and ip.indexToKey(index).eql(key, ip)) {
7924 break; // we found the entry to replace
7925 }
7926 }
7927 return .{ .new = .{
7928 .ip = ip,
7929 .tid = tid,
7930 .io = io,
7931 .shard = shard,
7932 .map_index = map_index,
7933 } };
7934}
79357351
79367352pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: Key) Allocator.Error!Index {
79377353 var gop = try ip.getOrPutKey(gpa, io, tid, key);
......@@ -8084,12 +7500,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
80847500 });
80857501 },
80867502
8087 .struct_type => unreachable, // use getStructType() instead
8088 .tuple_type => unreachable, // use getTupleType() instead
8089 .union_type => unreachable, // use getUnionType() instead
8090 .opaque_type => unreachable, // use getOpaqueType() instead
7503 .struct_type => unreachable, // instead use: getDeclaredStructType, getReifiedStructType
7504 .union_type => unreachable, // instead use: getDeclaredUnionType, getReifiedUnionType
7505 .enum_type => unreachable, // instead use: getDeclaredEnumType, getReifiedEnumType, getGeneratedEnumTagType
7506 .opaque_type => unreachable, // instead use: getDeclaredOpaqueType
80917507
8092 .enum_type => unreachable, // use getEnumType() instead
7508 .tuple_type => unreachable, // use getTupleType() instead
80937509 .func_type => unreachable, // use getFuncType() instead
80947510 .@"extern" => unreachable, // use getExtern() instead
80957511 .func => unreachable, // use getFuncInstance() or getFuncDecl() instead
......@@ -8247,25 +7663,8 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
82477663 });
82487664 },
82497665
8250 .int => |int| b: {
8251 assert(ip.isIntegerType(int.ty));
8252 switch (int.storage) {
8253 .u64, .i64, .big_int => {},
8254 .lazy_align, .lazy_size => |lazy_ty| {
8255 items.appendAssumeCapacity(.{
8256 .tag = switch (int.storage) {
8257 else => unreachable,
8258 .lazy_align => .int_lazy_align,
8259 .lazy_size => .int_lazy_size,
8260 },
8261 .data = try addExtra(extra, IntLazy{
8262 .ty = int.ty,
8263 .lazy_ty = lazy_ty,
8264 }),
8265 });
8266 return gop.put();
8267 },
8268 }
7666 .int => |int| b: {
7667 assert(ip.isIntegerType(int.ty));
82697668 switch (int.ty) {
82707669 .u8_type => switch (int.storage) {
82717670 .big_int => |big_int| {
......@@ -8282,7 +7681,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
82827681 });
82837682 break :b;
82847683 },
8285 .lazy_align, .lazy_size => unreachable,
82867684 },
82877685 .u16_type => switch (int.storage) {
82887686 .big_int => |big_int| {
......@@ -8299,7 +7697,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
82997697 });
83007698 break :b;
83017699 },
8302 .lazy_align, .lazy_size => unreachable,
83037700 },
83047701 .u32_type => switch (int.storage) {
83057702 .big_int => |big_int| {
......@@ -8316,7 +7713,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
83167713 });
83177714 break :b;
83187715 },
8319 .lazy_align, .lazy_size => unreachable,
83207716 },
83217717 .i32_type => switch (int.storage) {
83227718 .big_int => |big_int| {
......@@ -8334,7 +7730,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
83347730 });
83357731 break :b;
83367732 },
8337 .lazy_align, .lazy_size => unreachable,
83387733 },
83397734 .usize_type => switch (int.storage) {
83407735 .big_int => |big_int| {
......@@ -8355,7 +7750,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
83557750 break :b;
83567751 }
83577752 },
8358 .lazy_align, .lazy_size => unreachable,
83597753 },
83607754 .comptime_int_type => switch (int.storage) {
83617755 .big_int => |big_int| {
......@@ -8390,7 +7784,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
83907784 break :b;
83917785 }
83927786 },
8393 .lazy_align, .lazy_size => unreachable,
83947787 },
83957788 else => {},
83967789 }
......@@ -8427,7 +7820,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
84277820 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;
84287821 try addInt(ip, gpa, io, tid, int.ty, tag, big_int.limbs);
84297822 },
8430 .lazy_align, .lazy_size => unreachable,
84317823 }
84327824 },
84337825
......@@ -8468,7 +7860,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
84687860 assert(ip.isEnumType(enum_tag.ty));
84697861 switch (ip.indexToKey(enum_tag.ty)) {
84707862 .simple_type => assert(ip.isIntegerType(ip.typeOf(enum_tag.int))),
8471 .enum_type => assert(ip.typeOf(enum_tag.int) == ip.loadEnumType(enum_tag.ty).tag_ty),
7863 .enum_type => assert(ip.typeOf(enum_tag.int) == ip.loadEnumType(enum_tag.ty).int_tag_type),
84727864 else => unreachable,
84737865 }
84747866 items.appendAssumeCapacity(.{
......@@ -8477,11 +7869,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
84777869 });
84787870 },
84797871
8480 .empty_enum_value => |enum_or_union_ty| items.appendAssumeCapacity(.{
8481 .tag = .only_possible_value,
8482 .data = @intFromEnum(enum_or_union_ty),
8483 }),
8484
84857872 .float => |float| {
84867873 switch (float.ty) {
84877874 .f16_type => items.appendAssumeCapacity(.{
......@@ -8525,15 +7912,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
85257912 .aggregate => |aggregate| {
85267913 const ty_key = ip.indexToKey(aggregate.ty);
85277914 const len = ip.aggregateTypeLen(aggregate.ty);
8528 const child = switch (ty_key) {
8529 .array_type => |array_type| array_type.child,
8530 .vector_type => |vector_type| vector_type.child,
8531 .tuple_type, .struct_type => .none,
8532 else => unreachable,
8533 };
8534 const sentinel = switch (ty_key) {
8535 .array_type => |array_type| array_type.sentinel,
8536 .vector_type, .tuple_type, .struct_type => .none,
7915 const child: Index, const sentinel: Index = switch (ty_key) {
7916 .array_type => |array_type| .{ array_type.child, array_type.sentinel },
7917 .vector_type => |vector_type| .{ vector_type.child, .none },
7918 .tuple_type => .{ .none, .none },
7919 .struct_type => child: {
7920 assert(ip.loadStructType(aggregate.ty).layout != .@"packed");
7921 break :child .{ .none, .none };
7922 },
85377923 else => unreachable,
85387924 };
85397925 const len_including_sentinel = len + @intFromBool(sentinel != .none);
......@@ -8715,224 +8101,929 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key:
87158101 extra.appendSliceAssumeCapacity(.{@ptrCast(aggregate.storage.elems)});
87168102 if (sentinel != .none) extra.appendAssumeCapacity(.{@intFromEnum(sentinel)});
87178103 },
8104 .bitpack => |bitpack| {
8105 switch (ip.zigTypeTag(bitpack.ty)) {
8106 .@"struct" => assert(ip.typeOf(bitpack.backing_int_val) == ip.loadStructType(bitpack.ty).packed_backing_int_type),
8107 .@"union" => assert(ip.typeOf(bitpack.backing_int_val) == ip.loadUnionType(bitpack.ty).packed_backing_int_type),
8108 else => unreachable,
8109 }
8110 assert(!ip.isUndef(bitpack.backing_int_val));
8111 items.appendAssumeCapacity(.{
8112 .tag = .bitpack,
8113 .data = try addExtra(extra, bitpack),
8114 });
8115 },
87188116
87198117 .memoized_call => |memoized_call| {
87208118 for (memoized_call.arg_values) |arg| assert(arg != .none);
87218119 try extra.ensureUnusedCapacity(@typeInfo(MemoizedCall).@"struct".fields.len +
87228120 memoized_call.arg_values.len);
87238121 items.appendAssumeCapacity(.{
8724 .tag = .memoized_call,
8725 .data = addExtraAssumeCapacity(extra, MemoizedCall{
8726 .func = memoized_call.func,
8727 .args_len = @intCast(memoized_call.arg_values.len),
8728 .result = memoized_call.result,
8729 .branch_count = memoized_call.branch_count,
8730 }),
8122 .tag = .memoized_call,
8123 .data = addExtraAssumeCapacity(extra, MemoizedCall{
8124 .func = memoized_call.func,
8125 .args_len = @intCast(memoized_call.arg_values.len),
8126 .result = memoized_call.result,
8127 .branch_count = memoized_call.branch_count,
8128 }),
8129 });
8130 extra.appendSliceAssumeCapacity(.{@ptrCast(memoized_call.arg_values)});
8131 },
8132 }
8133 return gop.put();
8134}
8135
8136pub fn getDeclaredStructType(
8137 ip: *InternPool,
8138 gpa: Allocator,
8139 io: Io,
8140 tid: Zcu.PerThread.Id,
8141 ini: struct {
8142 zir_index: TrackedInst.Index,
8143 captures: []const CaptureValue,
8144
8145 // If the value of any of the following fields would change on an incremental update, then logic
8146 // in `Zcu.mapOldZirToNew` must detect that (these properties are all trivially known from ZIR)
8147 // and refuse to map the type declaration. This causes `zir_index` to change so that a new type
8148 // will be interned at a fresh index.
8149 //
8150 // In the future, it would be good to remove all of those fields from `ini`, and in fact just
8151 // have a single function `getDeclaredContainer` which is suitable for all container types.
8152 // However, this requires some major changes to how container types are represented in the
8153 // InternPool, so that it is possible for their backing storage to be "reallocated" as needed
8154 // during type resolution.
8155 fields_len: u32,
8156 layout: std.builtin.Type.ContainerLayout,
8157 any_comptime_fields: bool,
8158 any_field_defaults: bool,
8159 any_field_aligns: bool,
8160 packed_backing_mode: BackingTypeMode,
8161 },
8162) Allocator.Error!WipContainerType.Result {
8163 var gop = try ip.getOrPutKey(gpa, io, tid, .{ .struct_type = .{ .declared = .{
8164 .zir_index = ini.zir_index,
8165 .captures = .{ .external = ini.captures },
8166 } } });
8167 defer gop.deinit();
8168 if (gop == .existing) return .{ .existing = gop.existing };
8169
8170 const local = ip.getLocal(tid);
8171 const items = local.getMutableItems(gpa, io);
8172 const extra = local.getMutableExtra(gpa, io);
8173 try items.ensureUnusedCapacity(1);
8174
8175 const field_name_map = try ip.addMap(gpa, io, tid, ini.fields_len);
8176 errdefer local.mutate.maps.len -= 1;
8177
8178 const is_extern = switch (ini.layout) {
8179 .auto => false,
8180 .@"extern" => true,
8181 .@"packed" => {
8182 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStructPacked).@"struct".fields.len +
8183 ini.captures.len + // capture
8184 ini.fields_len + // field_name
8185 ini.fields_len + // field_type
8186 (if (ini.any_field_defaults) ini.fields_len else 0)); // field_default
8187
8188 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{
8189 .zir_index = ini.zir_index,
8190 .bits = .{
8191 .captures_len = @enumFromInt(ini.captures.len),
8192 .want_layout = false,
8193 },
8194 .name = undefined, // set by `finish`
8195 .name_nav = undefined, // set by `finish`
8196 .namespace = undefined, // set by `finish`
8197 .backing_int_type = .none,
8198 .fields_len = ini.fields_len,
8199 .field_name_map = field_name_map,
8200 });
8201 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.captures)}); // capture
8202 extra.appendNTimesAssumeCapacity(.{@intFromEnum(NullTerminatedString.empty)}, ini.fields_len); // field_name
8203 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len); // field_type
8204 if (ini.any_field_defaults) {
8205 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len); // field_default
8206 }
8207 items.appendAssumeCapacity(.{
8208 .tag = switch (ini.packed_backing_mode) {
8209 .auto => if (ini.any_field_defaults) .type_struct_packed_auto_defaults else .type_struct_packed_auto,
8210 .explicit => if (ini.any_field_defaults) .type_struct_packed_explicit_defaults else .type_struct_packed_explicit,
8211 },
8212 .data = extra_index,
8213 });
8214 return .{ .wip = .{
8215 .index = gop.put(),
8216 .tid = tid,
8217 .type_name_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "name").?,
8218 .name_nav_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "name_nav").?,
8219 .namespace_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?,
8220 .field_names = undefined,
8221 .field_types = undefined,
8222 .field_values = undefined,
8223 .field_aligns = undefined,
8224 .field_is_comptime_bits = undefined,
8225 } };
8226 },
8227 };
8228
8229 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStruct).@"struct".fields.len +
8230 1 + // captures_len
8231 ini.captures.len + // capture
8232 ini.fields_len + // field_name
8233 ini.fields_len + // field_type
8234 (if (ini.any_field_defaults) ini.fields_len else 0) + // field_default
8235 (if (ini.any_field_aligns) (ini.fields_len + 3) / 4 else 0) + // field_align
8236 (if (ini.any_comptime_fields) (ini.fields_len + 31) / 32 else 0) + // field_is_comptime_bits
8237 (if (!is_extern) ini.fields_len else 0) + // field_runtime_order
8238 ini.fields_len); // field_offset
8239
8240 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStruct{
8241 .zir_index = ini.zir_index,
8242 .name = undefined, // set by `finish`
8243 .name_nav = undefined, // set by `finish`
8244 .namespace = undefined, // set by `finish`
8245 .fields_len = ini.fields_len,
8246 .field_name_map = field_name_map,
8247 .size = 0,
8248 .flags = .{
8249 .any_captures = if (ini.captures.len != 0) .true else .false,
8250 .layout = if (is_extern) .@"extern" else .auto,
8251 .any_comptime_fields = ini.any_comptime_fields,
8252 .any_field_defaults = ini.any_field_defaults,
8253 .any_field_aligns = ini.any_field_aligns,
8254 .class = .no_possible_value,
8255 .alignment = .none,
8256 .want_layout = false,
8257 },
8258 });
8259 if (ini.captures.len != 0) {
8260 extra.appendAssumeCapacity(.{@intCast(ini.captures.len)}); // captures_len
8261 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.captures)}); // capture
8262 }
8263 extra.appendNTimesAssumeCapacity(.{@intFromEnum(NullTerminatedString.empty)}, ini.fields_len); // field_name
8264 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len); // field_type
8265 if (ini.any_field_defaults) {
8266 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len); // field_default
8267 }
8268 if (ini.any_field_aligns) {
8269 extra.appendNTimesAssumeCapacity(.{0}, (ini.fields_len + 3) / 4); // field_align
8270 }
8271 if (ini.any_comptime_fields) {
8272 extra.appendNTimesAssumeCapacity(.{0}, (ini.fields_len + 31) / 32); // field_is_comptime_bits
8273 }
8274 if (!is_extern) {
8275 extra.appendNTimesAssumeCapacity(.{@intFromEnum(LoadedStructType.RuntimeOrder.unresolved)}, ini.fields_len); // field_runtime_order
8276 }
8277 extra.appendNTimesAssumeCapacity(.{0}, ini.fields_len); // field_offset
8278 items.appendAssumeCapacity(.{
8279 .tag = .type_struct,
8280 .data = extra_index,
8281 });
8282 return .{ .wip = .{
8283 .index = gop.put(),
8284 .tid = tid,
8285 .type_name_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "name").?,
8286 .name_nav_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "name_nav").?,
8287 .namespace_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "namespace").?,
8288 .field_names = undefined,
8289 .field_types = undefined,
8290 .field_values = undefined,
8291 .field_aligns = undefined,
8292 .field_is_comptime_bits = undefined,
8293 } };
8294}
8295
8296pub fn getReifiedStructType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, ini: struct {
8297 zir_index: TrackedInst.Index,
8298 type_hash: u64,
8299 fields_len: u32,
8300 layout: std.builtin.Type.ContainerLayout,
8301 any_comptime_fields: bool,
8302 any_field_defaults: bool,
8303 any_field_aligns: bool,
8304 /// Explicitly specified backing int type. `.none` if not packed or if backing type is inferred.
8305 packed_backing_int_type: Index,
8306}) Allocator.Error!WipContainerType.Result {
8307 var gop = try ip.getOrPutKey(gpa, io, tid, .{ .struct_type = .{ .reified = .{
8308 .zir_index = ini.zir_index,
8309 .type_hash = ini.type_hash,
8310 } } });
8311 defer gop.deinit();
8312 if (gop == .existing) return .{ .existing = gop.existing };
8313
8314 const local = ip.getLocal(tid);
8315 const items = local.getMutableItems(gpa, io);
8316 const extra = local.getMutableExtra(gpa, io);
8317 try items.ensureUnusedCapacity(1);
8318
8319 const field_name_map = try ip.addMap(gpa, io, tid, ini.fields_len);
8320 errdefer local.mutate.maps.len -= 1;
8321
8322 const is_extern = switch (ini.layout) {
8323 .auto => false,
8324 .@"extern" => true,
8325 .@"packed" => {
8326 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStructPacked).@"struct".fields.len +
8327 2 + // type_hash
8328 ini.fields_len + // field_name
8329 ini.fields_len + // field_type
8330 (if (ini.any_field_defaults) ini.fields_len else 0)); // field_default
8331
8332 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{
8333 .zir_index = ini.zir_index,
8334 .bits = .{
8335 .captures_len = .reified,
8336 .want_layout = false,
8337 },
8338 .name = undefined, // set by `finish`
8339 .name_nav = undefined, // set by `finish`
8340 .namespace = undefined, // set by `finish`
8341 .backing_int_type = ini.packed_backing_int_type,
8342 .fields_len = ini.fields_len,
8343 .field_name_map = field_name_map,
8344 });
8345 _ = addExtraAssumeCapacity(extra, PackedU64.init(ini.type_hash)); // type_hash
8346 const field_names_start = extra.mutate.len;
8347 extra.appendNTimesAssumeCapacity(.{@intFromEnum(NullTerminatedString.empty)}, ini.fields_len); // field_name
8348 const field_types_start = extra.mutate.len;
8349 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len); // field_type
8350 const field_defaults_start = extra.mutate.len;
8351 if (ini.any_field_defaults) {
8352 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len); // field_default
8353 }
8354 items.appendAssumeCapacity(.{
8355 .tag = switch (ini.packed_backing_int_type) {
8356 .none => if (ini.any_field_defaults) .type_struct_packed_auto_defaults else .type_struct_packed_auto,
8357 else => if (ini.any_field_defaults) .type_struct_packed_explicit_defaults else .type_struct_packed_explicit,
8358 },
8359 .data = extra_index,
8360 });
8361 return .{ .wip = .{
8362 .index = gop.put(),
8363 .tid = tid,
8364 .type_name_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "name").?,
8365 .name_nav_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "name_nav").?,
8366 .namespace_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?,
8367 .field_names = .{ .tid = tid, .start = field_names_start, .len = ini.fields_len },
8368 .field_types = .{ .tid = tid, .start = field_types_start, .len = ini.fields_len },
8369 .field_values = if (ini.any_field_defaults)
8370 .{ .tid = tid, .start = field_defaults_start, .len = ini.fields_len }
8371 else
8372 undefined,
8373 .field_aligns = undefined,
8374 .field_is_comptime_bits = undefined,
8375 } };
8376 },
8377 };
8378
8379 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStruct).@"struct".fields.len +
8380 2 + // type_hash
8381 ini.fields_len + // field_name
8382 ini.fields_len + // field_type
8383 (if (ini.any_field_defaults) ini.fields_len else 0) + // field_default
8384 (if (ini.any_field_aligns) (ini.fields_len + 3) / 4 else 0) + // field_align
8385 (if (ini.any_comptime_fields) (ini.fields_len + 31) / 32 else 0) + // field_is_comptime_bits
8386 (if (!is_extern) ini.fields_len else 0) + // field_runtime_order
8387 ini.fields_len); // field_offset
8388
8389 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStruct{
8390 .zir_index = ini.zir_index,
8391 .name = undefined, // set by `finish`
8392 .name_nav = undefined, // set by `finish`
8393 .namespace = undefined, // set by `finish`
8394 .fields_len = ini.fields_len,
8395 .field_name_map = field_name_map,
8396 .size = 0,
8397 .flags = .{
8398 .any_captures = .reified,
8399 .layout = if (is_extern) .@"extern" else .auto,
8400 .any_comptime_fields = ini.any_comptime_fields,
8401 .any_field_defaults = ini.any_field_defaults,
8402 .any_field_aligns = ini.any_field_aligns,
8403 .class = .no_possible_value,
8404 .alignment = .none,
8405 .want_layout = false,
8406 },
8407 });
8408 _ = addExtraAssumeCapacity(extra, PackedU64.init(ini.type_hash)); // type_hash
8409 const field_names_start = extra.mutate.len;
8410 extra.appendNTimesAssumeCapacity(.{@intFromEnum(NullTerminatedString.empty)}, ini.fields_len); // field_name
8411 const field_types_start = extra.mutate.len;
8412 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len); // field_type
8413 const field_defaults_start = extra.mutate.len;
8414 if (ini.any_field_defaults) {
8415 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len); // field_default
8416 }
8417 const field_aligns_start = extra.mutate.len;
8418 if (ini.any_field_aligns) {
8419 extra.appendNTimesAssumeCapacity(.{0}, (ini.fields_len + 3) / 4); // field_align
8420 }
8421 const field_is_comptime_bits_start = extra.mutate.len;
8422 if (ini.any_comptime_fields) {
8423 extra.appendNTimesAssumeCapacity(.{0}, (ini.fields_len + 31) / 32); // field_is_comptime_bits
8424 }
8425 if (!is_extern) {
8426 extra.appendNTimesAssumeCapacity(.{@intFromEnum(LoadedStructType.RuntimeOrder.unresolved)}, ini.fields_len); // field_runtime_order
8427 }
8428 extra.appendNTimesAssumeCapacity(.{0}, ini.fields_len); // field_offset
8429 items.appendAssumeCapacity(.{
8430 .tag = .type_struct,
8431 .data = extra_index,
8432 });
8433 return .{ .wip = .{
8434 .index = gop.put(),
8435 .tid = tid,
8436 .type_name_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "name").?,
8437 .name_nav_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "name_nav").?,
8438 .namespace_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "namespace").?,
8439 .field_names = .{ .tid = tid, .start = field_names_start, .len = ini.fields_len },
8440 .field_types = .{ .tid = tid, .start = field_types_start, .len = ini.fields_len },
8441 .field_values = if (ini.any_field_defaults)
8442 .{ .tid = tid, .start = field_defaults_start, .len = ini.fields_len }
8443 else
8444 undefined,
8445 .field_aligns = if (ini.any_field_aligns)
8446 .{ .tid = tid, .start = field_aligns_start, .len = ini.fields_len }
8447 else
8448 undefined,
8449 .field_is_comptime_bits = if (ini.any_comptime_fields)
8450 .{ .tid = tid, .start = field_is_comptime_bits_start, .len = (ini.fields_len + 31) / 32 }
8451 else
8452 undefined,
8453 } };
8454}
8455
8456pub fn getDeclaredUnionType(
8457 ip: *InternPool,
8458 gpa: Allocator,
8459 io: Io,
8460 tid: Zcu.PerThread.Id,
8461 ini: struct {
8462 zir_index: TrackedInst.Index,
8463 captures: []const CaptureValue,
8464
8465 // If the value of any of the following fields would change on an incremental update, then logic
8466 // in `Zcu.mapOldZirToNew` must detect that (these properties are all trivially known from ZIR)
8467 // and refuse to map the type declaration. This causes `zir_index` to change so that a new type
8468 // will be interned at a fresh index.
8469 //
8470 // In the future, it would be good to remove all of those fields from `ini`, and in fact just
8471 // have a single function `getDeclaredContainer` which is suitable for all container types.
8472 // However, this requires some major changes to how container types are represented in the
8473 // InternPool, so that it is possible for their backing storage to be "reallocated" as needed
8474 // during type resolution.
8475 fields_len: u32,
8476 layout: std.builtin.Type.ContainerLayout,
8477 any_field_aligns: bool,
8478 tag_usage: LoadedUnionType.TagUsage,
8479 enum_tag_mode: BackingTypeMode,
8480 packed_backing_mode: BackingTypeMode,
8481 },
8482) Allocator.Error!WipContainerType.Result {
8483 var gop = try ip.getOrPutKey(gpa, io, tid, .{ .union_type = .{ .declared = .{
8484 .zir_index = ini.zir_index,
8485 .captures = .{ .external = ini.captures },
8486 } } });
8487 defer gop.deinit();
8488 if (gop == .existing) return .{ .existing = gop.existing };
8489
8490 const local = ip.getLocal(tid);
8491 const items = local.getMutableItems(gpa, io);
8492 const extra = local.getMutableExtra(gpa, io);
8493 try items.ensureUnusedCapacity(1);
8494
8495 const is_extern = switch (ini.layout) {
8496 .auto => false,
8497 .@"extern" => true,
8498 .@"packed" => {
8499 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeUnionPacked).@"struct".fields.len +
8500 ini.captures.len + // capture
8501 ini.fields_len); // field_type
8502
8503 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeUnionPacked{
8504 .zir_index = ini.zir_index,
8505 .bits = .{
8506 .captures_len = @enumFromInt(ini.captures.len),
8507 .want_layout = false,
8508 },
8509 .name = undefined, // set by `finish`
8510 .name_nav = undefined, // set by `finish`
8511 .namespace = undefined, // set by `finish`
8512 .backing_int_type = .none,
8513 .enum_tag_type = .none,
8514 .fields_len = ini.fields_len,
8515 });
8516 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.captures)}); // capture
8517 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len); // field_type
8518 items.appendAssumeCapacity(.{
8519 .tag = switch (ini.packed_backing_mode) {
8520 .auto => .type_union_packed_auto,
8521 .explicit => .type_union_packed_explicit,
8522 },
8523 .data = extra_index,
8524 });
8525 return .{ .wip = .{
8526 .index = gop.put(),
8527 .tid = tid,
8528 .type_name_index = extra_index + std.meta.fieldIndex(Tag.TypeUnionPacked, "name").?,
8529 .name_nav_index = extra_index + std.meta.fieldIndex(Tag.TypeUnionPacked, "name_nav").?,
8530 .namespace_index = extra_index + std.meta.fieldIndex(Tag.TypeUnionPacked, "namespace").?,
8531 .field_names = undefined,
8532 .field_types = undefined,
8533 .field_values = undefined,
8534 .field_aligns = undefined,
8535 .field_is_comptime_bits = undefined,
8536 } };
8537 },
8538 };
8539
8540 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeUnion).@"struct".fields.len +
8541 1 + // captures_len
8542 ini.captures.len + // capture
8543 ini.fields_len + // field_type
8544 (if (ini.any_field_aligns) (ini.fields_len + 3) / 4 else 0)); // field_align
8545
8546 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeUnion{
8547 .zir_index = ini.zir_index,
8548 .name = undefined, // set by `finish`
8549 .name_nav = undefined, // set by `finish`
8550 .namespace = undefined, // set by `finish`
8551 .enum_tag_type = .none,
8552 .fields_len = ini.fields_len,
8553 .size = 0,
8554 .padding = 0,
8555 .flags = .{
8556 .any_captures = if (ini.captures.len != 0) .true else .false,
8557 .enum_tag_mode = ini.enum_tag_mode,
8558 .layout = if (is_extern) .@"extern" else .auto,
8559 .any_field_aligns = ini.any_field_aligns,
8560 .tag_usage = ini.tag_usage,
8561 .class = .no_possible_value,
8562 .has_runtime_tag = false,
8563 .alignment = .none,
8564 .want_layout = false,
8565 },
8566 });
8567 if (ini.captures.len > 0) {
8568 extra.appendAssumeCapacity(.{@intCast(ini.captures.len)}); // captures_len
8569 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.captures)}); // capture
8570 }
8571 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len); // field_type
8572 if (ini.any_field_aligns) {
8573 extra.appendNTimesAssumeCapacity(.{0}, (ini.fields_len + 3) / 4); // field_align
8574 }
8575 items.appendAssumeCapacity(.{
8576 .tag = .type_union,
8577 .data = extra_index,
8578 });
8579 return .{ .wip = .{
8580 .index = gop.put(),
8581 .tid = tid,
8582 .type_name_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "name").?,
8583 .name_nav_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "name_nav").?,
8584 .namespace_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?,
8585 .field_names = undefined,
8586 .field_types = undefined,
8587 .field_values = undefined,
8588 .field_aligns = undefined,
8589 .field_is_comptime_bits = undefined,
8590 } };
8591}
8592
8593pub fn getReifiedUnionType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, ini: struct {
8594 zir_index: TrackedInst.Index,
8595 type_hash: u64,
8596 fields_len: u32,
8597 layout: std.builtin.Type.ContainerLayout,
8598 any_field_aligns: bool,
8599 tag_usage: LoadedUnionType.TagUsage,
8600 /// Explicitly specified enum tag type. `.none` if `tag_usage != .tagged`.
8601 enum_tag_type: Index,
8602 /// Explicitly specified backing int type. `.none` if not packed or if backing type is inferred.
8603 packed_backing_int_type: Index,
8604}) Allocator.Error!WipContainerType.Result {
8605 var gop = try ip.getOrPutKey(gpa, io, tid, .{ .union_type = .{ .reified = .{
8606 .zir_index = ini.zir_index,
8607 .type_hash = ini.type_hash,
8608 } } });
8609 defer gop.deinit();
8610 if (gop == .existing) return .{ .existing = gop.existing };
8611
8612 const local = ip.getLocal(tid);
8613 const items = local.getMutableItems(gpa, io);
8614 const extra = local.getMutableExtra(gpa, io);
8615 try items.ensureUnusedCapacity(1);
8616
8617 const is_extern = switch (ini.layout) {
8618 .auto => false,
8619 .@"extern" => true,
8620 .@"packed" => {
8621 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeUnionPacked).@"struct".fields.len +
8622 2 + // type_hash
8623 ini.fields_len + // reified_field_name
8624 ini.fields_len); // field_type
8625
8626 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeUnionPacked{
8627 .zir_index = ini.zir_index,
8628 .bits = .{
8629 .captures_len = .reified,
8630 .want_layout = false,
8631 },
8632 .name = undefined, // set by `finish`
8633 .name_nav = undefined, // set by `finish`
8634 .namespace = undefined, // set by `finish`
8635 .backing_int_type = ini.packed_backing_int_type,
8636 .enum_tag_type = .none,
8637 .fields_len = ini.fields_len,
8638 });
8639 _ = addExtraAssumeCapacity(extra, PackedU64.init(ini.type_hash)); // type_hash
8640 const field_names_start = extra.mutate.len;
8641 extra.appendNTimesAssumeCapacity(.{@intFromEnum(NullTerminatedString.empty)}, ini.fields_len); // reified_field_name
8642 const field_types_start = extra.mutate.len;
8643 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len); // field_type
8644 items.appendAssumeCapacity(.{
8645 .tag = switch (ini.packed_backing_int_type) {
8646 .none => .type_union_packed_auto,
8647 else => .type_union_packed_explicit,
8648 },
8649 .data = extra_index,
87318650 });
8732 extra.appendSliceAssumeCapacity(.{@ptrCast(memoized_call.arg_values)});
8651 return .{ .wip = .{
8652 .index = gop.put(),
8653 .tid = tid,
8654 .type_name_index = extra_index + std.meta.fieldIndex(Tag.TypeUnionPacked, "name").?,
8655 .name_nav_index = extra_index + std.meta.fieldIndex(Tag.TypeUnionPacked, "name_nav").?,
8656 .namespace_index = extra_index + std.meta.fieldIndex(Tag.TypeUnionPacked, "namespace").?,
8657 .field_names = .{ .tid = tid, .start = field_names_start, .len = ini.fields_len },
8658 .field_types = .{ .tid = tid, .start = field_types_start, .len = ini.fields_len },
8659 .field_values = undefined,
8660 .field_aligns = undefined,
8661 .field_is_comptime_bits = undefined,
8662 } };
8663 },
8664 };
8665
8666 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeUnion).@"struct".fields.len +
8667 2 + // type_hash
8668 ini.fields_len + // reified_field_name
8669 ini.fields_len + // field_type
8670 (if (ini.any_field_aligns) (ini.fields_len + 3) / 4 else 0)); // field_align
8671
8672 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeUnion{
8673 .zir_index = ini.zir_index,
8674 .name = undefined, // set by `finish`
8675 .name_nav = undefined, // set by `finish`
8676 .namespace = undefined, // set by `finish`
8677 .enum_tag_type = ini.enum_tag_type,
8678 .fields_len = ini.fields_len,
8679 .size = 0,
8680 .padding = 0,
8681 .flags = .{
8682 .any_captures = .reified,
8683 .enum_tag_mode = if (ini.enum_tag_type == .none) .auto else .explicit,
8684 .layout = if (is_extern) .@"extern" else .auto,
8685 .any_field_aligns = ini.any_field_aligns,
8686 .tag_usage = ini.tag_usage,
8687 .class = .no_possible_value,
8688 .has_runtime_tag = false,
8689 .alignment = .none,
8690 .want_layout = false,
87338691 },
8692 });
8693 _ = addExtraAssumeCapacity(extra, PackedU64.init(ini.type_hash));
8694 const field_names_start = extra.mutate.len;
8695 extra.appendNTimesAssumeCapacity(.{@intFromEnum(NullTerminatedString.empty)}, ini.fields_len); // reified_field_name
8696 const field_types_start = extra.mutate.len;
8697 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len); // field_type
8698 const field_aligns_start = extra.mutate.len;
8699 if (ini.any_field_aligns) {
8700 extra.appendNTimesAssumeCapacity(.{0}, (ini.fields_len + 3) / 4); // field_align
87348701 }
8735 return gop.put();
8702 items.appendAssumeCapacity(.{
8703 .tag = .type_union,
8704 .data = extra_index,
8705 });
8706 return .{ .wip = .{
8707 .index = gop.put(),
8708 .tid = tid,
8709 .type_name_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "name").?,
8710 .name_nav_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "name_nav").?,
8711 .namespace_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?,
8712 .field_names = .{ .tid = tid, .start = field_names_start, .len = ini.fields_len },
8713 .field_types = .{ .tid = tid, .start = field_types_start, .len = ini.fields_len },
8714 .field_values = undefined,
8715 .field_aligns = if (ini.any_field_aligns)
8716 .{ .tid = tid, .start = field_aligns_start, .len = ini.fields_len }
8717 else
8718 undefined,
8719 .field_is_comptime_bits = undefined,
8720 } };
87368721}
87378722
8738pub fn getUnion(
8723pub fn getDeclaredEnumType(
87398724 ip: *InternPool,
87408725 gpa: Allocator,
87418726 io: Io,
87428727 tid: Zcu.PerThread.Id,
8743 un: Key.Union,
8744) Allocator.Error!Index {
8745 var gop = try ip.getOrPutKey(gpa, io, tid, .{ .un = un });
8728 ini: struct {
8729 zir_index: TrackedInst.Index,
8730 captures: []const CaptureValue,
8731
8732 // If the value of any of the following fields would change on an incremental update, then logic
8733 // in `Zcu.mapOldZirToNew` must detect that (these properties are all trivially known from ZIR)
8734 // and refuse to map the type declaration. This causes `zir_index` to change so that a new type
8735 // will be interned at a fresh index.
8736 //
8737 // In the future, it would be good to remove all of those fields from `ini`, and in fact just
8738 // have a single function `getDeclaredContainer` which is suitable for all container types.
8739 // However, this requires some major changes to how container types are represented in the
8740 // InternPool, so that it is possible for their backing storage to be "reallocated" as needed
8741 // during type resolution.
8742 fields_len: u32,
8743 nonexhaustive: bool,
8744 /// For `enum(T)` this is `.explicit`. Otherwise this is `.none`.
8745 int_tag_mode: BackingTypeMode,
8746 },
8747) Allocator.Error!WipContainerType.Result {
8748 var gop = try ip.getOrPutKey(gpa, io, tid, .{ .enum_type = .{ .declared = .{
8749 .zir_index = ini.zir_index,
8750 .captures = .{ .external = ini.captures },
8751 } } });
87468752 defer gop.deinit();
8747 if (gop == .existing) return gop.existing;
8753 if (gop == .existing) return .{ .existing = gop.existing };
8754
87488755 const local = ip.getLocal(tid);
87498756 const items = local.getMutableItems(gpa, io);
87508757 const extra = local.getMutableExtra(gpa, io);
87518758 try items.ensureUnusedCapacity(1);
87528759
8753 assert(un.ty != .none);
8754 assert(un.val != .none);
8760 const tag: Tag, const have_values: bool = if (ini.nonexhaustive)
8761 .{ .type_enum_nonexhaustive, true }
8762 else if (ini.int_tag_mode == .explicit)
8763 .{ .type_enum_explicit, true }
8764 else
8765 .{ .type_enum_auto, false };
8766
8767 const field_name_map = try ip.addMap(gpa, io, tid, ini.fields_len);
8768 errdefer local.mutate.maps.len -= 1;
8769
8770 const field_value_map = if (have_values) try ip.addMap(gpa, io, tid, ini.fields_len) else undefined;
8771 errdefer local.mutate.maps.len -= @intFromBool(have_values);
8772
8773 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeEnum).@"struct".fields.len +
8774 1 + // zir_index
8775 ini.captures.len + // capture
8776 @intFromBool(have_values) + // field_value_map
8777 ini.fields_len + // field_name
8778 (if (have_values) ini.fields_len else 0)); // field_value
8779
8780 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeEnum{
8781 .bits = .{
8782 .captures_len = @enumFromInt(ini.captures.len),
8783 .want_layout = false,
8784 },
8785 .name = undefined, // set by `finish`
8786 .name_nav = undefined, // set by `finish`
8787 .namespace = undefined, // set by `finish`
8788 .int_tag_type = .none,
8789 .fields_len = ini.fields_len,
8790 .field_name_map = field_name_map,
8791 });
8792 extra.appendAssumeCapacity(.{@intFromEnum(ini.zir_index)}); // zir_index
8793 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.captures)}); // capture
8794 if (have_values) extra.appendAssumeCapacity(.{@intFromEnum(field_value_map)}); // field_value_map
8795 extra.appendNTimesAssumeCapacity(.{@intFromEnum(NullTerminatedString.empty)}, ini.fields_len); // field_name
8796 if (have_values) extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len); // field_value
87558797 items.appendAssumeCapacity(.{
8756 .tag = .union_value,
8757 .data = try addExtra(extra, un),
8798 .tag = tag,
8799 .data = extra_index,
87588800 });
8759
8760 return gop.put();
8801 return .{ .wip = .{
8802 .index = gop.put(),
8803 .tid = tid,
8804 .type_name_index = extra_index + std.meta.fieldIndex(Tag.TypeEnum, "name").?,
8805 .name_nav_index = extra_index + std.meta.fieldIndex(Tag.TypeEnum, "name_nav").?,
8806 .namespace_index = extra_index + std.meta.fieldIndex(Tag.TypeEnum, "namespace").?,
8807 .field_names = undefined,
8808 .field_types = undefined,
8809 .field_values = undefined,
8810 .field_aligns = undefined,
8811 .field_is_comptime_bits = undefined,
8812 } };
87618813}
87628814
8763pub const UnionTypeInit = struct {
8764 flags: packed struct {
8765 runtime_tag: LoadedUnionType.RuntimeTag,
8766 any_aligned_fields: bool,
8767 layout: std.builtin.Type.ContainerLayout,
8768 status: LoadedUnionType.Status,
8769 requires_comptime: RequiresComptime,
8770 assumed_runtime_bits: bool,
8771 assumed_pointer_aligned: bool,
8772 alignment: Alignment,
8773 },
8815pub fn getReifiedEnumType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, ini: struct {
8816 zir_index: TrackedInst.Index,
8817 type_hash: u64,
87748818 fields_len: u32,
8775 enum_tag_ty: Index,
8776 /// May have length 0 which leaves the values unset until later.
8777 field_types: []const Index,
8778 /// May have length 0 which leaves the values unset until later.
8779 /// The logic for `any_aligned_fields` is asserted to have been done before
8780 /// calling this function.
8781 field_aligns: []const Alignment,
8782 key: union(enum) {
8783 declared: struct {
8784 zir_index: TrackedInst.Index,
8785 captures: []const CaptureValue,
8786 },
8787 declared_owned_captures: struct {
8788 zir_index: TrackedInst.Index,
8789 captures: CaptureValue.Slice,
8790 },
8791 reified: struct {
8792 zir_index: TrackedInst.Index,
8793 type_hash: u64,
8794 },
8795 },
8796};
8797
8798pub fn getUnionType(
8799 ip: *InternPool,
8800 gpa: Allocator,
8801 io: Io,
8802 tid: Zcu.PerThread.Id,
8803 ini: UnionTypeInit,
8804 /// If it is known that there is an existing type with this key which is outdated,
8805 /// this is passed as `true`, and the type is replaced with one at a fresh index.
8806 replace_existing: bool,
8807) Allocator.Error!WipNamespaceType.Result {
8808 const key: Key = .{ .union_type = switch (ini.key) {
8809 .declared => |d| .{ .declared = .{
8810 .zir_index = d.zir_index,
8811 .captures = .{ .external = d.captures },
8812 } },
8813 .declared_owned_captures => |d| .{ .declared = .{
8814 .zir_index = d.zir_index,
8815 .captures = .{ .owned = d.captures },
8816 } },
8817 .reified => |r| .{ .reified = .{
8818 .zir_index = r.zir_index,
8819 .type_hash = r.type_hash,
8820 } },
8821 } };
8822 var gop = if (replace_existing)
8823 ip.putKeyReplace(io, tid, key)
8824 else
8825 try ip.getOrPutKey(gpa, io, tid, key);
8819 nonexhaustive: bool,
8820 /// Explicitly specified int tag type, or `.none` if the int tag type is inferred.
8821 int_tag_type: Index,
8822}) Allocator.Error!WipContainerType.Result {
8823 var gop = try ip.getOrPutKey(gpa, io, tid, .{ .enum_type = .{ .reified = .{
8824 .zir_index = ini.zir_index,
8825 .type_hash = ini.type_hash,
8826 } } });
88268827 defer gop.deinit();
88278828 if (gop == .existing) return .{ .existing = gop.existing };
88288829
88298830 const local = ip.getLocal(tid);
88308831 const items = local.getMutableItems(gpa, io);
8831 try items.ensureUnusedCapacity(1);
88328832 const extra = local.getMutableExtra(gpa, io);
8833 try items.ensureUnusedCapacity(1);
88338834
8834 const align_elements_len = if (ini.flags.any_aligned_fields) (ini.fields_len + 3) / 4 else 0;
8835 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);
8836 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeUnion).@"struct".fields.len +
8837 // TODO: fmt bug
8838 // zig fmt: off
8839 switch (ini.key) {
8840 inline .declared, .declared_owned_captures => |d| @intFromBool(d.captures.len != 0) + d.captures.len,
8841 .reified => 2, // type_hash: PackedU64
8842 } +
8843 // zig fmt: on
8844 ini.fields_len + // field types
8845 align_elements_len);
8835 const tag: Tag, const have_values: bool = if (ini.nonexhaustive)
8836 .{ .type_enum_nonexhaustive, true }
8837 else if (ini.int_tag_type != .none)
8838 .{ .type_enum_explicit, true }
8839 else
8840 .{ .type_enum_auto, false };
88468841
8847 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeUnion{
8848 .flags = .{
8849 .any_captures = switch (ini.key) {
8850 inline .declared, .declared_owned_captures => |d| d.captures.len != 0,
8851 .reified => false,
8852 },
8853 .runtime_tag = ini.flags.runtime_tag,
8854 .any_aligned_fields = ini.flags.any_aligned_fields,
8855 .layout = ini.flags.layout,
8856 .status = ini.flags.status,
8857 .requires_comptime = ini.flags.requires_comptime,
8858 .assumed_runtime_bits = ini.flags.assumed_runtime_bits,
8859 .assumed_pointer_aligned = ini.flags.assumed_pointer_aligned,
8860 .alignment = ini.flags.alignment,
8861 .is_reified = switch (ini.key) {
8862 .declared, .declared_owned_captures => false,
8863 .reified => true,
8864 },
8842 const field_name_map = try ip.addMap(gpa, io, tid, ini.fields_len);
8843 errdefer local.mutate.maps.len -= 1;
8844
8845 const field_value_map = if (have_values) try ip.addMap(gpa, io, tid, ini.fields_len) else undefined;
8846 errdefer local.mutate.maps.len -= @intFromBool(have_values);
8847
8848 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeEnum).@"struct".fields.len +
8849 1 + // zir_index
8850 2 + // type_hash
8851 @intFromBool(have_values) + // field_value_map
8852 ini.fields_len + // field_name
8853 (if (have_values) ini.fields_len else 0)); // field_value
8854
8855 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeEnum{
8856 .bits = .{
8857 .captures_len = .reified,
8858 .want_layout = false,
88658859 },
8866 .fields_len = ini.fields_len,
8867 .size = std.math.maxInt(u32),
8868 .padding = std.math.maxInt(u32),
88698860 .name = undefined, // set by `finish`
88708861 .name_nav = undefined, // set by `finish`
88718862 .namespace = undefined, // set by `finish`
8872 .tag_ty = ini.enum_tag_ty,
8873 .zir_index = switch (ini.key) {
8874 inline else => |x| x.zir_index,
8875 },
8863 .int_tag_type = ini.int_tag_type,
8864 .fields_len = ini.fields_len,
8865 .field_name_map = field_name_map,
88768866 });
8877
8867 extra.appendAssumeCapacity(.{@intFromEnum(ini.zir_index)}); // zir_index
8868 _ = addExtraAssumeCapacity(extra, PackedU64.init(ini.type_hash)); // type_hash
8869 if (have_values) extra.appendAssumeCapacity(.{@intFromEnum(field_value_map)}); // field_value_map
8870 const field_names_start = extra.mutate.len;
8871 extra.appendNTimesAssumeCapacity(.{@intFromEnum(NullTerminatedString.empty)}, ini.fields_len); // field_name
8872 const field_values_start = extra.mutate.len;
8873 if (have_values) extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len); // field_value
88788874 items.appendAssumeCapacity(.{
8879 .tag = .type_union,
8875 .tag = tag,
88808876 .data = extra_index,
88818877 });
8878 return .{ .wip = .{
8879 .index = gop.put(),
8880 .tid = tid,
8881 .type_name_index = extra_index + std.meta.fieldIndex(Tag.TypeEnum, "name").?,
8882 .name_nav_index = extra_index + std.meta.fieldIndex(Tag.TypeEnum, "name_nav").?,
8883 .namespace_index = extra_index + std.meta.fieldIndex(Tag.TypeEnum, "namespace").?,
8884 .field_names = .{ .tid = tid, .start = field_names_start, .len = ini.fields_len },
8885 .field_types = undefined,
8886 .field_values = if (have_values)
8887 .{ .tid = tid, .start = field_values_start, .len = ini.fields_len }
8888 else
8889 undefined,
8890 .field_aligns = undefined,
8891 .field_is_comptime_bits = undefined,
8892 } };
8893}
8894
8895pub fn getGeneratedEnumTagType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, ini: struct {
8896 /// The union type for which this enum is a generated tag.
8897 union_type: Index,
8898 /// For `union(enum(T))` this is `.explicit`. Otherwise this is `.none`.
8899 int_tag_mode: BackingTypeMode,
8900 fields_len: u32,
8901}) Allocator.Error!WipContainerType.Result {
8902 var gop = try ip.getOrPutKey(gpa, io, tid, .{ .enum_type = .{ .generated_union_tag = ini.union_type } });
8903 defer gop.deinit();
8904 if (gop == .existing) return .{ .existing = gop.existing };
88828905
8883 switch (ini.key) {
8884 .declared => |d| if (d.captures.len != 0) {
8885 extra.appendAssumeCapacity(.{@intCast(d.captures.len)});
8886 extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)});
8906 const local = ip.getLocal(tid);
8907 const items = local.getMutableItems(gpa, io);
8908 const extra = local.getMutableExtra(gpa, io);
8909 try items.ensureUnusedCapacity(1);
8910
8911 const field_name_map = try ip.addMap(gpa, io, tid, ini.fields_len);
8912 errdefer local.mutate.maps.len -= 1;
8913
8914 const have_values = switch (ini.int_tag_mode) {
8915 .explicit => true,
8916 .auto => false,
8917 };
8918
8919 const field_value_map = if (have_values) try ip.addMap(gpa, io, tid, ini.fields_len) else undefined;
8920 errdefer local.mutate.maps.len -= @intFromBool(have_values);
8921
8922 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeEnum).@"struct".fields.len +
8923 1 + // owner_union
8924 @intFromBool(have_values) + // field_value_map
8925 ini.fields_len + // field_name
8926 (if (have_values) ini.fields_len else 0)); // field_value
8927
8928 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeEnum{
8929 .bits = .{
8930 .captures_len = .generated_union_tag,
8931 .want_layout = false,
88878932 },
8888 .declared_owned_captures => |d| if (d.captures.len != 0) {
8889 extra.appendAssumeCapacity(.{@intCast(d.captures.len)});
8890 extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures.get(ip))});
8933 .name = undefined, // set by `finish`
8934 .name_nav = undefined, // set by `finish`
8935 .namespace = undefined, // set by `finish`
8936 .int_tag_type = .none,
8937 .fields_len = ini.fields_len,
8938 .field_name_map = field_name_map,
8939 });
8940 extra.appendAssumeCapacity(.{@intFromEnum(ini.union_type)}); // owner_union
8941 if (have_values) extra.appendAssumeCapacity(.{@intFromEnum(field_value_map)});
8942 extra.appendNTimesAssumeCapacity(.{@intFromEnum(NullTerminatedString.empty)}, ini.fields_len); // field_name
8943 if (have_values) extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len); // field_value
8944 items.appendAssumeCapacity(.{
8945 .tag = switch (ini.int_tag_mode) {
8946 .auto => .type_enum_auto,
8947 .explicit => .type_enum_explicit,
88918948 },
8892 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
8893 }
8949 .data = extra_index,
8950 });
8951 return .{ .wip = .{
8952 .index = gop.put(),
8953 .tid = tid,
8954 .type_name_index = extra_index + std.meta.fieldIndex(Tag.TypeEnum, "name").?,
8955 .name_nav_index = extra_index + std.meta.fieldIndex(Tag.TypeEnum, "name_nav").?,
8956 .namespace_index = extra_index + std.meta.fieldIndex(Tag.TypeEnum, "namespace").?,
8957 .field_names = undefined,
8958 .field_types = undefined,
8959 .field_values = undefined,
8960 .field_aligns = undefined,
8961 .field_is_comptime_bits = undefined,
8962 } };
8963}
88948964
8895 // field types
8896 if (ini.field_types.len > 0) {
8897 assert(ini.field_types.len == ini.fields_len);
8898 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.field_types)});
8899 } else {
8900 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
8901 }
8965pub fn getDeclaredOpaqueType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, ini: struct {
8966 zir_index: TrackedInst.Index,
8967 captures: []const CaptureValue,
8968}) Allocator.Error!WipContainerType.Result {
8969 var gop = try ip.getOrPutKey(gpa, io, tid, .{ .opaque_type = .{ .declared = .{
8970 .zir_index = ini.zir_index,
8971 .captures = .{ .external = ini.captures },
8972 } } });
8973 defer gop.deinit();
8974 if (gop == .existing) return .{ .existing = gop.existing };
89028975
8903 // field alignments
8904 if (ini.flags.any_aligned_fields) {
8905 extra.appendNTimesAssumeCapacity(.{align_element}, align_elements_len);
8906 if (ini.field_aligns.len > 0) {
8907 assert(ini.field_aligns.len == ini.fields_len);
8908 @memcpy((Alignment.Slice{
8909 .tid = tid,
8910 .start = @intCast(extra.mutate.len - align_elements_len),
8911 .len = @intCast(ini.field_aligns.len),
8912 }).get(ip), ini.field_aligns);
8913 }
8914 } else {
8915 assert(ini.field_aligns.len == 0);
8916 }
8976 const local = ip.getLocal(tid);
8977 const items = local.getMutableItems(gpa, io);
8978 const extra = local.getMutableExtra(gpa, io);
8979 try items.ensureUnusedCapacity(1);
89178980
8981 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeOpaque).@"struct".fields.len + ini.captures.len);
8982 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{
8983 .zir_index = ini.zir_index,
8984 .captures_len = @intCast(ini.captures.len),
8985 .name = undefined, // set by `finish`
8986 .name_nav = undefined, // set by `finish`
8987 .namespace = undefined, // set by `finish`
8988 });
8989 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.captures)});
8990 items.appendAssumeCapacity(.{
8991 .tag = .type_opaque,
8992 .data = extra_index,
8993 });
89188994 return .{ .wip = .{
8919 .tid = tid,
89208995 .index = gop.put(),
8921 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "name").?,
8922 .name_nav_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "name_nav").?,
8923 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?,
8996 .tid = tid,
8997 .type_name_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "name").?,
8998 .name_nav_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "name_nav").?,
8999 .namespace_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").?,
9000 .field_names = undefined,
9001 .field_types = undefined,
9002 .field_values = undefined,
9003 .field_aligns = undefined,
9004 .field_is_comptime_bits = undefined,
89249005 } };
89259006}
89269007
8927pub const WipNamespaceType = struct {
8928 tid: Zcu.PerThread.Id,
9008pub const WipContainerType = struct {
89299009 index: Index,
8930 type_name_extra_index: u32,
8931 namespace_extra_index: u32,
8932 name_nav_extra_index: u32,
9010 tid: Zcu.PerThread.Id,
9011 type_name_index: u32,
9012 name_nav_index: u32,
9013 namespace_index: u32,
9014
9015 // These fields are only populated when creating reified types, because reified types populate
9016 // field information immediately, with type resolution only handling validation. This is in
9017 // contrast to declared types, where field information is populated by the type resolution
9018 // process evaluating ZIR expressions.
9019 field_names: NullTerminatedString.Slice,
9020 field_types: Index.Slice,
9021 field_values: Index.Slice,
9022 field_aligns: Alignment.Slice,
9023 field_is_comptime_bits: LoadedStructType.ComptimeBits,
89339024
89349025 pub fn setName(
8935 wip: WipNamespaceType,
9026 wip: WipContainerType,
89369027 ip: *InternPool,
89379028 type_name: NullTerminatedString,
89389029 /// This should be the `Nav` we are named after if we use the `.parent` name strategy; `.none` otherwise.
......@@ -8941,257 +9032,58 @@ pub const WipNamespaceType = struct {
89419032 ) void {
89429033 const extra = ip.getLocalShared(wip.tid).extra.acquire();
89439034 const extra_items = extra.view().items(.@"0");
8944 extra_items[wip.type_name_extra_index] = @intFromEnum(type_name);
8945 extra_items[wip.name_nav_extra_index] = @intFromEnum(name_nav);
9035 extra_items[wip.type_name_index] = @intFromEnum(type_name);
9036 extra_items[wip.name_nav_index] = @intFromEnum(name_nav);
89469037 }
89479038
89489039 pub fn finish(
8949 wip: WipNamespaceType,
9040 wip: WipContainerType,
89509041 ip: *InternPool,
89519042 namespace: NamespaceIndex,
89529043 ) Index {
89539044 const extra = ip.getLocalShared(wip.tid).extra.acquire();
89549045 const extra_items = extra.view().items(.@"0");
89559046
8956 extra_items[wip.namespace_extra_index] = @intFromEnum(namespace);
9047 extra_items[wip.namespace_index] = @intFromEnum(namespace);
89579048
89589049 return wip.index;
89599050 }
89609051
8961 pub fn cancel(wip: WipNamespaceType, ip: *InternPool, tid: Zcu.PerThread.Id) void {
9052 pub fn cancel(wip: WipContainerType, ip: *InternPool, tid: Zcu.PerThread.Id) void {
89629053 ip.remove(tid, wip.index);
89639054 }
89649055
89659056 pub const Result = union(enum) {
8966 wip: WipNamespaceType,
8967 existing: Index,
8968 };
8969};
8970
8971pub const StructTypeInit = struct {
8972 layout: std.builtin.Type.ContainerLayout,
8973 fields_len: u32,
8974 known_non_opv: bool,
8975 requires_comptime: RequiresComptime,
8976 any_comptime_fields: bool,
8977 any_default_inits: bool,
8978 inits_resolved: bool,
8979 any_aligned_fields: bool,
8980 key: union(enum) {
8981 declared: struct {
8982 zir_index: TrackedInst.Index,
8983 captures: []const CaptureValue,
8984 },
8985 declared_owned_captures: struct {
8986 zir_index: TrackedInst.Index,
8987 captures: CaptureValue.Slice,
8988 },
8989 reified: struct {
8990 zir_index: TrackedInst.Index,
8991 type_hash: u64,
8992 },
8993 },
8994};
8995
8996pub fn getStructType(
8997 ip: *InternPool,
8998 gpa: Allocator,
8999 io: Io,
9000 tid: Zcu.PerThread.Id,
9001 ini: StructTypeInit,
9002 /// If it is known that there is an existing type with this key which is outdated,
9003 /// this is passed as `true`, and the type is replaced with one at a fresh index.
9004 replace_existing: bool,
9005) Allocator.Error!WipNamespaceType.Result {
9006 const key: Key = .{ .struct_type = switch (ini.key) {
9007 .declared => |d| .{ .declared = .{
9008 .zir_index = d.zir_index,
9009 .captures = .{ .external = d.captures },
9010 } },
9011 .declared_owned_captures => |d| .{ .declared = .{
9012 .zir_index = d.zir_index,
9013 .captures = .{ .owned = d.captures },
9014 } },
9015 .reified => |r| .{ .reified = .{
9016 .zir_index = r.zir_index,
9017 .type_hash = r.type_hash,
9018 } },
9019 } };
9020 var gop = if (replace_existing)
9021 ip.putKeyReplace(io, tid, key)
9022 else
9023 try ip.getOrPutKey(gpa, io, tid, key);
9024 defer gop.deinit();
9025 if (gop == .existing) return .{ .existing = gop.existing };
9026
9027 const local = ip.getLocal(tid);
9028 const items = local.getMutableItems(gpa, io);
9029 const extra = local.getMutableExtra(gpa, io);
9030
9031 const names_map = try ip.addMap(gpa, io, tid, ini.fields_len);
9032 errdefer local.mutate.maps.len -= 1;
9033
9034 const zir_index = switch (ini.key) {
9035 inline else => |x| x.zir_index,
9036 };
9037
9038 const is_extern = switch (ini.layout) {
9039 .auto => false,
9040 .@"extern" => true,
9041 .@"packed" => {
9042 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStructPacked).@"struct".fields.len +
9043 // TODO: fmt bug
9044 // zig fmt: off
9045 switch (ini.key) {
9046 inline .declared, .declared_owned_captures => |d| @intFromBool(d.captures.len != 0) + d.captures.len,
9047 .reified => 2, // type_hash: PackedU64
9048 } +
9049 // zig fmt: on
9050 ini.fields_len + // types
9051 ini.fields_len + // names
9052 ini.fields_len); // inits
9053 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{
9054 .name = undefined, // set by `finish`
9055 .name_nav = undefined, // set by `finish`
9056 .zir_index = zir_index,
9057 .fields_len = ini.fields_len,
9058 .namespace = undefined, // set by `finish`
9059 .backing_int_ty = .none,
9060 .names_map = names_map,
9061 .flags = .{
9062 .any_captures = switch (ini.key) {
9063 inline .declared, .declared_owned_captures => |d| d.captures.len != 0,
9064 .reified => false,
9065 },
9066 .field_inits_wip = false,
9067 .inits_resolved = ini.inits_resolved,
9068 .is_reified = switch (ini.key) {
9069 .declared, .declared_owned_captures => false,
9070 .reified => true,
9071 },
9072 },
9073 });
9074 try items.append(.{
9075 .tag = if (ini.any_default_inits) .type_struct_packed_inits else .type_struct_packed,
9076 .data = extra_index,
9077 });
9078 switch (ini.key) {
9079 .declared => |d| if (d.captures.len != 0) {
9080 extra.appendAssumeCapacity(.{@intCast(d.captures.len)});
9081 extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)});
9082 },
9083 .declared_owned_captures => |d| if (d.captures.len != 0) {
9084 extra.appendAssumeCapacity(.{@intCast(d.captures.len)});
9085 extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures.get(ip))});
9086 },
9087 .reified => |r| {
9088 _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash));
9089 },
9090 }
9091 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
9092 extra.appendNTimesAssumeCapacity(.{@intFromEnum(OptionalNullTerminatedString.none)}, ini.fields_len);
9093 if (ini.any_default_inits) {
9094 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
9095 }
9096 return .{ .wip = .{
9097 .tid = tid,
9098 .index = gop.put(),
9099 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "name").?,
9100 .name_nav_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "name_nav").?,
9101 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?,
9102 } };
9103 },
9057 wip: WipContainerType,
9058 existing: Index,
91049059 };
9060};
91059061
9106 const align_elements_len = if (ini.any_aligned_fields) (ini.fields_len + 3) / 4 else 0;
9107 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);
9108 const comptime_elements_len = if (ini.any_comptime_fields) (ini.fields_len + 31) / 32 else 0;
9062pub fn getUnion(
9063 ip: *InternPool,
9064 gpa: Allocator,
9065 io: Io,
9066 tid: Zcu.PerThread.Id,
9067 un: Key.Union,
9068) Allocator.Error!Index {
9069 assert(un.ty != .none);
9070 assert(un.val != .none);
9071 assert(ip.loadUnionType(un.ty).layout != .@"packed");
91099072
9110 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStruct).@"struct".fields.len +
9111 // TODO: fmt bug
9112 // zig fmt: off
9113 switch (ini.key) {
9114 inline .declared, .declared_owned_captures => |d| @intFromBool(d.captures.len != 0) + d.captures.len,
9115 .reified => 2, // type_hash: PackedU64
9116 } +
9117 // zig fmt: on
9118 (ini.fields_len * 5) + // types, names, inits, runtime order, offsets
9119 align_elements_len + comptime_elements_len +
9120 1); // names_map
9121 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStruct{
9122 .name = undefined, // set by `finish`
9123 .name_nav = undefined, // set by `finish`
9124 .zir_index = zir_index,
9125 .namespace = undefined, // set by `finish`
9126 .fields_len = ini.fields_len,
9127 .size = std.math.maxInt(u32),
9128 .flags = .{
9129 .any_captures = switch (ini.key) {
9130 inline .declared, .declared_owned_captures => |d| d.captures.len != 0,
9131 .reified => false,
9132 },
9133 .is_extern = is_extern,
9134 .known_non_opv = ini.known_non_opv,
9135 .requires_comptime = ini.requires_comptime,
9136 .assumed_runtime_bits = false,
9137 .assumed_pointer_aligned = false,
9138 .any_comptime_fields = ini.any_comptime_fields,
9139 .any_default_inits = ini.any_default_inits,
9140 .any_aligned_fields = ini.any_aligned_fields,
9141 .alignment = .none,
9142 .alignment_wip = false,
9143 .field_types_wip = false,
9144 .layout_wip = false,
9145 .layout_resolved = false,
9146 .field_inits_wip = false,
9147 .inits_resolved = ini.inits_resolved,
9148 .fully_resolved = false,
9149 .is_reified = switch (ini.key) {
9150 .declared, .declared_owned_captures => false,
9151 .reified => true,
9152 },
9153 },
9154 });
9155 try items.append(.{
9156 .tag = .type_struct,
9157 .data = extra_index,
9073 var gop = try ip.getOrPutKey(gpa, io, tid, .{ .un = un });
9074 defer gop.deinit();
9075 if (gop == .existing) return gop.existing;
9076 const local = ip.getLocal(tid);
9077 const items = local.getMutableItems(gpa, io);
9078 const extra = local.getMutableExtra(gpa, io);
9079 try items.ensureUnusedCapacity(1);
9080
9081 items.appendAssumeCapacity(.{
9082 .tag = .union_value,
9083 .data = try addExtra(extra, un),
91589084 });
9159 switch (ini.key) {
9160 .declared => |d| if (d.captures.len != 0) {
9161 extra.appendAssumeCapacity(.{@intCast(d.captures.len)});
9162 extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)});
9163 },
9164 .declared_owned_captures => |d| if (d.captures.len != 0) {
9165 extra.appendAssumeCapacity(.{@intCast(d.captures.len)});
9166 extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures.get(ip))});
9167 },
9168 .reified => |r| {
9169 _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash));
9170 },
9171 }
9172 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
9173 extra.appendAssumeCapacity(.{@intFromEnum(names_map)});
9174 extra.appendNTimesAssumeCapacity(.{@intFromEnum(OptionalNullTerminatedString.none)}, ini.fields_len);
9175 if (ini.any_default_inits) {
9176 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
9177 }
9178 if (ini.any_aligned_fields) {
9179 extra.appendNTimesAssumeCapacity(.{align_element}, align_elements_len);
9180 }
9181 if (ini.any_comptime_fields) {
9182 extra.appendNTimesAssumeCapacity(.{0}, comptime_elements_len);
9183 }
9184 if (ini.layout == .auto) {
9185 extra.appendNTimesAssumeCapacity(.{@intFromEnum(LoadedStructType.RuntimeOrder.unresolved)}, ini.fields_len);
9186 }
9187 extra.appendNTimesAssumeCapacity(.{std.math.maxInt(u32)}, ini.fields_len);
9188 return .{ .wip = .{
9189 .tid = tid,
9190 .index = gop.put(),
9191 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "name").?,
9192 .name_nav_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "name_nav").?,
9193 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "namespace").?,
9194 } };
9085
9086 return gop.put();
91959087}
91969088
91979089pub const TupleTypeInit = struct {
......@@ -9252,10 +9144,7 @@ pub const GetFuncTypeKey = struct {
92529144 /// `null` means generic.
92539145 cc: ?std.builtin.CallingConvention = .auto,
92549146 is_var_args: bool = false,
9255 is_generic: bool = false,
92569147 is_noinline: bool = false,
9257 section_is_generic: bool = false,
9258 addrspace_is_generic: bool = false,
92599148};
92609149
92619150pub fn getFuncType(
......@@ -9293,7 +9182,6 @@ pub fn getFuncType(
92939182 .is_var_args = key.is_var_args,
92949183 .has_comptime_bits = key.comptime_bits != 0,
92959184 .has_noalias_bits = key.noalias_bits != 0,
9296 .is_generic = key.is_generic,
92979185 .is_noinline = key.is_noinline,
92989186 },
92999187 });
......@@ -9427,7 +9315,7 @@ pub fn getFuncDecl(
94279315
94289316 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
94299317 .analysis = .{
9430 .is_analyzed = false,
9318 .want_runtime_analysis = false,
94319319 .branch_hint = .none,
94329320 .is_noinline = key.is_noinline,
94339321 .has_error_trace = false,
......@@ -9480,7 +9368,6 @@ pub const GetFuncDeclIesKey = struct {
94809368 /// null means generic.
94819369 cc: ?std.builtin.CallingConvention,
94829370 is_var_args: bool,
9483 is_generic: bool,
94849371 is_noinline: bool,
94859372 zir_body_inst: TrackedInst.Index,
94869373 lbrace_line: u32,
......@@ -9538,7 +9425,7 @@ pub fn getFuncDeclIes(
95389425
95399426 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
95409427 .analysis = .{
9541 .is_analyzed = false,
9428 .want_runtime_analysis = false,
95429429 .branch_hint = .none,
95439430 .is_noinline = key.is_noinline,
95449431 .has_error_trace = false,
......@@ -9564,7 +9451,6 @@ pub fn getFuncDeclIes(
95649451 .is_var_args = key.is_var_args,
95659452 .has_comptime_bits = key.comptime_bits != 0,
95669453 .has_noalias_bits = key.noalias_bits != 0,
9567 .is_generic = key.is_generic,
95689454 .is_noinline = key.is_noinline,
95699455 },
95709456 });
......@@ -9737,7 +9623,7 @@ pub fn getFuncInstance(
97379623
97389624 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
97399625 .analysis = .{
9740 .is_analyzed = false,
9626 .want_runtime_analysis = false,
97419627 .branch_hint = .none,
97429628 .is_noinline = arg.is_noinline,
97439629 .has_error_trace = false,
......@@ -9838,7 +9724,7 @@ fn getFuncInstanceIes(
98389724
98399725 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
98409726 .analysis = .{
9841 .is_analyzed = false,
9727 .want_runtime_analysis = false,
98429728 .branch_hint = .none,
98439729 .is_noinline = arg.is_noinline,
98449730 .has_error_trace = false,
......@@ -9864,7 +9750,6 @@ fn getFuncInstanceIes(
98649750 .is_var_args = false,
98659751 .has_comptime_bits = false,
98669752 .has_noalias_bits = arg.noalias_bits != 0,
9867 .is_generic = false,
98689753 .is_noinline = arg.is_noinline,
98699754 },
98709755 });
......@@ -9972,444 +9857,6 @@ fn finishFuncInstance(
99729857 ] = @intFromEnum(nav_index);
99739858}
99749859
9975pub const EnumTypeInit = struct {
9976 has_values: bool,
9977 tag_mode: LoadedEnumType.TagMode,
9978 fields_len: u32,
9979 key: union(enum) {
9980 declared: struct {
9981 zir_index: TrackedInst.Index,
9982 captures: []const CaptureValue,
9983 },
9984 declared_owned_captures: struct {
9985 zir_index: TrackedInst.Index,
9986 captures: CaptureValue.Slice,
9987 },
9988 reified: struct {
9989 zir_index: TrackedInst.Index,
9990 type_hash: u64,
9991 },
9992 },
9993};
9994
9995pub const WipEnumType = struct {
9996 tid: Zcu.PerThread.Id,
9997 index: Index,
9998 tag_ty_index: u32,
9999 type_name_extra_index: u32,
10000 namespace_extra_index: u32,
10001 name_nav_extra_index: u32,
10002 names_map: MapIndex,
10003 names_start: u32,
10004 values_map: OptionalMapIndex,
10005 values_start: u32,
10006
10007 pub fn setName(
10008 wip: WipEnumType,
10009 ip: *InternPool,
10010 type_name: NullTerminatedString,
10011 /// This should be the `Nav` we are named after if we use the `.parent` name strategy; `.none` otherwise.
10012 name_nav: Nav.Index.Optional,
10013 ) void {
10014 const extra = ip.getLocalShared(wip.tid).extra.acquire();
10015 const extra_items = extra.view().items(.@"0");
10016 extra_items[wip.type_name_extra_index] = @intFromEnum(type_name);
10017 extra_items[wip.name_nav_extra_index] = @intFromEnum(name_nav);
10018 }
10019
10020 pub fn prepare(
10021 wip: WipEnumType,
10022 ip: *InternPool,
10023 namespace: NamespaceIndex,
10024 ) void {
10025 const extra = ip.getLocalShared(wip.tid).extra.acquire();
10026 const extra_items = extra.view().items(.@"0");
10027
10028 extra_items[wip.namespace_extra_index] = @intFromEnum(namespace);
10029 }
10030
10031 pub fn setTagTy(wip: WipEnumType, ip: *InternPool, tag_ty: Index) void {
10032 assert(ip.isIntegerType(tag_ty));
10033 const extra = ip.getLocalShared(wip.tid).extra.acquire();
10034 extra.view().items(.@"0")[wip.tag_ty_index] = @intFromEnum(tag_ty);
10035 }
10036
10037 pub const FieldConflict = struct {
10038 kind: enum { name, value },
10039 prev_field_idx: u32,
10040 };
10041
10042 /// Returns the already-existing field with the same name or value, if any.
10043 /// If the enum is automatially numbered, `value` must be `.none`.
10044 /// Otherwise, the type of `value` must be the integer tag type of the enum.
10045 pub fn nextField(wip: WipEnumType, ip: *InternPool, name: NullTerminatedString, value: Index) ?FieldConflict {
10046 const unwrapped_index = wip.index.unwrap(ip);
10047 const extra_list = ip.getLocalShared(unwrapped_index.tid).extra.acquire();
10048 const extra_items = extra_list.view().items(.@"0");
10049 if (ip.addFieldName(extra_list, wip.names_map, wip.names_start, name)) |conflict| {
10050 return .{ .kind = .name, .prev_field_idx = conflict };
10051 }
10052 if (value == .none) {
10053 assert(wip.values_map == .none);
10054 return null;
10055 }
10056 assert(ip.typeOf(value) == @as(Index, @enumFromInt(extra_items[wip.tag_ty_index])));
10057 const map = wip.values_map.unwrap().?.get(ip);
10058 const field_index = map.count();
10059 const indexes = extra_items[wip.values_start..][0..field_index];
10060 const adapter: Index.Adapter = .{ .indexes = @ptrCast(indexes) };
10061 const gop = map.getOrPutAssumeCapacityAdapted(value, adapter);
10062 if (gop.found_existing) {
10063 return .{ .kind = .value, .prev_field_idx = @intCast(gop.index) };
10064 }
10065 extra_items[wip.values_start + field_index] = @intFromEnum(value);
10066 return null;
10067 }
10068
10069 pub fn cancel(wip: WipEnumType, ip: *InternPool, tid: Zcu.PerThread.Id) void {
10070 ip.remove(tid, wip.index);
10071 }
10072
10073 pub const Result = union(enum) {
10074 wip: WipEnumType,
10075 existing: Index,
10076 };
10077};
10078
10079pub fn getEnumType(
10080 ip: *InternPool,
10081 gpa: Allocator,
10082 io: Io,
10083 tid: Zcu.PerThread.Id,
10084 ini: EnumTypeInit,
10085 /// If it is known that there is an existing type with this key which is outdated,
10086 /// this is passed as `true`, and the type is replaced with one at a fresh index.
10087 replace_existing: bool,
10088) Allocator.Error!WipEnumType.Result {
10089 const key: Key = .{ .enum_type = switch (ini.key) {
10090 .declared => |d| .{ .declared = .{
10091 .zir_index = d.zir_index,
10092 .captures = .{ .external = d.captures },
10093 } },
10094 .declared_owned_captures => |d| .{ .declared = .{
10095 .zir_index = d.zir_index,
10096 .captures = .{ .owned = d.captures },
10097 } },
10098 .reified => |r| .{ .reified = .{
10099 .zir_index = r.zir_index,
10100 .type_hash = r.type_hash,
10101 } },
10102 } };
10103 var gop = if (replace_existing)
10104 ip.putKeyReplace(io, tid, key)
10105 else
10106 try ip.getOrPutKey(gpa, io, tid, key);
10107 defer gop.deinit();
10108 if (gop == .existing) return .{ .existing = gop.existing };
10109
10110 const local = ip.getLocal(tid);
10111 const items = local.getMutableItems(gpa, io);
10112 try items.ensureUnusedCapacity(1);
10113 const extra = local.getMutableExtra(gpa, io);
10114
10115 const names_map = try ip.addMap(gpa, io, tid, ini.fields_len);
10116 errdefer local.mutate.maps.len -= 1;
10117
10118 switch (ini.tag_mode) {
10119 .auto => {
10120 assert(!ini.has_values);
10121 try extra.ensureUnusedCapacity(@typeInfo(EnumAuto).@"struct".fields.len +
10122 // TODO: fmt bug
10123 // zig fmt: off
10124 switch (ini.key) {
10125 inline .declared, .declared_owned_captures => |d| d.captures.len,
10126 .reified => 2, // type_hash: PackedU64
10127 } +
10128 // zig fmt: on
10129 ini.fields_len); // field types
10130
10131 const extra_index = addExtraAssumeCapacity(extra, EnumAuto{
10132 .name = undefined, // set by `prepare`
10133 .name_nav = undefined, // set by `prepare`
10134 .captures_len = switch (ini.key) {
10135 inline .declared, .declared_owned_captures => |d| @intCast(d.captures.len),
10136 .reified => std.math.maxInt(u32),
10137 },
10138 .namespace = undefined, // set by `prepare`
10139 .int_tag_type = .none, // set by `prepare`
10140 .fields_len = ini.fields_len,
10141 .names_map = names_map,
10142 .zir_index = switch (ini.key) {
10143 inline else => |x| x.zir_index,
10144 }.toOptional(),
10145 });
10146 items.appendAssumeCapacity(.{
10147 .tag = .type_enum_auto,
10148 .data = extra_index,
10149 });
10150 switch (ini.key) {
10151 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
10152 .declared_owned_captures => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures.get(ip))}),
10153 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
10154 }
10155 const names_start = extra.mutate.len;
10156 _ = extra.addManyAsSliceAssumeCapacity(ini.fields_len);
10157 return .{ .wip = .{
10158 .tid = tid,
10159 .index = gop.put(),
10160 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,
10161 .type_name_extra_index = extra_index + std.meta.fieldIndex(EnumAuto, "name").?,
10162 .name_nav_extra_index = extra_index + std.meta.fieldIndex(EnumAuto, "name_nav").?,
10163 .namespace_extra_index = extra_index + std.meta.fieldIndex(EnumAuto, "namespace").?,
10164 .names_map = names_map,
10165 .names_start = @intCast(names_start),
10166 .values_map = .none,
10167 .values_start = undefined,
10168 } };
10169 },
10170 .explicit, .nonexhaustive => {
10171 const values_map: OptionalMapIndex = if (!ini.has_values) .none else m: {
10172 const values_map = try ip.addMap(gpa, io, tid, ini.fields_len);
10173 break :m values_map.toOptional();
10174 };
10175 errdefer if (ini.has_values) {
10176 local.mutate.maps.len -= 1;
10177 };
10178
10179 try extra.ensureUnusedCapacity(@typeInfo(EnumExplicit).@"struct".fields.len +
10180 // TODO: fmt bug
10181 // zig fmt: off
10182 switch (ini.key) {
10183 inline .declared, .declared_owned_captures => |d| d.captures.len,
10184 .reified => 2, // type_hash: PackedU64
10185 } +
10186 // zig fmt: on
10187 ini.fields_len + // field types
10188 ini.fields_len * @intFromBool(ini.has_values)); // field values
10189
10190 const extra_index = addExtraAssumeCapacity(extra, EnumExplicit{
10191 .name = undefined, // set by `prepare`
10192 .name_nav = undefined, // set by `prepare`
10193 .captures_len = switch (ini.key) {
10194 inline .declared, .declared_owned_captures => |d| @intCast(d.captures.len),
10195 .reified => std.math.maxInt(u32),
10196 },
10197 .namespace = undefined, // set by `prepare`
10198 .int_tag_type = .none, // set by `prepare`
10199 .fields_len = ini.fields_len,
10200 .names_map = names_map,
10201 .values_map = values_map,
10202 .zir_index = switch (ini.key) {
10203 inline else => |x| x.zir_index,
10204 }.toOptional(),
10205 });
10206 items.appendAssumeCapacity(.{
10207 .tag = switch (ini.tag_mode) {
10208 .auto => unreachable,
10209 .explicit => .type_enum_explicit,
10210 .nonexhaustive => .type_enum_nonexhaustive,
10211 },
10212 .data = extra_index,
10213 });
10214 switch (ini.key) {
10215 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
10216 .declared_owned_captures => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures.get(ip))}),
10217 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
10218 }
10219 const names_start = extra.mutate.len;
10220 _ = extra.addManyAsSliceAssumeCapacity(ini.fields_len);
10221 const values_start = extra.mutate.len;
10222 if (ini.has_values) {
10223 _ = extra.addManyAsSliceAssumeCapacity(ini.fields_len);
10224 }
10225 return .{ .wip = .{
10226 .tid = tid,
10227 .index = gop.put(),
10228 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumExplicit, "int_tag_type").?,
10229 .type_name_extra_index = extra_index + std.meta.fieldIndex(EnumExplicit, "name").?,
10230 .name_nav_extra_index = extra_index + std.meta.fieldIndex(EnumExplicit, "name_nav").?,
10231 .namespace_extra_index = extra_index + std.meta.fieldIndex(EnumExplicit, "namespace").?,
10232 .names_map = names_map,
10233 .names_start = @intCast(names_start),
10234 .values_map = values_map,
10235 .values_start = @intCast(values_start),
10236 } };
10237 },
10238 }
10239}
10240
10241const GeneratedTagEnumTypeInit = struct {
10242 name: NullTerminatedString,
10243 owner_union_ty: Index,
10244 tag_ty: Index,
10245 names: []const NullTerminatedString,
10246 values: []const Index,
10247 tag_mode: LoadedEnumType.TagMode,
10248 parent_namespace: NamespaceIndex,
10249};
10250
10251/// Creates an enum type which was automatically-generated as the tag type of a
10252/// `union` with no explicit tag type. Since this is only called once per union
10253/// type, it asserts that no matching type yet exists.
10254pub fn getGeneratedTagEnumType(
10255 ip: *InternPool,
10256 gpa: Allocator,
10257 io: Io,
10258 tid: Zcu.PerThread.Id,
10259 ini: GeneratedTagEnumTypeInit,
10260) Allocator.Error!Index {
10261 assert(ip.isUnion(ini.owner_union_ty));
10262 assert(ip.isIntegerType(ini.tag_ty));
10263 for (ini.values) |val| assert(ip.typeOf(val) == ini.tag_ty);
10264
10265 const local = ip.getLocal(tid);
10266 const items = local.getMutableItems(gpa, io);
10267 try items.ensureUnusedCapacity(1);
10268 const extra = local.getMutableExtra(gpa, io);
10269
10270 const names_map = try ip.addMap(gpa, io, tid, ini.names.len);
10271 errdefer local.mutate.maps.len -= 1;
10272 ip.addStringsToMap(names_map, ini.names);
10273
10274 const fields_len: u32 = @intCast(ini.names.len);
10275
10276 // Predict the index the enum will live at so we can construct the namespace before releasing the shard's mutex.
10277 const enum_index = Index.Unwrapped.wrap(.{
10278 .tid = tid,
10279 .index = items.mutate.len,
10280 }, ip);
10281 const parent_namespace = ip.namespacePtr(ini.parent_namespace);
10282 const namespace = try ip.createNamespace(gpa, io, tid, .{
10283 .parent = ini.parent_namespace.toOptional(),
10284 .owner_type = enum_index,
10285 .file_scope = parent_namespace.file_scope,
10286 .generation = parent_namespace.generation,
10287 });
10288 errdefer ip.destroyNamespace(tid, namespace);
10289
10290 const prev_extra_len = extra.mutate.len;
10291 switch (ini.tag_mode) {
10292 .auto => {
10293 try extra.ensureUnusedCapacity(@typeInfo(EnumAuto).@"struct".fields.len +
10294 1 + // owner_union
10295 fields_len); // field names
10296 items.appendAssumeCapacity(.{
10297 .tag = .type_enum_auto,
10298 .data = addExtraAssumeCapacity(extra, EnumAuto{
10299 .name = ini.name,
10300 .name_nav = .none,
10301 .captures_len = 0,
10302 .namespace = namespace,
10303 .int_tag_type = ini.tag_ty,
10304 .fields_len = fields_len,
10305 .names_map = names_map,
10306 .zir_index = .none,
10307 }),
10308 });
10309 extra.appendAssumeCapacity(.{@intFromEnum(ini.owner_union_ty)});
10310 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.names)});
10311 },
10312 .explicit, .nonexhaustive => {
10313 try extra.ensureUnusedCapacity(@typeInfo(EnumExplicit).@"struct".fields.len +
10314 1 + // owner_union
10315 fields_len + // field names
10316 ini.values.len); // field values
10317
10318 const values_map: OptionalMapIndex = if (ini.values.len != 0) m: {
10319 const map = try ip.addMap(gpa, io, tid, ini.values.len);
10320 ip.addIndexesToMap(map, ini.values);
10321 break :m map.toOptional();
10322 } else .none;
10323 // We don't clean up the values map on error!
10324 errdefer @compileError("error path leaks values_map");
10325
10326 items.appendAssumeCapacity(.{
10327 .tag = switch (ini.tag_mode) {
10328 .explicit => .type_enum_explicit,
10329 .nonexhaustive => .type_enum_nonexhaustive,
10330 .auto => unreachable,
10331 },
10332 .data = addExtraAssumeCapacity(extra, EnumExplicit{
10333 .name = ini.name,
10334 .name_nav = .none,
10335 .captures_len = 0,
10336 .namespace = namespace,
10337 .int_tag_type = ini.tag_ty,
10338 .fields_len = fields_len,
10339 .names_map = names_map,
10340 .values_map = values_map,
10341 .zir_index = .none,
10342 }),
10343 });
10344 extra.appendAssumeCapacity(.{@intFromEnum(ini.owner_union_ty)});
10345 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.names)});
10346 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.values)});
10347 },
10348 }
10349 errdefer extra.mutate.len = prev_extra_len;
10350 errdefer switch (ini.tag_mode) {
10351 .auto => {},
10352 .explicit, .nonexhaustive => if (ini.values.len != 0) {
10353 local.mutate.maps.len -= 1;
10354 },
10355 };
10356
10357 var gop = try ip.getOrPutKey(gpa, io, tid, .{ .enum_type = .{
10358 .generated_tag = .{ .union_type = ini.owner_union_ty },
10359 } });
10360 defer gop.deinit();
10361 assert(gop.put() == enum_index);
10362 return enum_index;
10363}
10364
10365pub const OpaqueTypeInit = struct {
10366 zir_index: TrackedInst.Index,
10367 captures: []const CaptureValue,
10368};
10369
10370pub fn getOpaqueType(
10371 ip: *InternPool,
10372 gpa: Allocator,
10373 io: Io,
10374 tid: Zcu.PerThread.Id,
10375 ini: OpaqueTypeInit,
10376) Allocator.Error!WipNamespaceType.Result {
10377 var gop = try ip.getOrPutKey(gpa, io, tid, .{ .opaque_type = .{ .declared = .{
10378 .zir_index = ini.zir_index,
10379 .captures = .{ .external = ini.captures },
10380 } } });
10381 defer gop.deinit();
10382 if (gop == .existing) return .{ .existing = gop.existing };
10383
10384 const local = ip.getLocal(tid);
10385 const items = local.getMutableItems(gpa, io);
10386 const extra = local.getMutableExtra(gpa, io);
10387 try items.ensureUnusedCapacity(1);
10388
10389 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeOpaque).@"struct".fields.len + ini.captures.len);
10390 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{
10391 .name = undefined, // set by `finish`
10392 .name_nav = undefined, // set by `finish`
10393 .namespace = undefined, // set by `finish`
10394 .zir_index = ini.zir_index,
10395 .captures_len = @intCast(ini.captures.len),
10396 });
10397 items.appendAssumeCapacity(.{
10398 .tag = .type_opaque,
10399 .data = extra_index,
10400 });
10401 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.captures)});
10402 return .{
10403 .wip = .{
10404 .tid = tid,
10405 .index = gop.put(),
10406 .type_name_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "name").?,
10407 .name_nav_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "name_nav").?,
10408 .namespace_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").?,
10409 },
10410 };
10411}
10412
104139860pub fn getIfExists(ip: *const InternPool, key: Key) ?Index {
104149861 const full_hash = key.hash64(ip);
104159862 const hash: u32 = @truncate(full_hash >> 32);
......@@ -10427,28 +9874,15 @@ pub fn getIfExists(ip: *const InternPool, key: Key) ?Index {
104279874 }
104289875}
104299876
10430fn addStringsToMap(
10431 ip: *InternPool,
10432 map_index: MapIndex,
10433 strings: []const NullTerminatedString,
10434) void {
10435 const map = map_index.get(ip);
10436 const adapter: NullTerminatedString.Adapter = .{ .strings = strings };
10437 for (strings) |string| {
10438 const gop = map.getOrPutAssumeCapacityAdapted(string, adapter);
10439 assert(!gop.found_existing);
10440 }
10441}
10442
10443fn addIndexesToMap(
9877fn addStringsToMap(
104449878 ip: *InternPool,
104459879 map_index: MapIndex,
10446 indexes: []const Index,
9880 strings: []const NullTerminatedString,
104479881) void {
104489882 const map = map_index.get(ip);
10449 const adapter: Index.Adapter = .{ .indexes = indexes };
10450 for (indexes) |index| {
10451 const gop = map.getOrPutAssumeCapacityAdapted(index, adapter);
9883 const adapter: NullTerminatedString.Adapter = .{ .strings = strings };
9884 for (strings) |string| {
9885 const gop = map.getOrPutAssumeCapacityAdapted(string, adapter);
104529886 assert(!gop.found_existing);
104539887 }
104549888}
......@@ -10545,7 +9979,9 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {
105459979 Tag.TypePointer.PackedOffset,
105469980 Tag.TypeUnion.Flags,
105479981 Tag.TypeStruct.Flags,
10548 Tag.TypeStructPacked.Flags,
9982 Tag.TypeStructPacked.Bits,
9983 Tag.TypeUnionPacked.Bits,
9984 Tag.TypeEnum.Bits,
105499985 => @bitCast(@field(item, field.name)),
105509986
105519987 else => @compileError("bad field type: " ++ @typeName(field.type)),
......@@ -10607,8 +10043,10 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat
1060710043 Tag.TypePointer.PackedOffset,
1060810044 Tag.TypeUnion.Flags,
1060910045 Tag.TypeStruct.Flags,
10610 Tag.TypeStructPacked.Flags,
1061110046 FuncAnalysis,
10047 Tag.TypeStructPacked.Bits,
10048 Tag.TypeUnionPacked.Bits,
10049 Tag.TypeEnum.Bits,
1061210050 => @bitCast(extra_item),
1061310051
1061410052 else => @compileError("bad field type: " ++ @typeName(field.type)),
......@@ -10786,7 +10224,7 @@ pub fn getCoerced(
1078610224 .int => |int| switch (ip.indexToKey(new_ty)) {
1078710225 .enum_type => return ip.get(gpa, io, tid, .{ .enum_tag = .{
1078810226 .ty = new_ty,
10789 .int = try ip.getCoerced(gpa, io, tid, val, ip.loadEnumType(new_ty).tag_ty),
10227 .int = try ip.getCoerced(gpa, io, tid, val, ip.loadEnumType(new_ty).int_tag_type),
1079010228 } }),
1079110229 .ptr_type => switch (int.storage) {
1079210230 inline .u64, .i64 => |int_val| return ip.get(gpa, io, tid, .{ .ptr = .{
......@@ -10795,7 +10233,6 @@ pub fn getCoerced(
1079510233 .byte_offset = @intCast(int_val),
1079610234 } }),
1079710235 .big_int => unreachable, // must be a usize
10798 .lazy_align, .lazy_size => {},
1079910236 },
1080010237 else => if (ip.isIntegerType(new_ty))
1080110238 return ip.getCoercedInts(gpa, io, tid, int, new_ty),
......@@ -10825,11 +10262,11 @@ pub fn getCoerced(
1082510262 const index = enum_type.nameIndex(ip, enum_literal).?;
1082610263 return ip.get(gpa, io, tid, .{ .enum_tag = .{
1082710264 .ty = new_ty,
10828 .int = if (enum_type.values.len != 0)
10829 enum_type.values.get(ip)[index]
10265 .int = if (enum_type.field_values.len != 0)
10266 enum_type.field_values.get(ip)[index]
1083010267 else
1083110268 try ip.get(gpa, io, tid, .{ .int = .{
10832 .ty = enum_type.tag_ty,
10269 .ty = enum_type.int_tag_type,
1083310270 .storage = .{ .u64 = index },
1083410271 } }),
1083510272 } });
......@@ -11193,10 +10630,78 @@ pub fn dump(ip: *const InternPool) void {
1119310630 const stderr = std.debug.lockStderr(&buffer);
1119410631 defer std.debug.unlockStderr();
1119510632 const w = &stderr.file_writer.interface;
10633 dumpDependencyStatsFallible(ip, w) catch return;
1119610634 dumpStatsFallible(ip, w, std.heap.page_allocator) catch return;
1119710635 dumpAllFallible(ip, w) catch return;
1119810636}
1119910637
10638fn dumpDependencyStatsFallible(ip: *const InternPool, w: *Io.Writer) !void {
10639 const dep_entries_len = ip.dep_entries.items.len - ip.free_dep_entries.items.len;
10640 const src_hash_deps_len = ip.src_hash_deps.count();
10641 const nav_val_deps_len = ip.nav_val_deps.count();
10642 const nav_ty_deps_len = ip.nav_ty_deps.count();
10643 const func_ies_deps_len = ip.func_ies_deps.count();
10644 const type_layout_deps_len = ip.type_layout_deps.count();
10645 const struct_defaults_deps_len = ip.struct_defaults_deps.count();
10646 const zon_file_deps_len = ip.zon_file_deps.count();
10647 const embed_file_deps_len = ip.embed_file_deps.count();
10648 const namespace_deps_len = ip.namespace_deps.count();
10649 const namespace_name_deps_len = ip.namespace_name_deps.count();
10650 const dep_entries_size = dep_entries_len * @sizeOf(DepEntry);
10651 const src_hash_deps_size = src_hash_deps_len * 8;
10652 const nav_val_deps_size = nav_val_deps_len * 8;
10653 const nav_ty_deps_size = nav_ty_deps_len * 8;
10654 const func_ies_deps_size = func_ies_deps_len * 8;
10655 const type_layout_deps_size = type_layout_deps_len * 8;
10656 const struct_defaults_deps_size = struct_defaults_deps_len * 8;
10657 const zon_file_deps_size = zon_file_deps_len * 8;
10658 const embed_file_deps_size = embed_file_deps_len * 8;
10659 const namespace_deps_size = namespace_deps_len * 8;
10660 const namespace_name_deps_size = namespace_name_deps_len * (@sizeOf(NamespaceNameKey) + 4);
10661
10662 try w.print(
10663 \\InternPool dependencies: {d} bytes
10664 \\ {d} entries: {d} bytes
10665 \\ {d} src_hash: {d} bytes
10666 \\ {d} nav_val: {d} bytes
10667 \\ {d} nav_ty: {d} bytes
10668 \\ {d} func_ies: {d} bytes
10669 \\ {d} type_layout: {d} bytes
10670 \\ {d} struct_defaults: {d} bytes
10671 \\ {d} zon_file: {d} bytes
10672 \\ {d} embed_file: {d} bytes
10673 \\ {d} namespace: {d} bytes
10674 \\ {d} namespace_name: {d} bytes
10675 \\
10676 , .{
10677 dep_entries_size + src_hash_deps_size + nav_val_deps_size + nav_ty_deps_size +
10678 func_ies_deps_size + type_layout_deps_size + struct_defaults_deps_size + zon_file_deps_size +
10679 embed_file_deps_size + namespace_deps_size + namespace_name_deps_size,
10680 dep_entries_len,
10681 dep_entries_size,
10682 src_hash_deps_len,
10683 src_hash_deps_size,
10684 nav_val_deps_len,
10685 nav_val_deps_size,
10686 nav_ty_deps_len,
10687 nav_ty_deps_size,
10688 func_ies_deps_len,
10689 func_ies_deps_size,
10690 type_layout_deps_len,
10691 type_layout_deps_size,
10692 struct_defaults_deps_len,
10693 struct_defaults_deps_size,
10694 zon_file_deps_len,
10695 zon_file_deps_size,
10696 embed_file_deps_len,
10697 embed_file_deps_size,
10698 namespace_deps_len,
10699 namespace_deps_size,
10700 namespace_name_deps_len,
10701 namespace_name_deps_size,
10702 });
10703}
10704
1120010705fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !void {
1120110706 var items_len: usize = 0;
1120210707 var extra_len: usize = 0;
......@@ -11211,10 +10716,10 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
1121110716 const limbs_size = 8 * limbs_len;
1121210717
1121310718 // TODO: map overhead size is not taken into account
11214 const total_size = @sizeOf(InternPool) + items_size + extra_size + limbs_size;
10719 const total_size = items_size + extra_size + limbs_size;
1121510720
11216 std.debug.print(
11217 \\InternPool size: {d} bytes
10721 try w.print(
10722 \\InternPool values: {d} bytes
1121810723 \\ {d} items: {d} bytes
1121910724 \\ {d} extra: {d} bytes
1122010725 \\ {d} limbs: {d} bytes
......@@ -11235,6 +10740,8 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
1123510740 };
1123610741 var counts = std.AutoArrayHashMap(Tag, TagStats).init(arena);
1123710742 for (ip.locals) |*local| {
10743 // Early check for length 0, because `view()` is invalid if capacity is 0
10744 if (local.mutate.items.len == 0) continue;
1123810745 const items = local.shared.items.view().slice();
1123910746 const extra_list = local.shared.extra;
1124010747 const extra_items = extra_list.view().items(.@"0");
......@@ -11266,98 +10773,137 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
1126610773 break :b @sizeOf(Tag.ErrorSet) + (@sizeOf(u32) * info.names_len);
1126710774 },
1126810775 .type_inferred_error_set => 0,
11269 .type_enum_explicit, .type_enum_nonexhaustive => b: {
11270 const info = extraData(extra_list, EnumExplicit, data);
11271 var ints = @typeInfo(EnumExplicit).@"struct".fields.len;
11272 if (info.zir_index == .none) ints += 1;
11273 ints += if (info.captures_len != std.math.maxInt(u32))
11274 info.captures_len
11275 else
11276 @typeInfo(PackedU64).@"struct".fields.len;
11277 ints += info.fields_len;
11278 if (info.values_map != .none) ints += info.fields_len;
11279 break :b @sizeOf(u32) * ints;
11280 },
11281 .type_enum_auto => b: {
11282 const info = extraData(extra_list, EnumAuto, data);
11283 const ints = @typeInfo(EnumAuto).@"struct".fields.len + info.captures_len + info.fields_len;
11284 break :b @sizeOf(u32) * ints;
10776 .type_tuple => b: {
10777 const info = extraData(extra_list, TypeTuple, data);
10778 break :b @sizeOf(TypeTuple) + (@sizeOf(u32) * 2 * info.fields_len);
1128510779 },
11286 .type_opaque => b: {
11287 const info = extraData(extra_list, Tag.TypeOpaque, data);
11288 const ints = @typeInfo(Tag.TypeOpaque).@"struct".fields.len + info.captures_len;
11289 break :b @sizeOf(u32) * ints;
10780 .type_function => b: {
10781 const info = extraData(extra_list, Tag.TypeFunction, data);
10782 break :b @sizeOf(Tag.TypeFunction) +
10783 (@sizeOf(Index) * info.params_len) +
10784 (@as(u32, 4) * @intFromBool(info.flags.has_comptime_bits)) +
10785 (@as(u32, 4) * @intFromBool(info.flags.has_noalias_bits));
1129010786 },
10787
1129110788 .type_struct => b: {
10789 var n: usize = @typeInfo(Tag.TypeStruct).@"struct".fields.len;
1129210790 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);
11293 const info = extra.data;
11294 var ints: usize = @typeInfo(Tag.TypeStruct).@"struct".fields.len;
11295 if (info.flags.any_captures) {
11296 const captures_len = extra_items[extra.end];
11297 ints += 1 + captures_len;
10791 switch (extra.data.flags.any_captures) {
10792 .reified => n += 2, // type_hash: PackedU64
10793 .true => {
10794 n += 1; // captures_len: u32
10795 n += extra_items[extra.end]; // capture: CaptureValue
10796 },
10797 .false => {},
10798 }
10799 n += extra.data.fields_len; // field_name: NullTerminatedString
10800 n += extra.data.fields_len; // field_type: Index
10801 if (extra.data.flags.any_field_defaults) {
10802 n += extra.data.fields_len; // field_default: Index
10803 }
10804 if (extra.data.flags.any_field_aligns) {
10805 n += (extra.data.fields_len + 3) / 4; // field_align: Alignment
1129810806 }
11299 ints += info.fields_len; // types
11300 ints += 1; // names_map
11301 ints += info.fields_len; // names
11302 if (info.flags.any_default_inits)
11303 ints += info.fields_len; // inits
11304 if (info.flags.any_aligned_fields)
11305 ints += (info.fields_len + 3) / 4; // aligns
11306 if (info.flags.any_comptime_fields)
11307 ints += (info.fields_len + 31) / 32; // comptime bits
11308 if (!info.flags.is_extern)
11309 ints += info.fields_len; // runtime order
11310 ints += info.fields_len; // offsets
11311 break :b @sizeOf(u32) * ints;
10807 if (extra.data.flags.any_comptime_fields) {
10808 n += (extra.data.fields_len + 31) / 32; // field_is_comptime_bits: u32
10809 }
10810 if (extra.data.flags.layout == .auto) {
10811 n += extra.data.fields_len; // field_runtime_order: RuntimeOrder
10812 }
10813 n += extra.data.fields_len; // field_offset: u32
10814 break :b n * @sizeOf(u32);
1131210815 },
11313 .type_struct_packed => b: {
10816 .type_struct_packed_auto, .type_struct_packed_explicit => b: {
10817 var n: usize = @typeInfo(Tag.TypeStructPacked).@"struct".fields.len;
1131410818 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
11315 const captures_len = if (extra.data.flags.any_captures)
11316 extra_items[extra.end]
11317 else
11318 0;
11319 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).@"struct".fields.len +
11320 @intFromBool(extra.data.flags.any_captures) + captures_len +
11321 extra.data.fields_len * 2);
10819 switch (extra.data.bits.captures_len) {
10820 .reified => n += 2, // type_hash: PackedU64
10821 _ => |len| n += @intFromEnum(len), // capture: CaptureValue
10822 }
10823 n += extra.data.fields_len; // field_name: NullTerminatedString
10824 n += extra.data.fields_len; // field_type: Index
10825 break :b n * @sizeOf(u32);
1132210826 },
11323 .type_struct_packed_inits => b: {
10827 .type_struct_packed_auto_defaults, .type_struct_packed_explicit_defaults => b: {
10828 var n: usize = @typeInfo(Tag.TypeStructPacked).@"struct".fields.len;
1132410829 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
11325 const captures_len = if (extra.data.flags.any_captures)
11326 extra_items[extra.end]
11327 else
11328 0;
11329 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).@"struct".fields.len +
11330 @intFromBool(extra.data.flags.any_captures) + captures_len +
11331 extra.data.fields_len * 3);
11332 },
11333 .type_tuple => b: {
11334 const info = extraData(extra_list, TypeTuple, data);
11335 break :b @sizeOf(TypeTuple) + (@sizeOf(u32) * 2 * info.fields_len);
10830 switch (extra.data.bits.captures_len) {
10831 .reified => n += 2, // type_hash: PackedU64
10832 _ => |len| n += @intFromEnum(len), // capture: CaptureValue
10833 }
10834 n += extra.data.fields_len; // field_name: NullTerminatedString
10835 n += extra.data.fields_len; // field_type: Index
10836 n += extra.data.fields_len; // field_default: Index
10837 break :b n * @sizeOf(u32);
1133610838 },
11337
1133810839 .type_union => b: {
10840 var n: usize = @typeInfo(Tag.TypeUnion).@"struct".fields.len;
1133910841 const extra = extraDataTrail(extra_list, Tag.TypeUnion, data);
11340 const captures_len = if (extra.data.flags.any_captures)
11341 extra_items[extra.end]
11342 else
11343 0;
11344 const per_field = @sizeOf(u32); // field type
11345 // 1 byte per field for alignment, rounded up to the nearest 4 bytes
11346 const alignments = if (extra.data.flags.any_aligned_fields)
11347 ((extra.data.fields_len + 3) / 4) * 4
11348 else
11349 0;
11350 break :b @sizeOf(Tag.TypeUnion) +
11351 4 * (@intFromBool(extra.data.flags.any_captures) + captures_len) +
11352 (extra.data.fields_len * per_field) + alignments;
10842 switch (extra.data.flags.any_captures) {
10843 .reified => n += 2, // type_hash: PackedU64
10844 .true => {
10845 n += 1; // captures_len: u32
10846 n += extra_items[extra.end]; // capture: CaptureValue
10847 },
10848 .false => {},
10849 }
10850 n += extra.data.fields_len; // field_type: Index
10851 if (extra.data.flags.any_field_aligns) {
10852 n += (extra.data.fields_len + 3) / 4; // field_align: Alignment
10853 }
10854 break :b n * @sizeOf(u32);
1135310855 },
11354
11355 .type_function => b: {
11356 const info = extraData(extra_list, Tag.TypeFunction, data);
11357 break :b @sizeOf(Tag.TypeFunction) +
11358 (@sizeOf(Index) * info.params_len) +
11359 (@as(u32, 4) * @intFromBool(info.flags.has_comptime_bits)) +
11360 (@as(u32, 4) * @intFromBool(info.flags.has_noalias_bits));
10856 .type_union_packed_auto, .type_union_packed_explicit => b: {
10857 var n: usize = @typeInfo(Tag.TypeUnionPacked).@"struct".fields.len;
10858 const extra = extraDataTrail(extra_list, Tag.TypeUnionPacked, data);
10859 switch (extra.data.bits.captures_len) {
10860 .reified => n += 2, // type_hash: PackedU64
10861 _ => |len| n += @intFromEnum(len), // capture: CaptureValue
10862 }
10863 n += extra.data.fields_len; // field_type: Index
10864 break :b n * @sizeOf(u32);
10865 },
10866 .type_enum_auto => b: {
10867 var n: usize = @typeInfo(Tag.TypeEnum).@"struct".fields.len;
10868 const extra = extraData(extra_list, Tag.TypeEnum, data);
10869 switch (extra.bits.captures_len) {
10870 .generated_union_tag => n += 1, // owner_union: Index
10871 .reified => {
10872 n += 1; // zir_index: TrackedInst.Index,
10873 n += 2; // type_hash: PackedU64
10874 },
10875 _ => |len| {
10876 n += 1; // zir_index: TrackedInst.Index,
10877 n += @intFromEnum(len); // capture: CaptureValue
10878 },
10879 }
10880 n += extra.fields_len; // field_name: NullTerminatedString
10881 break :b n * @sizeOf(u32);
10882 },
10883 .type_enum_explicit, .type_enum_nonexhaustive => b: {
10884 var n: usize = @typeInfo(Tag.TypeEnum).@"struct".fields.len;
10885 const extra = extraData(extra_list, Tag.TypeEnum, data);
10886 switch (extra.bits.captures_len) {
10887 .generated_union_tag => n += 1, // owner_union: Index
10888 .reified => {
10889 n += 1; // zir_index: TrackedInst.Index,
10890 n += 2; // type_hash: PackedU64
10891 },
10892 _ => |len| {
10893 n += 1; // zir_index: TrackedInst.Index,
10894 n += @intFromEnum(len); // capture: CaptureValue
10895 },
10896 }
10897 n += 1; // field_value_map: MapIndex
10898 n += extra.fields_len; // field_name: NullTerminatedString
10899 n += extra.fields_len; // field_value: Index
10900 break :b n * @sizeOf(u32);
10901 },
10902 .type_opaque => b: {
10903 var n: usize = @typeInfo(Tag.TypeEnum).@"struct".fields.len;
10904 const extra = extraData(extra_list, Tag.TypeOpaque, data);
10905 n += extra.captures_len; // capture: CaptureValue
10906 break :b n * @sizeOf(u32);
1136110907 },
1136210908
1136310909 .undef => 0,
......@@ -11393,8 +10939,6 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
1139310939 break :b @sizeOf(Int) + int.limbs_len * @sizeOf(Limb);
1139410940 },
1139510941
11396 .int_lazy_align, .int_lazy_size => @sizeOf(IntLazy),
11397
1139810942 .error_set_error, .error_union_error => @sizeOf(Key.Error),
1139910943 .error_union_payload => @sizeOf(Tag.TypeValue),
1140010944 .enum_literal => 0,
......@@ -11432,6 +10976,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
1143210976 .func_coerced => @sizeOf(Tag.FuncCoerced),
1143310977 .only_possible_value => 0,
1143410978 .union_value => @sizeOf(Key.Union),
10979 .bitpack => 2 * @sizeOf(u32),
1143510980
1143610981 .memoized_call => b: {
1143710982 const info = extraData(extra_list, MemoizedCall, data);
......@@ -11458,6 +11003,8 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo
1145811003
1145911004fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {
1146011005 for (ip.locals, 0..) |*local, tid| {
11006 // Early check for length 0, because `view()` is invalid if capacity is 0
11007 if (local.mutate.items.len == 0) continue;
1146111008 const items = local.shared.items.view();
1146211009 for (
1146311010 items.items(.tag)[0..local.mutate.items.len],
......@@ -11484,16 +11031,20 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {
1148411031 .type_anyerror_union,
1148511032 .type_error_set,
1148611033 .type_inferred_error_set,
11034 .type_tuple,
11035 .type_function,
11036 .type_struct,
11037 .type_struct_packed_auto,
11038 .type_struct_packed_explicit,
11039 .type_struct_packed_auto_defaults,
11040 .type_struct_packed_explicit_defaults,
11041 .type_union,
11042 .type_union_packed_auto,
11043 .type_union_packed_explicit,
11044 .type_enum_auto,
1148711045 .type_enum_explicit,
1148811046 .type_enum_nonexhaustive,
11489 .type_enum_auto,
1149011047 .type_opaque,
11491 .type_struct,
11492 .type_struct_packed,
11493 .type_struct_packed_inits,
11494 .type_tuple,
11495 .type_union,
11496 .type_function,
1149711048 .undef,
1149811049 .ptr_nav,
1149911050 .ptr_comptime_alloc,
......@@ -11517,8 +11068,6 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {
1151711068 .int_small,
1151811069 .int_positive,
1151911070 .int_negative,
11520 .int_lazy_align,
11521 .int_lazy_size,
1152211071 .error_set_error,
1152311072 .error_union_error,
1152411073 .error_union_payload,
......@@ -11542,6 +11091,7 @@ fn dumpAllFallible(ip: *const InternPool, w: *Io.Writer) anyerror!void {
1154211091 .func_instance,
1154311092 .func_coerced,
1154411093 .union_value,
11094 .bitpack,
1154511095 .memoized_call,
1154611096 => try w.print("{d}", .{data}),
1154711097
......@@ -11581,7 +11131,7 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator,
1158111131 const info = extraData(extra_list, Tag.FuncInstance, data);
1158211132
1158311133 const gop = try instances.getOrPut(arena, info.generic_owner);
11584 if (!gop.found_existing) gop.value_ptr.* = .{};
11134 if (!gop.found_existing) gop.value_ptr.* = .empty;
1158511135
1158611136 try gop.value_ptr.append(
1158711137 arena,
......@@ -11722,6 +11272,7 @@ pub fn createDeclNav(
1172211272 .analysis = .{
1172311273 .namespace = namespace,
1172411274 .zir_index = zir_index,
11275 .wanted = false,
1172511276 },
1172611277 .status = .unresolved,
1172711278 }));
......@@ -12245,16 +11796,20 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1224511796 .type_anyerror_union,
1224611797 .type_error_set,
1224711798 .type_inferred_error_set,
11799 .type_tuple,
11800 .type_function,
11801 .type_struct,
11802 .type_struct_packed_auto,
11803 .type_struct_packed_explicit,
11804 .type_struct_packed_auto_defaults,
11805 .type_struct_packed_explicit_defaults,
11806 .type_union,
11807 .type_union_packed_auto,
11808 .type_union_packed_explicit,
1224811809 .type_enum_auto,
1224911810 .type_enum_explicit,
1225011811 .type_enum_nonexhaustive,
1225111812 .type_opaque,
12252 .type_struct,
12253 .type_struct_packed,
12254 .type_struct_packed_inits,
12255 .type_tuple,
12256 .type_union,
12257 .type_function,
1225811813 => .type_type,
1225911814
1226011815 .undef,
......@@ -12278,8 +11833,6 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1227811833 .opt_payload,
1227911834 .error_union_payload,
1228011835 .int_small,
12281 .int_lazy_align,
12282 .int_lazy_size,
1228311836 .error_set_error,
1228411837 .error_union_error,
1228511838 .enum_tag,
......@@ -12293,6 +11846,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1229311846 .bytes,
1229411847 .aggregate,
1229511848 .repeated,
11849 .bitpack,
1229611850 => |t| {
1229711851 const extra_list = unwrapped_index.getExtra(ip);
1229811852 return @enumFromInt(extra_list.view().items(.@"0")[item.data + std.meta.fieldIndex(t.Payload(), "ty").?]);
......@@ -12389,20 +11943,6 @@ pub fn funcTypeReturnType(ip: *const InternPool, ty: Index) Index {
1238911943 ]);
1239011944}
1239111945
12392pub fn isNoReturn(ip: *const InternPool, ty: Index) bool {
12393 switch (ty) {
12394 .noreturn_type => return true,
12395 else => {
12396 const unwrapped_ty = ty.unwrap(ip);
12397 const ty_item = unwrapped_ty.getItem(ip);
12398 return switch (ty_item.tag) {
12399 .type_error_set => unwrapped_ty.getExtra(ip).view().items(.@"0")[ty_item.data + std.meta.fieldIndex(Tag.ErrorSet, "names_len").?] == 0,
12400 else => false,
12401 };
12402 },
12403 }
12404}
12405
1240611946pub fn isUndef(ip: *const InternPool, val: Index) bool {
1240711947 return val == .undef or val.unwrap(ip).getTag(ip) == .undef;
1240811948}
......@@ -12613,22 +12153,26 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
1261312153 .type_inferred_error_set,
1261412154 => .error_set,
1261512155
12616 .type_enum_auto,
12617 .type_enum_explicit,
12618 .type_enum_nonexhaustive,
12619 => .@"enum",
12620
1262112156 .simple_type => unreachable, // handled via Index tag above
1262212157
12623 .type_opaque => .@"opaque",
12158 .type_tuple => .@"struct",
1262412159
1262512160 .type_struct,
12626 .type_struct_packed,
12627 .type_struct_packed_inits,
12628 .type_tuple,
12161 .type_struct_packed_auto,
12162 .type_struct_packed_explicit,
12163 .type_struct_packed_auto_defaults,
12164 .type_struct_packed_explicit_defaults,
1262912165 => .@"struct",
12630
12631 .type_union => .@"union",
12166 .type_union,
12167 .type_union_packed_auto,
12168 .type_union_packed_explicit,
12169 => .@"union",
12170 .type_enum_auto,
12171 .type_enum_explicit,
12172 .type_enum_nonexhaustive,
12173 => .@"enum",
12174 .type_opaque,
12175 => .@"opaque",
1263212176
1263312177 .type_function => .@"fn",
1263412178
......@@ -12658,8 +12202,6 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
1265812202 .int_small,
1265912203 .int_positive,
1266012204 .int_negative,
12661 .int_lazy_align,
12662 .int_lazy_size,
1266312205 .error_set_error,
1266412206 .error_union_error,
1266512207 .error_union_payload,
......@@ -12684,6 +12226,7 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
1268412226 .bytes,
1268512227 .aggregate,
1268612228 .repeated,
12229 .bitpack,
1268712230 // memoization, not types
1268812231 .memoized_call,
1268912232 => unreachable,
......@@ -12871,22 +12414,42 @@ pub fn unwrapCoercedFunc(ip: *const InternPool, index: Index) Index {
1287112414 };
1287212415}
1287312416
12874/// Returns the already-existing field with the same name, if any.
12417/// Puts `name` into `names_slice` at the next index (that being the current length of `map`).
12418/// Also inserts the name into `map`. If there is an existing field with this name, its index
12419/// is returned. Otherwise, `null` is returned.
1287512420pub fn addFieldName(
1287612421 ip: *InternPool,
12877 extra: Local.Extra,
12878 names_map: MapIndex,
12879 names_start: u32,
12422 names: NullTerminatedString.Slice,
12423 map: MapIndex,
1288012424 name: NullTerminatedString,
1288112425) ?u32 {
12882 const extra_items = extra.view().items(.@"0");
12883 const map = names_map.get(ip);
12884 const field_index = map.count();
12885 const strings = extra_items[names_start..][0..field_index];
12886 const adapter: NullTerminatedString.Adapter = .{ .strings = @ptrCast(strings) };
12887 const gop = map.getOrPutAssumeCapacityAdapted(name, adapter);
12426 const m = map.get(ip);
12427 const field_idx = m.count();
12428 const names_slice = names.get(ip);
12429 names_slice[field_idx] = name;
12430 const adapter: NullTerminatedString.Adapter = .{ .strings = names_slice[0..field_idx] };
12431 const gop = m.getOrPutAssumeCapacityAdapted(name, adapter);
1288812432 if (gop.found_existing) return @intCast(gop.index);
12889 extra_items[names_start + field_index] = @intFromEnum(name);
12433 assert(gop.index == field_idx);
12434 return null;
12435}
12436
12437/// Like `addFieldName`, but instead of adding a field name to a struct, union, or enum, adds a
12438/// field tag value for an enum.
12439pub fn addFieldTagValue(
12440 ip: *InternPool,
12441 values: Index.Slice,
12442 map: MapIndex,
12443 value: Index,
12444) ?u32 {
12445 const m = map.get(ip);
12446 const field_idx = m.count();
12447 const values_slice = values.get(ip);
12448 values_slice[field_idx] = value;
12449 const adapter: Index.Adapter = .{ .indexes = values_slice[0..field_idx] };
12450 const gop = m.getOrPutAssumeCapacityAdapted(value, adapter);
12451 if (gop.found_existing) return @intCast(gop.index);
12452 assert(gop.index == field_idx);
1289012453 return null;
1289112454}
1289212455
......@@ -13169,3 +12732,275 @@ const PackedCallingConvention = packed struct(u18) {
1316912732 };
1317012733 }
1317112734};
12735
12736/// Asserts that `struct_type` is a non-packed struct type.
12737/// As well as calling this function, the caller must also populate these arrays:
12738/// * `field_types`
12739/// * `field_aligns`
12740/// * `field_runtime_order`
12741/// * `field_offsets`
12742pub fn resolveStructLayout(
12743 ip: *InternPool,
12744 io: Io,
12745 struct_type: Index,
12746 size: u32,
12747 alignment: Alignment,
12748 class: TypeClass,
12749) void {
12750 const unwrapped_index = struct_type.unwrap(ip);
12751
12752 const local = ip.getLocal(unwrapped_index.tid);
12753 local.mutate.extra.mutex.lockUncancelable(io);
12754 defer local.mutate.extra.mutex.unlock(io);
12755
12756 const extra_items = local.shared.extra.view().items(.@"0");
12757 const item = unwrapped_index.getItem(ip);
12758 assert(item.tag == .type_struct);
12759
12760 extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "size").?] = size;
12761 const flags: *Tag.TypeStruct.Flags = @ptrCast(&extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?]);
12762 flags.class = class;
12763 flags.alignment = alignment;
12764}
12765
12766/// Asserts that `union_type` is a non-packed union type.
12767/// As well as calling this function, the caller must also populate these arrays:
12768/// * `field_types`
12769/// * `field_aligns`
12770pub fn resolveUnionLayout(
12771 ip: *InternPool,
12772 io: Io,
12773 union_type: Index,
12774 enum_tag_type: Index,
12775 class: TypeClass,
12776 has_runtime_tag: bool,
12777 size: u32,
12778 padding: u32,
12779 alignment: Alignment,
12780) void {
12781 const unwrapped_index = union_type.unwrap(ip);
12782
12783 const local = ip.getLocal(unwrapped_index.tid);
12784 local.mutate.extra.mutex.lockUncancelable(io);
12785 defer local.mutate.extra.mutex.unlock(io);
12786
12787 const extra_items = local.shared.extra.view().items(.@"0");
12788 const item = unwrapped_index.getItem(ip);
12789 assert(item.tag == .type_union);
12790
12791 extra_items[item.data + std.meta.fieldIndex(Tag.TypeUnion, "enum_tag_type").?] = @intFromEnum(enum_tag_type);
12792 extra_items[item.data + std.meta.fieldIndex(Tag.TypeUnion, "size").?] = size;
12793 extra_items[item.data + std.meta.fieldIndex(Tag.TypeUnion, "padding").?] = padding;
12794 const flags: *Tag.TypeUnion.Flags = @ptrCast(&extra_items[item.data + std.meta.fieldIndex(Tag.TypeUnion, "flags").?]);
12795 flags.class = class;
12796 flags.has_runtime_tag = has_runtime_tag;
12797 flags.alignment = alignment;
12798}
12799
12800/// Asserts that `struct_type` is a packed struct type.
12801pub fn resolvePackedStructLayout(
12802 ip: *InternPool,
12803 io: Io,
12804 struct_type: Index,
12805 backing_int_type: Index,
12806) void {
12807 const unwrapped_index = struct_type.unwrap(ip);
12808
12809 const local = ip.getLocal(unwrapped_index.tid);
12810 local.mutate.extra.mutex.lockUncancelable(io);
12811 defer local.mutate.extra.mutex.unlock(io);
12812
12813 const extra_items = local.shared.extra.view().items(.@"0");
12814 const item = unwrapped_index.getItem(ip);
12815 switch (item.tag) {
12816 .type_struct_packed_auto,
12817 .type_struct_packed_explicit,
12818 .type_struct_packed_auto_defaults,
12819 .type_struct_packed_explicit_defaults,
12820 => {},
12821 else => unreachable,
12822 }
12823
12824 extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "backing_int_type").?] = @intFromEnum(backing_int_type);
12825}
12826
12827/// Asserts that `union_type` is a packed union type.
12828pub fn resolvePackedUnionLayout(
12829 ip: *InternPool,
12830 io: Io,
12831 union_type: Index,
12832 enum_tag_type: Index,
12833 backing_int_type: Index,
12834) void {
12835 const unwrapped_index = union_type.unwrap(ip);
12836
12837 const local = ip.getLocal(unwrapped_index.tid);
12838 local.mutate.extra.mutex.lockUncancelable(io);
12839 defer local.mutate.extra.mutex.unlock(io);
12840
12841 const extra_items = local.shared.extra.view().items(.@"0");
12842 const item = unwrapped_index.getItem(ip);
12843 switch (item.tag) {
12844 .type_union_packed_auto,
12845 .type_union_packed_explicit,
12846 => {},
12847 else => unreachable,
12848 }
12849
12850 extra_items[item.data + std.meta.fieldIndex(Tag.TypeUnionPacked, "enum_tag_type").?] = @intFromEnum(enum_tag_type);
12851 extra_items[item.data + std.meta.fieldIndex(Tag.TypeUnionPacked, "backing_int_type").?] = @intFromEnum(backing_int_type);
12852}
12853
12854/// Asserts that `enum_type` is an enum type.
12855pub fn resolveEnumLayout(
12856 ip: *InternPool,
12857 io: Io,
12858 enum_type: Index,
12859 int_tag_type: Index,
12860) void {
12861 const unwrapped_index = enum_type.unwrap(ip);
12862
12863 const local = ip.getLocal(unwrapped_index.tid);
12864 local.mutate.extra.mutex.lockUncancelable(io);
12865 defer local.mutate.extra.mutex.unlock(io);
12866
12867 const extra_items = local.shared.extra.view().items(.@"0");
12868 const item = unwrapped_index.getItem(ip);
12869 switch (item.tag) {
12870 .type_enum_auto,
12871 .type_enum_explicit,
12872 .type_enum_nonexhaustive,
12873 => {},
12874 else => unreachable,
12875 }
12876
12877 extra_items[item.data + std.meta.fieldIndex(Tag.TypeEnum, "int_tag_type").?] = @intFromEnum(int_tag_type);
12878}
12879
12880/// Sets the "want_layout" flag on the given struct, union, or enum type. Returns true if the flag
12881/// was *not* already set, meaning we have just discovered the first reference to this type's
12882/// layout. This flag is never reset to false, and exists purely as an optimization; for details,
12883/// see doc comments in `LoadedStructType`.
12884pub fn setWantTypeLayout(ip: *InternPool, io: Io, container_type: Index) bool {
12885 const unwrapped_index = container_type.unwrap(ip);
12886
12887 const local = ip.getLocal(unwrapped_index.tid);
12888 local.mutate.extra.mutex.lockUncancelable(io);
12889 defer local.mutate.extra.mutex.unlock(io);
12890
12891 const extra_items = local.shared.extra.view().items(.@"0");
12892 const item = unwrapped_index.getItem(ip);
12893 switch (item.tag) {
12894 .type_struct_packed_auto,
12895 .type_struct_packed_explicit,
12896 .type_struct_packed_auto_defaults,
12897 .type_struct_packed_explicit_defaults,
12898 => {
12899 const bits: *Tag.TypeStructPacked.Bits = @ptrCast(&extra_items[
12900 item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "bits").?
12901 ]);
12902 if (bits.want_layout) {
12903 return false;
12904 } else {
12905 bits.want_layout = true;
12906 return true;
12907 }
12908 },
12909
12910 .type_struct => {
12911 const flags: *Tag.TypeStruct.Flags = @ptrCast(&extra_items[
12912 item.data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?
12913 ]);
12914 if (flags.want_layout) {
12915 return false;
12916 } else {
12917 flags.want_layout = true;
12918 return true;
12919 }
12920 },
12921
12922 .type_union_packed_auto,
12923 .type_union_packed_explicit,
12924 => {
12925 const bits: *Tag.TypeUnionPacked.Bits = @ptrCast(&extra_items[
12926 item.data + std.meta.fieldIndex(Tag.TypeUnionPacked, "bits").?
12927 ]);
12928 if (bits.want_layout) {
12929 return false;
12930 } else {
12931 bits.want_layout = true;
12932 return true;
12933 }
12934 },
12935
12936 .type_union => {
12937 const flags: *Tag.TypeUnion.Flags = @ptrCast(&extra_items[
12938 item.data + std.meta.fieldIndex(Tag.TypeUnion, "flags").?
12939 ]);
12940 if (flags.want_layout) {
12941 return false;
12942 } else {
12943 flags.want_layout = true;
12944 return true;
12945 }
12946 },
12947
12948 .type_enum_auto,
12949 .type_enum_explicit,
12950 .type_enum_nonexhaustive,
12951 => {
12952 const bits: *Tag.TypeEnum.Bits = @ptrCast(&extra_items[
12953 item.data + std.meta.fieldIndex(Tag.TypeEnum, "bits").?
12954 ]);
12955 if (bits.want_layout) {
12956 return false;
12957 } else {
12958 bits.want_layout = true;
12959 return true;
12960 }
12961 },
12962
12963 else => unreachable,
12964 }
12965}
12966
12967/// Like `setWantTypeLayout`, but for runtime analysis of a function body, using the
12968/// `FuncAnalysis.want_runtime_analysis` flag.
12969pub fn setWantRuntimeFnAnalysis(ip: *InternPool, io: Io, func_index: Index) bool {
12970 const unwrapped_index = func_index.unwrap(ip);
12971
12972 const local = ip.getLocal(unwrapped_index.tid);
12973 local.mutate.extra.mutex.lockUncancelable(io);
12974 defer local.mutate.extra.mutex.unlock(io);
12975
12976 const a = funcAnalysisPtr(ip, func_index);
12977 if (a.want_runtime_analysis) {
12978 return false;
12979 } else {
12980 a.want_runtime_analysis = true;
12981 return true;
12982 }
12983}
12984
12985/// Like `setWantTypeLayout`, but for runtime analysis of a `Nav`, using the `Nav.analysis.wanted` flag.
12986pub fn setWantNavAnalysis(ip: *InternPool, io: Io, nav_index: Nav.Index) bool {
12987 const unwrapped = nav_index.unwrap(ip);
12988
12989 const local = ip.getLocal(unwrapped.tid);
12990 local.mutate.extra.mutex.lockUncancelable(io);
12991 defer local.mutate.extra.mutex.unlock(io);
12992
12993 const navs = local.shared.navs.view();
12994
12995 if (navs.items(.analysis_namespace)[unwrapped.index] == .none) {
12996 return false;
12997 }
12998
12999 const bits = &navs.items(.bits)[unwrapped.index];
13000 if (bits.want_analysis) {
13001 return false;
13002 } else {
13003 bits.want_analysis = true;
13004 return true;
13005 }
13006}
src/Package/Manifest.zig+3-3
......@@ -66,7 +66,7 @@ pub fn parse(gpa: Allocator, ast: *const Ast, rng: std.Random, options: ParseOpt
6666 .gpa = gpa,
6767 .ast = ast.*,
6868 .arena = arena_instance.allocator(),
69 .errors = .{},
69 .errors = .empty,
7070
7171 .name = undefined,
7272 .id = 0,
......@@ -74,10 +74,10 @@ pub fn parse(gpa: Allocator, ast: *const Ast, rng: std.Random, options: ParseOpt
7474 .version_node = undefined,
7575 .dependencies = .{},
7676 .dependencies_node = .none,
77 .paths = .{},
77 .paths = .empty,
7878 .allow_missing_paths_field = options.allow_missing_paths_field,
7979 .minimum_zig_version = null,
80 .buf = .{},
80 .buf = .empty,
8181 };
8282 defer p.buf.deinit(gpa);
8383 defer p.errors.deinit(gpa);
src/Sema.zig+4104-7112
......@@ -173,13 +173,20 @@ const ComptimeAlloc = struct {
173173 runtime_index: RuntimeIndex,
174174};
175175
176/// Asserts that `ty` is not an OPV type.
176177/// `src` may be `null` if `is_const` will be set.
177178fn newComptimeAlloc(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type, alignment: Alignment) !ComptimeAllocIndex {
178179 const pt = sema.pt;
179 const init_val = try sema.typeHasOnePossibleValue(ty) orelse try pt.undefValue(ty);
180
181 switch (ty.classify(pt.zcu)) {
182 .no_possible_value => unreachable,
183 .one_possible_value => unreachable,
184 else => {},
185 }
186
180187 const idx = sema.comptime_allocs.items.len;
181188 try sema.comptime_allocs.append(sema.gpa, .{
182 .val = .{ .interned = init_val.toIntern() },
189 .val = .{ .interned = (try pt.undefValue(ty)).toIntern() },
183190 .is_const = false,
184191 .src = src,
185192 .alignment = alignment,
......@@ -393,7 +400,7 @@ pub const Block = struct {
393400 /// The name of the current "context" for naming namespace types.
394401 /// The interpretation of this depends on the name strategy in ZIR, but the name
395402 /// is always incorporated into the type name somehow.
396 /// See `Sema.createTypeName`.
403 /// See `Sema.setTypeName`.
397404 type_name_ctx: InternPool.NullTerminatedString,
398405
399406 /// Create a `LazySrcLoc` based on an `Offset` from the code being analyzed in this block.
......@@ -409,7 +416,7 @@ pub const Block = struct {
409416 return block.comptime_reason != null;
410417 }
411418
412 fn builtinCallArgSrc(block: *Block, builtin_call_node: std.zig.Ast.Node.Offset, arg_index: u32) LazySrcLoc {
419 pub fn builtinCallArgSrc(block: *Block, builtin_call_node: std.zig.Ast.Node.Offset, arg_index: u32) LazySrcLoc {
413420 return block.src(.{ .node_offset_builtin_call_arg = .{
414421 .builtin_call_node = builtin_call_node,
415422 .arg_index = arg_index,
......@@ -1082,7 +1089,7 @@ fn analyzeInlineBody(
10821089 // This control flow goes further up the stack.
10831090 return error.ComptimeBreak;
10841091 }
1085 return try sema.resolveInst(break_inst.data.@"break".operand);
1092 return sema.resolveInst(break_inst.data.@"break".operand);
10861093}
10871094
10881095/// Like `analyzeInlineBody`, but if the body does not break with a value, returns
......@@ -1154,7 +1161,7 @@ fn analyzeBodyInner(
11541161 }, inst });
11551162 }
11561163
1157 const air_inst: Air.Inst.Ref = inst: switch (tags[@intFromEnum(inst)]) {
1164 const air_ref: Air.Inst.Ref = inst: switch (tags[@intFromEnum(inst)]) {
11581165 // zig fmt: off
11591166 .alloc => try sema.zirAlloc(block, inst),
11601167 .alloc_inferred => try sema.zirAllocInferred(block, true),
......@@ -1382,10 +1389,10 @@ fn analyzeBodyInner(
13821389 const extended = datas[@intFromEnum(inst)].extended;
13831390 break :ext switch (extended.opcode) {
13841391 // zig fmt: off
1385 .struct_decl => try sema.zirStructDecl( block, extended, inst),
1386 .enum_decl => try sema.zirEnumDecl( block, extended, inst),
1387 .union_decl => try sema.zirUnionDecl( block, extended, inst),
1388 .opaque_decl => try sema.zirOpaqueDecl( block, extended, inst),
1392 .struct_decl => try sema.zirStructDecl( block, inst),
1393 .enum_decl => try sema.zirEnumDecl( block, inst),
1394 .union_decl => try sema.zirUnionDecl( block, inst),
1395 .opaque_decl => try sema.zirOpaqueDecl( block, inst),
13891396 .tuple_decl => try sema.zirTupleDecl( block, extended),
13901397 .this => try sema.zirThis( block, extended),
13911398 .ret_addr => try sema.zirRetAddr( block, extended),
......@@ -1869,7 +1876,7 @@ fn analyzeBodyInner(
18691876
18701877 const break_data = opt_break_data orelse break;
18711878 if (inst == break_data.block_inst) {
1872 break :blk try sema.resolveInst(break_data.operand);
1879 break :blk sema.resolveInst(break_data.operand);
18731880 } else {
18741881 // `comptime_break_inst` preserved from `analyzeBodyInner` above.
18751882 return error.ComptimeBreak;
......@@ -1890,7 +1897,7 @@ fn analyzeBodyInner(
18901897 extra.end + then_body.len,
18911898 extra.data.else_body_len,
18921899 );
1893 const uncasted_cond = try sema.resolveInst(extra.data.condition);
1900 const uncasted_cond = sema.resolveInst(extra.data.condition);
18941901 const cond = try sema.coerce(block, .bool, uncasted_cond, cond_src);
18951902 const cond_val = try sema.resolveConstDefinedValue(
18961903 block,
......@@ -1916,7 +1923,7 @@ fn analyzeBodyInner(
19161923 const operand_src = block.src(.{ .node_offset_try_operand = inst_data.src_node });
19171924 const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);
19181925 const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);
1919 const err_union = try sema.resolveInst(extra.data.operand);
1926 const err_union = sema.resolveInst(extra.data.operand);
19201927 const err_union_ty = sema.typeOf(err_union);
19211928 if (err_union_ty.zigTypeTag(zcu) != .error_union) {
19221929 return sema.failWithOwnedErrorMsg(block, msg: {
......@@ -1942,7 +1949,7 @@ fn analyzeBodyInner(
19421949 const operand_src = block.src(.{ .node_offset_try_operand = inst_data.src_node });
19431950 const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);
19441951 const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);
1945 const operand = try sema.resolveInst(extra.data.operand);
1952 const operand = sema.resolveInst(extra.data.operand);
19461953 const err_union = try sema.analyzeLoad(block, src, operand, operand_src);
19471954 const is_non_err_val = (try sema.resolveIsNonErrVal(block, operand_src, err_union)).?;
19481955 if (is_non_err_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, operand_src, null);
......@@ -1971,7 +1978,7 @@ fn analyzeBodyInner(
19711978 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].defer_err_code;
19721979 const extra = sema.code.extraData(Zir.Inst.DeferErrCode, inst_data.payload_index).data;
19731980 const defer_body = sema.code.bodySlice(extra.index, extra.len);
1974 const err_code = try sema.resolveInst(inst_data.err_code);
1981 const err_code = sema.resolveInst(inst_data.err_code);
19751982 try map.ensureSpaceForInstructions(sema.gpa, defer_body);
19761983 map.putAssumeCapacity(extra.remapped_err_code, err_code);
19771984 if (sema.analyzeBodyInner(block, defer_body)) {
......@@ -1987,18 +1994,35 @@ fn analyzeBodyInner(
19871994 break :blk .void_value;
19881995 },
19891996 };
1990 if (sema.isNoReturn(air_inst)) {
1991 // We're going to assume that the body itself is noreturn, so let's ensure that now
1992 assert(block.instructions.items.len > 0);
1993 assert(sema.isNoReturn(block.instructions.items[block.instructions.items.len - 1].toRef()));
1994 break;
1995 }
1996 map.putAssumeCapacity(inst, air_inst);
1997
1998 const is_inferred_alloc = if (air_ref.toIndex()) |air_inst| switch (sema.air_instructions.items(.tag)[@intFromEnum(air_inst)]) {
1999 .inferred_alloc, .inferred_alloc_comptime => true,
2000 else => false,
2001 } else false;
2002 // We must resolve the layout of a type before creating a value of that type. Therefore,
2003 // the layout of the type of `air_ref` must already be resolved. The call to `classify`
2004 // doubles as an assertion of this.
2005 if (!is_inferred_alloc) switch (sema.typeOf(air_ref).classify(zcu)) {
2006 .no_possible_value => {
2007 // The instruction result was noreturn, which should mean that the body itself now
2008 // ends with a noreturn instruction. Let's confirm that.
2009 const last_inst = block.instructions.items[block.instructions.items.len - 1];
2010 const last_inst_ty = sema.typeOf(last_inst.toRef());
2011 assert(last_inst_ty.classify(zcu) == .no_possible_value);
2012 break;
2013 },
2014 .one_possible_value => assert(air_ref.toInterned() != null), // the value should be comptime-known
2015 .partially_comptime => assert(air_ref.toInterned() != null), // the value should be comptime-known
2016 .fully_comptime => assert(air_ref.toInterned() != null), // the value should be comptime-known
2017 .runtime => {},
2018 };
2019
2020 map.putAssumeCapacity(inst, air_ref);
19972021 i += 1;
19982022 }
19992023}
20002024
2001pub fn resolveInstAllowNone(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref {
2025fn resolveInstAllowNone(sema: *Sema, zir_ref: Zir.Inst.Ref) Air.Inst.Ref {
20022026 if (zir_ref == .none) {
20032027 return .none;
20042028 } else {
......@@ -2006,7 +2030,7 @@ pub fn resolveInstAllowNone(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref {
20062030 }
20072031}
20082032
2009pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref {
2033fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) Air.Inst.Ref {
20102034 assert(zir_ref != .none);
20112035 if (zir_ref.toIndex()) |i| {
20122036 return sema.inst_map.get(i).?;
......@@ -2023,7 +2047,7 @@ fn resolveConstBool(
20232047 zir_ref: Zir.Inst.Ref,
20242048 reason: ComptimeReason,
20252049) !bool {
2026 const air_inst = try sema.resolveInst(zir_ref);
2050 const air_inst = sema.resolveInst(zir_ref);
20272051 const wanted_type: Type = .bool;
20282052 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
20292053 const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason);
......@@ -2039,7 +2063,7 @@ fn resolveConstString(
20392063 /// being comptime-resolved is that the block is being comptime-evaluated.
20402064 reason: ?ComptimeReason,
20412065) ![]u8 {
2042 const air_inst = try sema.resolveInst(zir_ref);
2066 const air_inst = sema.resolveInst(zir_ref);
20432067 return sema.toConstString(block, src, air_inst, reason);
20442068}
20452069
......@@ -2066,7 +2090,7 @@ pub fn resolveConstStringIntern(
20662090 zir_ref: Zir.Inst.Ref,
20672091 reason: ComptimeReason,
20682092) !InternPool.NullTerminatedString {
2069 const air_inst = try sema.resolveInst(zir_ref);
2093 const air_inst = sema.resolveInst(zir_ref);
20702094 const wanted_type: Type = .slice_const_u8;
20712095 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
20722096 const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, reason);
......@@ -2074,8 +2098,8 @@ pub fn resolveConstStringIntern(
20742098}
20752099
20762100fn resolveTypeOrPoison(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !?Type {
2077 const air_inst = try sema.resolveInst(zir_ref);
2078 const ty = try sema.analyzeAsType(block, src, air_inst);
2101 const air_inst = sema.resolveInst(zir_ref);
2102 const ty = try sema.analyzeAsType(block, src, .type, air_inst);
20792103 if (ty.isGenericPoison()) return null;
20802104 return ty;
20812105}
......@@ -2168,7 +2192,7 @@ fn genericPoisonReason(sema: *Sema, block: *Block, ref: Zir.Inst.Ref) GenericPoi
21682192 // There are two cases here: the pointer type may already have been
21692193 // generic poison, or it may have been an anyopaque pointer.
21702194 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
2171 const operand_ref = try sema.resolveInst(un_node.operand);
2195 const operand_ref = sema.resolveInst(un_node.operand);
21722196 const operand_val = operand_ref.toInterned() orelse return .unknown;
21732197 if (operand_val == .generic_poison_type) {
21742198 // The pointer was generic poison - keep looking.
......@@ -2190,15 +2214,16 @@ fn genericPoisonReason(sema: *Sema, block: *Block, ref: Zir.Inst.Ref) GenericPoi
21902214 }
21912215}
21922216
2193fn analyzeAsType(
2217pub fn analyzeAsType(
21942218 sema: *Sema,
21952219 block: *Block,
21962220 src: LazySrcLoc,
2221 reason: std.zig.SimpleComptimeReason,
21972222 air_inst: Air.Inst.Ref,
21982223) !Type {
21992224 const wanted_type: Type = .type;
22002225 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
2201 const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, .{ .simple = .type });
2226 const val = try sema.resolveConstDefinedValue(block, src, coerced_inst, .{ .simple = reason });
22022227 return val.toType();
22032228}
22042229
......@@ -2227,7 +2252,6 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
22272252
22282253 // var st: StackTrace = undefined;
22292254 const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(.zero), .StackTrace);
2230 try stack_trace_ty.resolveFields(pt);
22312255 const st_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(stack_trace_ty));
22322256
22332257 // st.instruction_addresses = &addrs;
......@@ -2247,14 +2271,10 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
22472271}
22482272
22492273/// Return the Value corresponding to a given AIR ref, or `null` if it refers to a runtime value.
2250fn resolveValue(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value {
2274fn resolveValue(sema: *Sema, inst: Air.Inst.Ref) ?Value {
22512275 const zcu = sema.pt.zcu;
22522276 assert(inst != .none);
22532277
2254 if (try sema.typeHasOnePossibleValue(sema.typeOf(inst))) |opv| {
2255 return opv;
2256 }
2257
22582278 if (inst.toInterned()) |ip_index| {
22592279 const val: Value = .fromInterned(ip_index);
22602280 assert(val.getVariable(zcu) == null);
......@@ -2267,12 +2287,21 @@ fn resolveValue(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value {
22672287 .inferred_alloc_comptime => unreachable, // assertion failure
22682288 else => {},
22692289 }
2290 // LLVM fails to eliminate this `classify` call in ReleaseFast, which hurts performance, so
2291 // we must explicitly check for `std.debug.runtime_safety`.
2292 if (std.debug.runtime_safety) switch (sema.typeOf(inst).classify(zcu)) {
2293 .no_possible_value => unreachable, // values of this type do not exist
2294 .one_possible_value => unreachable, // the value should be comptime-known
2295 .partially_comptime => unreachable, // the value should be comptime-known
2296 .fully_comptime => unreachable, // the value should be comptime-known
2297 .runtime => {},
2298 };
22702299 return null;
22712300 }
22722301}
22732302
22742303/// Like `resolveValue`, but emits an error if the value is not comptime-known.
2275fn resolveConstValue(
2304pub fn resolveConstValue(
22762305 sema: *Sema,
22772306 block: *Block,
22782307 src: LazySrcLoc,
......@@ -2281,7 +2310,8 @@ fn resolveConstValue(
22812310 /// being comptime-resolved is that the block is being comptime-evaluated.
22822311 reason: ?ComptimeReason,
22832312) CompileError!Value {
2284 return try sema.resolveValue(inst) orelse {
2313 assert(reason != null or block.isComptime());
2314 return sema.resolveValue(inst) orelse {
22852315 return sema.failWithNeededComptime(block, src, reason);
22862316 };
22872317}
......@@ -2295,13 +2325,13 @@ fn resolveDefinedValue(
22952325) CompileError!?Value {
22962326 const pt = sema.pt;
22972327 const zcu = pt.zcu;
2298 const val = try sema.resolveValue(air_ref) orelse return null;
2328 const val = sema.resolveValue(air_ref) orelse return null;
22992329 if (val.isUndef(zcu)) return sema.failWithUseOfUndef(block, src, null);
23002330 return val;
23012331}
23022332
23032333/// Like `resolveValue`, but emits an error if the value is not comptime-known or is undefined.
2304fn resolveConstDefinedValue(
2334pub fn resolveConstDefinedValue(
23052335 sema: *Sema,
23062336 block: *Block,
23072337 src: LazySrcLoc,
......@@ -2315,11 +2345,6 @@ fn resolveConstDefinedValue(
23152345 return val;
23162346}
23172347
2318/// Like `resolveValue`, but recursively resolves lazy values before returning.
2319fn resolveValueResolveLazy(sema: *Sema, inst: Air.Inst.Ref) CompileError!?Value {
2320 return try sema.resolveLazyValue((try sema.resolveValue(inst)) orelse return null);
2321}
2322
23232348/// Value Tag may be `undef` or `variable`.
23242349pub fn resolveFinalDeclValue(
23252350 sema: *Sema,
......@@ -2439,13 +2464,14 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non
24392464
24402465fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
24412466 const pt = sema.pt;
2467 const zcu = pt.zcu;
24422468 const msg = msg: {
24432469 const msg = try sema.errMsg(src, "type '{f}' does not support array initialization syntax", .{
24442470 ty.fmt(pt),
24452471 });
24462472 errdefer msg.destroy(sema.gpa);
2447 if (ty.isSlice(pt.zcu)) {
2448 try sema.errNote(src, msg, "inferred array length is specified with an underscore: '[_]{f}'", .{ty.elemType2(pt.zcu).fmt(pt)});
2473 if (ty.isSlice(zcu)) {
2474 try sema.errNote(src, msg, "inferred array length is specified with an underscore: '[_]{f}'", .{ty.childType(zcu).fmt(pt)});
24492475 }
24502476 break :msg msg;
24512477 };
......@@ -2644,7 +2670,7 @@ pub fn fail(
26442670 src: LazySrcLoc,
26452671 comptime format: []const u8,
26462672 args: anytype,
2647) CompileError {
2673) SemaError {
26482674 const err_msg = try sema.errMsg(src, format, args);
26492675 inline for (args) |arg| {
26502676 if (@TypeOf(arg) == Type.Formatter) {
......@@ -2772,7 +2798,7 @@ fn resolveAlign(
27722798 src: LazySrcLoc,
27732799 zir_ref: Zir.Inst.Ref,
27742800) !Alignment {
2775 const air_ref = try sema.resolveInst(zir_ref);
2801 const air_ref = sema.resolveInst(zir_ref);
27762802 return sema.analyzeAsAlign(block, src, air_ref);
27772803}
27782804
......@@ -2784,7 +2810,7 @@ fn resolveInt(
27842810 dest_ty: Type,
27852811 reason: ComptimeReason,
27862812) !u64 {
2787 const air_ref = try sema.resolveInst(zir_ref);
2813 const air_ref = sema.resolveInst(zir_ref);
27882814 return sema.analyzeAsInt(block, src, air_ref, dest_ty, reason);
27892815}
27902816
......@@ -2798,27 +2824,26 @@ fn analyzeAsInt(
27982824) !u64 {
27992825 const coerced = try sema.coerce(block, dest_ty, air_ref, src);
28002826 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);
2801 return try val.toUnsignedIntSema(sema.pt);
2827 return val.toUnsignedInt(sema.pt.zcu);
28022828}
28032829
28042830fn analyzeValueAsCallconv(
28052831 sema: *Sema,
28062832 block: *Block,
28072833 src: LazySrcLoc,
2808 unresolved_val: Value,
2834 val: Value,
28092835) !std.builtin.CallingConvention {
2810 return interpretBuiltinType(sema, block, src, unresolved_val, std.builtin.CallingConvention);
2836 return interpretBuiltinType(sema, block, src, val, std.builtin.CallingConvention);
28112837}
28122838
28132839fn interpretBuiltinType(
28142840 sema: *Sema,
28152841 block: *Block,
28162842 src: LazySrcLoc,
2817 unresolved_val: Value,
2843 val: Value,
28182844 comptime T: type,
28192845) !T {
2820 const resolved_val = try sema.resolveLazyValue(unresolved_val);
2821 return resolved_val.interpret(T, sema.pt) catch |err| switch (err) {
2846 return val.interpret(T, sema.pt) catch |err| switch (err) {
28222847 error.OutOfMemory => |e| return e,
28232848 error.UndefinedValue => return sema.failWithUseOfUndef(block, src, null),
28242849 error.TypeMismatch => @panic("std.builtin is corrupt"),
......@@ -2864,7 +2889,7 @@ fn zirTupleDecl(
28642889 field_ty.* = field_type.toIntern();
28652890 field_init.* = init: {
28662891 if (zir_field_init != .none) {
2867 const uncoerced_field_init = try sema.resolveInst(zir_field_init);
2892 const uncoerced_field_init = sema.resolveInst(zir_field_init);
28682893 const coerced_field_init = try sema.coerce(block, field_type, uncoerced_field_init, init_src);
28692894 const field_init_val = try sema.resolveConstDefinedValue(block, init_src, coerced_field_init, .{ .simple = .tuple_field_default_value });
28702895 if (field_init_val.canMutateComptimeVarState(zcu)) {
......@@ -2913,7 +2938,13 @@ fn validateTupleFieldType(
29132938
29142939/// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`,
29152940/// resolves this into a list of `InternPool.CaptureValue` allocated by `arena`.
2916fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: usize, captures_len: u32) ![]InternPool.CaptureValue {
2941fn getCaptures(
2942 sema: *Sema,
2943 block: *Block,
2944 type_src: LazySrcLoc,
2945 zir_captures: []const Zir.Inst.Capture,
2946 zir_capture_names: []const Zir.NullTerminatedString,
2947) ![]InternPool.CaptureValue {
29172948 const pt = sema.pt;
29182949 const zcu = pt.zcu;
29192950 const comp = zcu.comp;
......@@ -2924,41 +2955,38 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
29242955 const parent_ty: Type = .fromInterned(zcu.namespacePtr(block.namespace).owner_type);
29252956 const parent_captures: InternPool.CaptureValue.Slice = parent_ty.getCaptures(zcu);
29262957
2927 const captures = try sema.arena.alloc(InternPool.CaptureValue, captures_len);
2958 const captures = try sema.arena.alloc(InternPool.CaptureValue, zir_captures.len);
29282959
2929 for (sema.code.extra[extra_index..][0..captures_len], sema.code.extra[extra_index + captures_len ..][0..captures_len], captures) |raw, raw_name, *capture| {
2930 const zir_capture: Zir.Inst.Capture = @bitCast(raw);
2931 const zir_name: Zir.NullTerminatedString = @enumFromInt(raw_name);
2960 for (zir_captures, zir_capture_names, captures) |zir_capture, zir_name, *capture| {
29322961 const zir_name_slice = sema.code.nullTerminatedString(zir_name);
29332962 capture.* = switch (zir_capture.unwrap()) {
29342963 .nested => |parent_idx| parent_captures.get(ip)[parent_idx],
2935 .instruction_load => |ptr_inst| InternPool.CaptureValue.wrap(capture: {
2936 const ptr_ref = try sema.resolveInst(ptr_inst.toRef());
2937 const ptr_val = try sema.resolveValue(ptr_ref) orelse {
2938 break :capture .{ .runtime = sema.typeOf(ptr_ref).childType(zcu).toIntern() };
2964 .instruction_load => |ptr_inst| capture: {
2965 const ptr_ref = sema.resolveInst(ptr_inst.toRef());
2966 const ptr_val = sema.resolveValue(ptr_ref) orelse {
2967 break :capture .wrap(.{ .runtime = sema.typeOf(ptr_ref).childType(zcu).toIntern() });
29392968 };
29402969 // TODO: better source location
2941 const unresolved_loaded_val = try sema.pointerDeref(block, type_src, ptr_val, sema.typeOf(ptr_ref)) orelse {
2942 break :capture .{ .runtime = sema.typeOf(ptr_ref).childType(zcu).toIntern() };
2970 const loaded_val = try sema.pointerDeref(block, type_src, ptr_val, sema.typeOf(ptr_ref)) orelse {
2971 break :capture .wrap(.{ .runtime = sema.typeOf(ptr_ref).childType(zcu).toIntern() });
29432972 };
2944 const loaded_val = try sema.resolveLazyValue(unresolved_loaded_val);
29452973 if (loaded_val.canMutateComptimeVarState(zcu)) {
29462974 const field_name = try ip.getOrPutString(gpa, io, pt.tid, zir_name_slice, .no_embedded_nulls);
29472975 return sema.failWithContainsReferenceToComptimeVar(block, type_src, field_name, "captured value", loaded_val);
29482976 }
2949 break :capture .{ .@"comptime" = loaded_val.toIntern() };
2950 }),
2951 .instruction => |inst| InternPool.CaptureValue.wrap(capture: {
2952 const air_ref = try sema.resolveInst(inst.toRef());
2953 if (try sema.resolveValueResolveLazy(air_ref)) |val| {
2977 break :capture .wrap(.{ .@"comptime" = loaded_val.toIntern() });
2978 },
2979 .instruction => |inst| capture: {
2980 const air_ref = sema.resolveInst(inst.toRef());
2981 if (sema.resolveValue(air_ref)) |val| {
29542982 if (val.canMutateComptimeVarState(zcu)) {
29552983 const field_name = try ip.getOrPutString(gpa, io, pt.tid, zir_name_slice, .no_embedded_nulls);
29562984 return sema.failWithContainsReferenceToComptimeVar(block, type_src, field_name, "captured value", val);
29572985 }
2958 break :capture .{ .@"comptime" = val.toIntern() };
2986 break :capture .wrap(.{ .@"comptime" = val.toIntern() });
29592987 }
2960 break :capture .{ .runtime = sema.typeOf(air_ref).toIntern() };
2961 }),
2988 break :capture .wrap(.{ .runtime = sema.typeOf(air_ref).toIntern() });
2989 },
29622990 .decl_val => |str| capture: {
29632991 const decl_name = try ip.getOrPutString(
29642992 gpa,
......@@ -2968,7 +2996,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
29682996 .no_embedded_nulls,
29692997 );
29702998 const nav = try sema.lookupIdentifier(block, decl_name);
2971 break :capture InternPool.CaptureValue.wrap(.{ .nav_val = nav });
2999 break :capture .wrap(.{ .nav_val = nav });
29723000 },
29733001 .decl_ref => |str| capture: {
29743002 const decl_name = try ip.getOrPutString(
......@@ -2987,952 +3015,335 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
29873015 return captures;
29883016}
29893017
2990fn zirStructDecl(
3018fn zirErrorSetDecl(
29913019 sema: *Sema,
2992 block: *Block,
2993 extended: Zir.Inst.Extended.InstData,
29943020 inst: Zir.Inst.Index,
29953021) CompileError!Air.Inst.Ref {
3022 const tracy = trace(@src());
3023 defer tracy.end();
3024
29963025 const pt = sema.pt;
29973026 const zcu = pt.zcu;
29983027 const comp = zcu.comp;
29993028 const gpa = comp.gpa;
30003029 const io = comp.io;
3001 const ip = &zcu.intern_pool;
3002
3003 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
3004 const extra = sema.code.extraData(Zir.Inst.StructDecl, extended.operand);
30053030
3006 const tracked_inst = try block.trackZir(inst);
3007 const src: LazySrcLoc = .{
3008 .base_node_inst = tracked_inst,
3009 .offset = LazySrcLoc.Offset.nodeOffset(.zero),
3010 };
3031 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
3032 const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index);
30113033
3012 var extra_index = extra.end;
3034 var names: InferredErrorSet.NameMap = .{};
3035 try names.ensureUnusedCapacity(sema.arena, extra.data.fields_len);
30133036
3014 const captures_len = if (small.has_captures_len) blk: {
3015 const captures_len = sema.code.extra[extra_index];
3016 extra_index += 1;
3017 break :blk captures_len;
3018 } else 0;
3019 const fields_len = if (small.has_fields_len) blk: {
3020 const fields_len = sema.code.extra[extra_index];
3021 extra_index += 1;
3022 break :blk fields_len;
3023 } else 0;
3024 const decls_len = if (small.has_decls_len) blk: {
3025 const decls_len = sema.code.extra[extra_index];
3026 extra_index += 1;
3027 break :blk decls_len;
3028 } else 0;
3037 var extra_index: u32 = @intCast(extra.end);
3038 const extra_index_end = extra_index + extra.data.fields_len;
3039 while (extra_index < extra_index_end) : (extra_index += 1) {
3040 const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);
3041 const name = sema.code.nullTerminatedString(name_index);
3042 const name_ip = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, name, .no_embedded_nulls);
3043 _ = try pt.getErrorValue(name_ip);
3044 const result = names.getOrPutAssumeCapacity(name_ip);
3045 assert(!result.found_existing); // verified in AstGen
3046 }
30293047
3030 const captures = try sema.getCaptures(block, src, extra_index, captures_len);
3031 extra_index += captures_len * 2;
3048 return Air.internedToRef((try pt.errorSetFromUnsortedNames(names.keys())).toIntern());
3049}
30323050
3033 if (small.has_backing_int) {
3034 const backing_int_body_len = sema.code.extra[extra_index];
3035 extra_index += 1; // backing_int_body_len
3036 if (backing_int_body_len == 0) {
3037 extra_index += 1; // backing_int_ref
3038 } else {
3039 extra_index += backing_int_body_len; // backing_int_body_inst
3040 }
3041 }
3042
3043 const struct_init: InternPool.StructTypeInit = .{
3044 .layout = small.layout,
3045 .fields_len = fields_len,
3046 .known_non_opv = small.known_non_opv,
3047 .requires_comptime = if (small.known_comptime_only) .yes else .unknown,
3048 .any_comptime_fields = small.any_comptime_fields,
3049 .any_default_inits = small.any_default_inits,
3050 .inits_resolved = false,
3051 .any_aligned_fields = small.any_aligned_fields,
3052 .key = .{ .declared = .{
3053 .zir_index = tracked_inst,
3054 .captures = captures,
3055 } },
3056 };
3057 const wip_ty = switch (try ip.getStructType(gpa, io, pt.tid, struct_init, false)) {
3058 .existing => |ty| {
3059 const new_ty = try pt.ensureTypeUpToDate(ty);
3051fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
3052 const tracy = trace(@src());
3053 defer tracy.end();
30603054
3061 // Make sure we update the namespace if the declaration is re-analyzed, to pick
3062 // up on e.g. changed comptime decls.
3063 try pt.ensureNamespaceUpToDate(Type.fromInterned(new_ty).getNamespaceIndex(zcu));
3055 const pt = sema.pt;
3056 const zcu = pt.zcu;
30643057
3065 try sema.declareDependency(.{ .interned = new_ty });
3066 try sema.addTypeReferenceEntry(src, new_ty);
3067 return Air.internedToRef(new_ty);
3068 },
3069 .wip => |wip| wip,
3070 };
3071 errdefer wip_ty.cancel(ip, pt.tid);
3058 const src = block.nodeOffset(sema.code.instructions.items(.data)[@intFromEnum(inst)].node);
30723059
3073 const type_name = try sema.createTypeName(
3074 block,
3075 small.name_strategy,
3076 "struct",
3077 inst,
3078 wip_ty.index,
3079 );
3080 wip_ty.setName(ip, type_name.name, type_name.nav);
3060 if (block.isComptime() or sema.fn_ret_ty.comptimeOnly(zcu)) {
3061 return sema.analyzeComptimeAlloc(block, src, sema.fn_ret_ty, .none);
3062 }
30813063
3082 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
3083 .parent = block.namespace.toOptional(),
3084 .owner_type = wip_ty.index,
3085 .file_scope = block.getFileScopeIndex(zcu),
3086 .generation = zcu.generation,
3064 const target = zcu.getTarget();
3065 const ptr_type = try pt.ptrType(.{
3066 .child = sema.fn_ret_ty.toIntern(),
3067 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
30873068 });
3088 errdefer pt.destroyNamespace(new_namespace_index);
30893069
3090 if (pt.zcu.comp.config.incremental) {
3091 try pt.addDependency(.wrap(.{ .type = wip_ty.index }), .{ .src_hash = tracked_inst });
3070 if (block.inlining != null) {
3071 // We are inlining a function call; this should be emitted as an alloc, not a ret_ptr.
3072 // TODO when functions gain result location support, the inlining struct in
3073 // Block should contain the return pointer, and we would pass that through here.
3074 return block.addTy(.alloc, ptr_type);
30923075 }
30933076
3094 const decls = sema.code.bodySlice(extra_index, decls_len);
3095 try pt.scanNamespace(new_namespace_index, decls);
3096
3097 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
3098 codegen_type: {
3099 if (zcu.comp.config.use_llvm) break :codegen_type;
3100 if (block.ownerModule().strip) break :codegen_type;
3101 // This job depends on any resolve_type_fully jobs queued up before it.
3102 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
3103 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
3104 }
3105 try sema.declareDependency(.{ .interned = wip_ty.index });
3106 try sema.addTypeReferenceEntry(src, wip_ty.index);
3107 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
3108 return Air.internedToRef(wip_ty.finish(ip, new_namespace_index));
3077 return block.addTy(.ret_ptr, ptr_type);
31093078}
31103079
3111pub fn createTypeName(
3112 sema: *Sema,
3113 block: *Block,
3114 name_strategy: Zir.Inst.NameStrategy,
3115 anon_prefix: []const u8,
3116 inst: ?Zir.Inst.Index,
3117 /// This is used purely to give the type a unique name in the `anon` case.
3118 type_index: InternPool.Index,
3119) CompileError!struct {
3120 name: InternPool.NullTerminatedString,
3121 nav: InternPool.Nav.Index.Optional,
3122} {
3123 const pt = sema.pt;
3124 const zcu = pt.zcu;
3125 const comp = zcu.comp;
3126 const gpa = comp.gpa;
3127 const io = comp.io;
3128 const ip = &zcu.intern_pool;
3129
3130 switch (name_strategy) {
3131 .anon => {}, // handled after switch
3132 .parent => return .{
3133 .name = block.type_name_ctx,
3134 .nav = sema.owner.unwrap().nav_val.toOptional(),
3135 },
3136 .func => func_strat: {
3137 const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip) orelse return error.AnalysisFail);
3138 const zir_tags = sema.code.instructions.items(.tag);
3080fn zirRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
3081 const tracy = trace(@src());
3082 defer tracy.end();
31393083
3140 var aw: std.Io.Writer.Allocating = .init(gpa);
3141 defer aw.deinit();
3142 const w = &aw.writer;
3143 w.print("{f}(", .{block.type_name_ctx.fmt(ip)}) catch return error.OutOfMemory;
3084 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok;
3085 const operand = sema.resolveInst(inst_data.operand);
3086 return sema.analyzeRef(block, block.tokenOffset(inst_data.src_tok), operand, .none);
3087}
31443088
3145 var arg_i: usize = 0;
3146 for (fn_info.param_body) |zir_inst| switch (zir_tags[@intFromEnum(zir_inst)]) {
3147 .param, .param_comptime, .param_anytype, .param_anytype_comptime => {
3148 const arg = sema.inst_map.get(zir_inst).?;
3149 // If this is being called in a generic function then analyzeCall will
3150 // have already resolved the args and this will work.
3151 // If not then this is a struct type being returned from a non-generic
3152 // function and the name doesn't matter since it will later
3153 // result in a compile error.
3154 const arg_val = try sema.resolveValue(arg) orelse break :func_strat; // fall through to anon strat
3089fn zirEnsureResultUsed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
3090 const tracy = trace(@src());
3091 defer tracy.end();
31553092
3156 if (arg_i != 0) w.writeByte(',') catch return error.OutOfMemory;
3093 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3094 const operand = sema.resolveInst(inst_data.operand);
3095 const src = block.nodeOffset(inst_data.src_node);
31573096
3158 // Limiting the depth here helps avoid type names getting too long, which
3159 // in turn helps to avoid unreasonably long symbol names for namespaced
3160 // symbols. Such names should ideally be human-readable, and additionally,
3161 // some tooling may not support very long symbol names.
3162 w.print("{f}", .{Value.fmtValueSemaFull(.{
3163 .val = arg_val,
3164 .pt = pt,
3165 .opt_sema = sema,
3166 .depth = 1,
3167 })}) catch return error.OutOfMemory;
3097 return sema.ensureResultUsed(block, sema.typeOf(operand), src);
3098}
31683099
3169 arg_i += 1;
3170 continue;
3171 },
3172 else => continue,
3100fn ensureResultUsed(
3101 sema: *Sema,
3102 block: *Block,
3103 ty: Type,
3104 src: LazySrcLoc,
3105) CompileError!void {
3106 const pt = sema.pt;
3107 const zcu = pt.zcu;
3108 switch (ty.zigTypeTag(zcu)) {
3109 .void, .noreturn => return,
3110 .error_set => return sema.fail(block, src, "error set is ignored", .{}),
3111 .error_union => {
3112 const msg = msg: {
3113 const msg = try sema.errMsg(src, "error union is ignored", .{});
3114 errdefer msg.destroy(sema.gpa);
3115 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
3116 break :msg msg;
31733117 };
3174
3175 w.writeByte(')') catch return error.OutOfMemory;
3176 return .{
3177 .name = try ip.getOrPutString(gpa, io, pt.tid, aw.written(), .no_embedded_nulls),
3178 .nav = .none,
3118 return sema.failWithOwnedErrorMsg(block, msg);
3119 },
3120 else => {
3121 const msg = msg: {
3122 const msg = try sema.errMsg(src, "value of type '{f}' ignored", .{ty.fmt(pt)});
3123 errdefer msg.destroy(sema.gpa);
3124 try sema.errNote(src, msg, "all non-void values must be used", .{});
3125 try sema.errNote(src, msg, "to discard the value, assign it to '_'", .{});
3126 break :msg msg;
31793127 };
3128 return sema.failWithOwnedErrorMsg(block, msg);
31803129 },
3181 .dbg_var => {
3182 // TODO: this logic is questionable. We ideally should be traversing the `Block` rather than relying on the order of AstGen instructions.
3183 const ref = inst.?.toRef();
3184 const zir_tags = sema.code.instructions.items(.tag);
3185 const zir_data = sema.code.instructions.items(.data);
3186 for (@intFromEnum(inst.?)..zir_tags.len) |i| switch (zir_tags[i]) {
3187 .dbg_var_ptr, .dbg_var_val => if (zir_data[i].str_op.operand == ref) {
3188 return .{
3189 .name = try ip.getOrPutStringFmt(gpa, io, pt.tid, "{f}.{s}", .{
3190 block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),
3191 }, .no_embedded_nulls),
3192 .nav = .none,
3193 };
3194 },
3195 else => {},
3130 }
3131}
3132
3133fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
3134 const tracy = trace(@src());
3135 defer tracy.end();
3136
3137 const pt = sema.pt;
3138 const zcu = pt.zcu;
3139 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3140 const operand = sema.resolveInst(inst_data.operand);
3141 const src = block.nodeOffset(inst_data.src_node);
3142 const operand_ty = sema.typeOf(operand);
3143 switch (operand_ty.zigTypeTag(zcu)) {
3144 .error_set => return sema.fail(block, src, "error set is discarded", .{}),
3145 .error_union => {
3146 const msg = msg: {
3147 const msg = try sema.errMsg(src, "error union is discarded", .{});
3148 errdefer msg.destroy(sema.gpa);
3149 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
3150 break :msg msg;
31963151 };
3197 // fall through to anon strat
3152 return sema.failWithOwnedErrorMsg(block, msg);
31983153 },
3154 else => return,
3155 }
3156}
3157
3158fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
3159 const tracy = trace(@src());
3160 defer tracy.end();
3161
3162 const pt = sema.pt;
3163 const zcu = pt.zcu;
3164 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3165 const src = block.nodeOffset(inst_data.src_node);
3166 const operand = sema.resolveInst(inst_data.operand);
3167 const operand_ty = sema.typeOf(operand);
3168 const err_union_ty = if (operand_ty.zigTypeTag(zcu) == .pointer)
3169 operand_ty.childType(zcu)
3170 else
3171 operand_ty;
3172 if (err_union_ty.zigTypeTag(zcu) != .error_union) return;
3173 const payload_ty = err_union_ty.errorUnionPayload(zcu).zigTypeTag(zcu);
3174 if (payload_ty != .void and payload_ty != .noreturn) {
3175 const msg = msg: {
3176 const msg = try sema.errMsg(src, "error union payload is ignored", .{});
3177 errdefer msg.destroy(sema.gpa);
3178 try sema.errNote(src, msg, "payload value can be explicitly ignored with '|_|'", .{});
3179 break :msg msg;
3180 };
3181 return sema.failWithOwnedErrorMsg(block, msg);
31993182 }
3183}
32003184
3201 // anon strat handling
3185fn zirIndexablePtrLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
3186 const tracy = trace(@src());
3187 defer tracy.end();
32023188
3203 // It would be neat to have "struct:line:column" but this name has
3204 // to survive incremental updates, where it may have been shifted down
3205 // or up to a different line, but unchanged, and thus not unnecessarily
3206 // semantically analyzed.
3207 // TODO: that would be possible, by detecting line number changes and renaming
3208 // types appropriately. However, `@typeName` becomes a problem then. If we remove
3209 // that builtin from the language, we can consider this.
3189 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3190 const src = block.nodeOffset(inst_data.src_node);
3191 const object = sema.resolveInst(inst_data.operand);
32103192
3211 return .{
3212 .name = try ip.getOrPutStringFmt(gpa, io, pt.tid, "{f}__{s}_{d}", .{
3213 block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(type_index),
3214 }, .no_embedded_nulls),
3215 .nav = .none,
3216 };
3193 return indexablePtrLen(sema, block, src, object);
32173194}
32183195
3219fn zirEnumDecl(
3196fn indexablePtrLen(
32203197 sema: *Sema,
32213198 block: *Block,
3222 extended: Zir.Inst.Extended.InstData,
3223 inst: Zir.Inst.Index,
3199 src: LazySrcLoc,
3200 object: Air.Inst.Ref,
32243201) CompileError!Air.Inst.Ref {
3225 const tracy = trace(@src());
3226 defer tracy.end();
3227
32283202 const pt = sema.pt;
32293203 const zcu = pt.zcu;
32303204 const comp = zcu.comp;
32313205 const gpa = comp.gpa;
32323206 const io = comp.io;
3233 const ip = &zcu.intern_pool;
3234
3235 const small: Zir.Inst.EnumDecl.Small = @bitCast(extended.small);
3236 const extra = sema.code.extraData(Zir.Inst.EnumDecl, extended.operand);
3237 var extra_index: usize = extra.end;
3238
3239 const tracked_inst = try block.trackZir(inst);
3240 const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(.zero) };
3241
3242 const tag_type_ref = if (small.has_tag_type) blk: {
3243 const tag_type_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
3244 extra_index += 1;
3245 break :blk tag_type_ref;
3246 } else .none;
3247
3248 const captures_len = if (small.has_captures_len) blk: {
3249 const captures_len = sema.code.extra[extra_index];
3250 extra_index += 1;
3251 break :blk captures_len;
3252 } else 0;
3253
3254 const body_len = if (small.has_body_len) blk: {
3255 const body_len = sema.code.extra[extra_index];
3256 extra_index += 1;
3257 break :blk body_len;
3258 } else 0;
3259
3260 const fields_len = if (small.has_fields_len) blk: {
3261 const fields_len = sema.code.extra[extra_index];
3262 extra_index += 1;
3263 break :blk fields_len;
3264 } else 0;
3265
3266 const decls_len = if (small.has_decls_len) blk: {
3267 const decls_len = sema.code.extra[extra_index];
3268 extra_index += 1;
3269 break :blk decls_len;
3270 } else 0;
3271
3272 const captures = try sema.getCaptures(block, src, extra_index, captures_len);
3273 extra_index += captures_len * 2;
3274
3275 const decls = sema.code.bodySlice(extra_index, decls_len);
3276 extra_index += decls_len;
3277
3278 const body = sema.code.bodySlice(extra_index, body_len);
3279 extra_index += body.len;
3280
3281 const bit_bags_count = std.math.divCeil(usize, fields_len, 32) catch unreachable;
3282 const body_end = extra_index;
3283 extra_index += bit_bags_count;
3284
3285 const any_values = for (sema.code.extra[body_end..][0..bit_bags_count]) |bag| {
3286 if (bag != 0) break true;
3287 } else false;
3288
3289 const enum_init: InternPool.EnumTypeInit = .{
3290 .has_values = any_values,
3291 .tag_mode = if (small.nonexhaustive)
3292 .nonexhaustive
3293 else if (tag_type_ref == .none)
3294 .auto
3295 else
3296 .explicit,
3297 .fields_len = fields_len,
3298 .key = .{ .declared = .{
3299 .zir_index = tracked_inst,
3300 .captures = captures,
3301 } },
3302 };
3303 const wip_ty = switch (try ip.getEnumType(gpa, io, pt.tid, enum_init, false)) {
3304 .existing => |ty| {
3305 const new_ty = try pt.ensureTypeUpToDate(ty);
3306
3307 // Make sure we update the namespace if the declaration is re-analyzed, to pick
3308 // up on e.g. changed comptime decls.
3309 try pt.ensureNamespaceUpToDate(Type.fromInterned(new_ty).getNamespaceIndex(zcu));
3310
3311 try sema.declareDependency(.{ .interned = new_ty });
3312 try sema.addTypeReferenceEntry(src, new_ty);
3313
3314 // Since this is an enum, it has to be resolved immediately.
3315 // `ensureTypeUpToDate` has resolved the new type if necessary.
3316 // We just need to check for resolution failures.
3317 const ty_unit: AnalUnit = .wrap(.{ .type = new_ty });
3318 if (zcu.failed_analysis.contains(ty_unit) or zcu.transitive_failed_analysis.contains(ty_unit)) {
3319 return error.AnalysisFail;
3320 }
3321
3322 return Air.internedToRef(new_ty);
3323 },
3324 .wip => |wip| wip,
3325 };
3326
3327 // Once this is `true`, we will not delete the decl or type even upon failure, since we
3328 // have finished constructing the type and are in the process of analyzing it.
3329 var done = false;
3330
3331 errdefer if (!done) wip_ty.cancel(ip, pt.tid);
3332
3333 const type_name = try sema.createTypeName(
3334 block,
3335 small.name_strategy,
3336 "enum",
3337 inst,
3338 wip_ty.index,
3339 );
3340 wip_ty.setName(ip, type_name.name, type_name.nav);
3341
3342 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
3343 .parent = block.namespace.toOptional(),
3344 .owner_type = wip_ty.index,
3345 .file_scope = block.getFileScopeIndex(zcu),
3346 .generation = zcu.generation,
3347 });
3348 errdefer if (!done) pt.destroyNamespace(new_namespace_index);
3349
3350 try pt.scanNamespace(new_namespace_index, decls);
3351
3352 try sema.declareDependency(.{ .interned = wip_ty.index });
3353 try sema.addTypeReferenceEntry(src, wip_ty.index);
3354
3355 // We've finished the initial construction of this type, and are about to perform analysis.
3356 // Set the namespace appropriately, and don't destroy anything on failure.
3357 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
3358 wip_ty.prepare(ip, new_namespace_index);
3359 done = true;
3360
3361 {
3362 const tracked_unit = zcu.trackUnitSema(type_name.name.toSlice(ip), null);
3363 defer tracked_unit.end(zcu);
3364 try Sema.resolveDeclaredEnum(
3365 pt,
3366 wip_ty,
3367 inst,
3368 tracked_inst,
3369 new_namespace_index,
3370 type_name.name,
3371 small,
3372 body,
3373 tag_type_ref,
3374 any_values,
3375 fields_len,
3376 sema.code,
3377 body_end,
3378 );
3379 }
3380
3381 codegen_type: {
3382 if (zcu.comp.config.use_llvm) break :codegen_type;
3383 if (block.ownerModule().strip) break :codegen_type;
3384 // This job depends on any resolve_type_fully jobs queued up before it.
3385 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
3386 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
3387 }
3388 return Air.internedToRef(wip_ty.index);
3207 const object_ty = sema.typeOf(object);
3208 const is_pointer_to = object_ty.isSinglePointer(zcu);
3209 const indexable_ty = if (is_pointer_to) object_ty.childType(zcu) else object_ty;
3210 try sema.checkIndexable(block, src, indexable_ty);
3211 const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "len", .no_embedded_nulls);
3212 return sema.fieldVal(block, src, object, field_name, src);
33893213}
33903214
3391fn zirUnionDecl(
3215fn indexablePtrLenOrNone(
33923216 sema: *Sema,
33933217 block: *Block,
3394 extended: Zir.Inst.Extended.InstData,
3395 inst: Zir.Inst.Index,
3218 src: LazySrcLoc,
3219 operand: Air.Inst.Ref,
33963220) CompileError!Air.Inst.Ref {
3397 const tracy = trace(@src());
3398 defer tracy.end();
3399
34003221 const pt = sema.pt;
34013222 const zcu = pt.zcu;
34023223 const comp = zcu.comp;
34033224 const gpa = comp.gpa;
34043225 const io = comp.io;
3405 const ip = &zcu.intern_pool;
3406
3407 const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small);
3408 const extra = sema.code.extraData(Zir.Inst.UnionDecl, extended.operand);
3409 var extra_index: usize = extra.end;
3410
3411 const tracked_inst = try block.trackZir(inst);
3412 const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(.zero) };
3413
3414 extra_index += @intFromBool(small.has_tag_type);
3415 const captures_len = if (small.has_captures_len) blk: {
3416 const captures_len = sema.code.extra[extra_index];
3417 extra_index += 1;
3418 break :blk captures_len;
3419 } else 0;
3420 extra_index += @intFromBool(small.has_body_len);
3421 const fields_len = if (small.has_fields_len) blk: {
3422 const fields_len = sema.code.extra[extra_index];
3423 extra_index += 1;
3424 break :blk fields_len;
3425 } else 0;
3426
3427 const decls_len = if (small.has_decls_len) blk: {
3428 const decls_len = sema.code.extra[extra_index];
3429 extra_index += 1;
3430 break :blk decls_len;
3431 } else 0;
3432
3433 const captures = try sema.getCaptures(block, src, extra_index, captures_len);
3434 extra_index += captures_len * 2;
3435
3436 const union_init: InternPool.UnionTypeInit = .{
3437 .flags = .{
3438 .layout = small.layout,
3439 .status = .none,
3440 .runtime_tag = if (small.has_tag_type or small.auto_enum_tag)
3441 .tagged
3442 else if (small.layout != .auto)
3443 .none
3444 else switch (block.wantSafeTypes()) {
3445 true => .safety,
3446 false => .none,
3447 },
3448 .any_aligned_fields = small.any_aligned_fields,
3449 .requires_comptime = .unknown,
3450 .assumed_runtime_bits = false,
3451 .assumed_pointer_aligned = false,
3452 .alignment = .none,
3453 },
3454 .fields_len = fields_len,
3455 .enum_tag_ty = .none, // set later
3456 .field_types = &.{}, // set later
3457 .field_aligns = &.{}, // set later
3458 .key = .{ .declared = .{
3459 .zir_index = tracked_inst,
3460 .captures = captures,
3461 } },
3462 };
3463 const wip_ty = switch (try ip.getUnionType(gpa, io, pt.tid, union_init, false)) {
3464 .existing => |ty| {
3465 const new_ty = try pt.ensureTypeUpToDate(ty);
3466
3467 // Make sure we update the namespace if the declaration is re-analyzed, to pick
3468 // up on e.g. changed comptime decls.
3469 try pt.ensureNamespaceUpToDate(Type.fromInterned(new_ty).getNamespaceIndex(zcu));
3470
3471 try sema.declareDependency(.{ .interned = new_ty });
3472 try sema.addTypeReferenceEntry(src, new_ty);
3473 return Air.internedToRef(new_ty);
3474 },
3475 .wip => |wip| wip,
3476 };
3477 errdefer wip_ty.cancel(ip, pt.tid);
3478
3479 const type_name = try sema.createTypeName(
3480 block,
3481 small.name_strategy,
3482 "union",
3483 inst,
3484 wip_ty.index,
3485 );
3486 wip_ty.setName(ip, type_name.name, type_name.nav);
3487
3488 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
3489 .parent = block.namespace.toOptional(),
3490 .owner_type = wip_ty.index,
3491 .file_scope = block.getFileScopeIndex(zcu),
3492 .generation = zcu.generation,
3493 });
3494 errdefer pt.destroyNamespace(new_namespace_index);
3495
3496 if (pt.zcu.comp.config.incremental) {
3497 try pt.addDependency(.wrap(.{ .type = wip_ty.index }), .{ .src_hash = tracked_inst });
3498 }
3499
3500 const decls = sema.code.bodySlice(extra_index, decls_len);
3501 try pt.scanNamespace(new_namespace_index, decls);
3502
3503 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
3504 codegen_type: {
3505 if (zcu.comp.config.use_llvm) break :codegen_type;
3506 if (block.ownerModule().strip) break :codegen_type;
3507 // This job depends on any resolve_type_fully jobs queued up before it.
3508 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
3509 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
3226 const operand_ty = sema.typeOf(operand);
3227 try checkMemOperand(sema, block, src, operand_ty);
3228 switch (operand_ty.ptrSize(zcu)) {
3229 .many, .c => return .none,
3230 .one, .slice => {},
35103231 }
3511 try sema.declareDependency(.{ .interned = wip_ty.index });
3512 try sema.addTypeReferenceEntry(src, wip_ty.index);
3513 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
3514 return Air.internedToRef(wip_ty.finish(ip, new_namespace_index));
3232 const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "len", .no_embedded_nulls);
3233 return sema.fieldVal(block, src, operand, field_name, src);
35153234}
35163235
3517fn zirOpaqueDecl(
3236fn zirAllocExtended(
35183237 sema: *Sema,
35193238 block: *Block,
35203239 extended: Zir.Inst.Extended.InstData,
3521 inst: Zir.Inst.Index,
35223240) CompileError!Air.Inst.Ref {
3523 const tracy = trace(@src());
3524 defer tracy.end();
3525
35263241 const pt = sema.pt;
35273242 const zcu = pt.zcu;
3528 const comp = zcu.comp;
3529 const gpa = comp.gpa;
3530 const io = comp.io;
3531 const ip = &zcu.intern_pool;
3243 const gpa = sema.gpa;
3244 const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand);
3245 const var_src = block.nodeOffset(extra.data.src_node);
3246 const ty_src = block.src(.{ .node_offset_var_decl_ty = extra.data.src_node });
3247 const align_src = block.src(.{ .node_offset_var_decl_align = extra.data.src_node });
3248 const small: Zir.Inst.AllocExtended.Small = @bitCast(extended.small);
35323249
3533 const small: Zir.Inst.OpaqueDecl.Small = @bitCast(extended.small);
3534 const extra = sema.code.extraData(Zir.Inst.OpaqueDecl, extended.operand);
35353250 var extra_index: usize = extra.end;
35363251
3537 const tracked_inst = try block.trackZir(inst);
3538 const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(.zero) };
3539
3540 const captures_len = if (small.has_captures_len) blk: {
3541 const captures_len = sema.code.extra[extra_index];
3252 const var_ty: Type = if (small.has_type) blk: {
3253 const type_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
35423254 extra_index += 1;
3543 break :blk captures_len;
3544 } else 0;
3255 break :blk try sema.resolveType(block, ty_src, type_ref);
3256 } else undefined;
35453257
3546 const decls_len = if (small.has_decls_len) blk: {
3547 const decls_len = sema.code.extra[extra_index];
3258 const alignment = if (small.has_align) blk: {
3259 const align_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
35483260 extra_index += 1;
3549 break :blk decls_len;
3550 } else 0;
3551
3552 const captures = try sema.getCaptures(block, src, extra_index, captures_len);
3553 extra_index += captures_len * 2;
3554
3555 const opaque_init: InternPool.OpaqueTypeInit = .{
3556 .zir_index = tracked_inst,
3557 .captures = captures,
3558 };
3559 const wip_ty = switch (try ip.getOpaqueType(gpa, io, pt.tid, opaque_init)) {
3560 .existing => |ty| {
3561 // Make sure we update the namespace if the declaration is re-analyzed, to pick
3562 // up on e.g. changed comptime decls.
3563 try pt.ensureNamespaceUpToDate(Type.fromInterned(ty).getNamespaceIndex(zcu));
3261 break :blk try sema.resolveAlign(block, align_src, align_ref);
3262 } else .none;
35643263
3565 try sema.declareDependency(.{ .interned = ty });
3566 try sema.addTypeReferenceEntry(src, ty);
3567 return Air.internedToRef(ty);
3568 },
3569 .wip => |wip| wip,
3570 };
3571 errdefer wip_ty.cancel(ip, pt.tid);
3264 if (small.has_type) {
3265 try sema.ensureLayoutResolved(var_ty, var_src, if (small.is_const) .constant else .variable);
3266 if (block.isComptime() or small.is_comptime or var_ty.comptimeOnly(zcu)) {
3267 return sema.analyzeComptimeAlloc(block, var_src, var_ty, alignment);
3268 }
3269 if (!small.is_const) {
3270 try sema.validateVarType(block, ty_src, var_ty, false);
3271 }
3272 const target = pt.zcu.getTarget();
3273 if (sema.func_is_naked and var_ty.hasRuntimeBits(zcu)) {
3274 const store_src = block.src(.{ .node_offset_store_ptr = extra.data.src_node });
3275 return sema.fail(block, store_src, "local variable in naked function", .{});
3276 }
3277 const ptr_type = try pt.ptrType(.{
3278 .child = var_ty.toIntern(),
3279 .flags = .{
3280 .alignment = alignment,
3281 .address_space = target_util.defaultAddressSpace(target, .local),
3282 },
3283 });
3284 const ptr = try block.addTy(.alloc, ptr_type);
3285 if (small.is_const) {
3286 const ptr_inst = ptr.toIndex().?;
3287 try sema.maybe_comptime_allocs.put(gpa, ptr_inst, .{ .runtime_index = block.runtime_index });
3288 try sema.base_allocs.put(gpa, ptr_inst, ptr_inst);
3289 }
3290 return ptr;
3291 }
35723292
3573 const type_name = try sema.createTypeName(
3574 block,
3575 small.name_strategy,
3576 "opaque",
3577 inst,
3578 wip_ty.index,
3579 );
3580 wip_ty.setName(ip, type_name.name, type_name.nav);
3293 if (block.isComptime() or small.is_comptime) {
3294 const iac_index: Air.Inst.Index = @enumFromInt(sema.air_instructions.len);
3295 try sema.air_instructions.append(gpa, .{
3296 .tag = .inferred_alloc_comptime,
3297 .data = .{ .inferred_alloc_comptime = .{
3298 .alignment = alignment,
3299 .is_const = small.is_const,
3300 .ptr = undefined,
3301 } },
3302 });
3303 return iac_index.toRef();
3304 }
35813305
3582 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
3583 .parent = block.namespace.toOptional(),
3584 .owner_type = wip_ty.index,
3585 .file_scope = block.getFileScopeIndex(zcu),
3586 .generation = zcu.generation,
3306 const result_index = try block.addInstAsIndex(.{
3307 .tag = .inferred_alloc,
3308 .data = .{ .inferred_alloc = .{
3309 .alignment = alignment,
3310 .is_const = small.is_const,
3311 } },
35873312 });
3588 errdefer pt.destroyNamespace(new_namespace_index);
3589
3590 const decls = sema.code.bodySlice(extra_index, decls_len);
3591 try pt.scanNamespace(new_namespace_index, decls);
3592
3593 codegen_type: {
3594 if (zcu.comp.config.use_llvm) break :codegen_type;
3595 if (block.ownerModule().strip) break :codegen_type;
3596 // This job depends on any resolve_type_fully jobs queued up before it.
3597 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
3598 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
3313 try sema.unresolved_inferred_allocs.putNoClobber(gpa, result_index, .{});
3314 if (small.is_const) {
3315 try sema.maybe_comptime_allocs.put(gpa, result_index, .{ .runtime_index = block.runtime_index });
3316 try sema.base_allocs.put(gpa, result_index, result_index);
35993317 }
3600 try sema.addTypeReferenceEntry(src, wip_ty.index);
3601 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
3602 return Air.internedToRef(wip_ty.finish(ip, new_namespace_index));
3318 return result_index.toRef();
36033319}
36043320
3605fn zirErrorSetDecl(
3606 sema: *Sema,
3607 inst: Zir.Inst.Index,
3608) CompileError!Air.Inst.Ref {
3321fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
36093322 const tracy = trace(@src());
36103323 defer tracy.end();
36113324
3612 const pt = sema.pt;
3613 const zcu = pt.zcu;
3614 const comp = zcu.comp;
3615 const gpa = comp.gpa;
3616 const io = comp.io;
3617
3618 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
3619 const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index);
3620
3621 var names: InferredErrorSet.NameMap = .{};
3622 try names.ensureUnusedCapacity(sema.arena, extra.data.fields_len);
3623
3624 var extra_index: u32 = @intCast(extra.end);
3625 const extra_index_end = extra_index + extra.data.fields_len;
3626 while (extra_index < extra_index_end) : (extra_index += 1) {
3627 const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);
3628 const name = sema.code.nullTerminatedString(name_index);
3629 const name_ip = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, name, .no_embedded_nulls);
3630 _ = try pt.getErrorValue(name_ip);
3631 const result = names.getOrPutAssumeCapacity(name_ip);
3632 assert(!result.found_existing); // verified in AstGen
3633 }
3634
3635 return Air.internedToRef((try pt.errorSetFromUnsortedNames(names.keys())).toIntern());
3325 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3326 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
3327 const var_src = block.nodeOffset(inst_data.src_node);
3328 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
3329 try sema.ensureLayoutResolved(var_ty, var_src, .variable);
3330 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);
36363331}
36373332
3638fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
3639 const tracy = trace(@src());
3640 defer tracy.end();
3641
3333fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
36423334 const pt = sema.pt;
3335 const zcu = pt.zcu;
3336 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3337 const alloc = sema.resolveInst(inst_data.operand);
3338 const alloc_ty = sema.typeOf(alloc);
3339 const ptr_info = alloc_ty.ptrInfo(zcu);
3340 const elem_ty: Type = .fromInterned(ptr_info.child);
36433341
3644 const src = block.nodeOffset(sema.code.instructions.items(.data)[@intFromEnum(inst)].node);
3645
3646 if (block.isComptime() or try sema.fn_ret_ty.comptimeOnlySema(pt)) {
3647 try sema.fn_ret_ty.resolveFields(pt);
3648 return sema.analyzeComptimeAlloc(block, src, sema.fn_ret_ty, .none);
3649 }
3650
3651 const target = pt.zcu.getTarget();
3652 const ptr_type = try pt.ptrTypeSema(.{
3653 .child = sema.fn_ret_ty.toIntern(),
3654 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
3655 });
3656
3657 if (block.inlining != null) {
3658 // We are inlining a function call; this should be emitted as an alloc, not a ret_ptr.
3659 // TODO when functions gain result location support, the inlining struct in
3660 // Block should contain the return pointer, and we would pass that through here.
3661 return block.addTy(.alloc, ptr_type);
3662 }
3663
3664 return block.addTy(.ret_ptr, ptr_type);
3665}
3666
3667fn zirRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
3668 const tracy = trace(@src());
3669 defer tracy.end();
3670
3671 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_tok;
3672 const operand = try sema.resolveInst(inst_data.operand);
3673 return sema.analyzeRef(block, block.tokenOffset(inst_data.src_tok), operand);
3674}
3675
3676fn zirEnsureResultUsed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
3677 const tracy = trace(@src());
3678 defer tracy.end();
3679
3680 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3681 const operand = try sema.resolveInst(inst_data.operand);
3682 const src = block.nodeOffset(inst_data.src_node);
3683
3684 return sema.ensureResultUsed(block, sema.typeOf(operand), src);
3685}
3686
3687fn ensureResultUsed(
3688 sema: *Sema,
3689 block: *Block,
3690 ty: Type,
3691 src: LazySrcLoc,
3692) CompileError!void {
3693 const pt = sema.pt;
3694 const zcu = pt.zcu;
3695 switch (ty.zigTypeTag(zcu)) {
3696 .void, .noreturn => return,
3697 .error_set => return sema.fail(block, src, "error set is ignored", .{}),
3698 .error_union => {
3699 const msg = msg: {
3700 const msg = try sema.errMsg(src, "error union is ignored", .{});
3701 errdefer msg.destroy(sema.gpa);
3702 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
3703 break :msg msg;
3704 };
3705 return sema.failWithOwnedErrorMsg(block, msg);
3706 },
3707 else => {
3708 const msg = msg: {
3709 const msg = try sema.errMsg(src, "value of type '{f}' ignored", .{ty.fmt(pt)});
3710 errdefer msg.destroy(sema.gpa);
3711 try sema.errNote(src, msg, "all non-void values must be used", .{});
3712 try sema.errNote(src, msg, "to discard the value, assign it to '_'", .{});
3713 break :msg msg;
3714 };
3715 return sema.failWithOwnedErrorMsg(block, msg);
3716 },
3717 }
3718}
3719
3720fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
3721 const tracy = trace(@src());
3722 defer tracy.end();
3723
3724 const pt = sema.pt;
3725 const zcu = pt.zcu;
3726 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3727 const operand = try sema.resolveInst(inst_data.operand);
3728 const src = block.nodeOffset(inst_data.src_node);
3729 const operand_ty = sema.typeOf(operand);
3730 switch (operand_ty.zigTypeTag(zcu)) {
3731 .error_set => return sema.fail(block, src, "error set is discarded", .{}),
3732 .error_union => {
3733 const msg = msg: {
3734 const msg = try sema.errMsg(src, "error union is discarded", .{});
3735 errdefer msg.destroy(sema.gpa);
3736 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
3737 break :msg msg;
3738 };
3739 return sema.failWithOwnedErrorMsg(block, msg);
3740 },
3741 else => return,
3742 }
3743}
3744
3745fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
3746 const tracy = trace(@src());
3747 defer tracy.end();
3748
3749 const pt = sema.pt;
3750 const zcu = pt.zcu;
3751 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3752 const src = block.nodeOffset(inst_data.src_node);
3753 const operand = try sema.resolveInst(inst_data.operand);
3754 const operand_ty = sema.typeOf(operand);
3755 const err_union_ty = if (operand_ty.zigTypeTag(zcu) == .pointer)
3756 operand_ty.childType(zcu)
3757 else
3758 operand_ty;
3759 if (err_union_ty.zigTypeTag(zcu) != .error_union) return;
3760 const payload_ty = err_union_ty.errorUnionPayload(zcu).zigTypeTag(zcu);
3761 if (payload_ty != .void and payload_ty != .noreturn) {
3762 const msg = msg: {
3763 const msg = try sema.errMsg(src, "error union payload is ignored", .{});
3764 errdefer msg.destroy(sema.gpa);
3765 try sema.errNote(src, msg, "payload value can be explicitly ignored with '|_|'", .{});
3766 break :msg msg;
3767 };
3768 return sema.failWithOwnedErrorMsg(block, msg);
3769 }
3770}
3771
3772fn zirIndexablePtrLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
3773 const tracy = trace(@src());
3774 defer tracy.end();
3775
3776 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3777 const src = block.nodeOffset(inst_data.src_node);
3778 const object = try sema.resolveInst(inst_data.operand);
3779
3780 return indexablePtrLen(sema, block, src, object);
3781}
3782
3783fn indexablePtrLen(
3784 sema: *Sema,
3785 block: *Block,
3786 src: LazySrcLoc,
3787 object: Air.Inst.Ref,
3788) CompileError!Air.Inst.Ref {
3789 const pt = sema.pt;
3790 const zcu = pt.zcu;
3791 const comp = zcu.comp;
3792 const gpa = comp.gpa;
3793 const io = comp.io;
3794 const object_ty = sema.typeOf(object);
3795 const is_pointer_to = object_ty.isSinglePointer(zcu);
3796 const indexable_ty = if (is_pointer_to) object_ty.childType(zcu) else object_ty;
3797 try sema.checkIndexable(block, src, indexable_ty);
3798 const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "len", .no_embedded_nulls);
3799 return sema.fieldVal(block, src, object, field_name, src);
3800}
3801
3802fn indexablePtrLenOrNone(
3803 sema: *Sema,
3804 block: *Block,
3805 src: LazySrcLoc,
3806 operand: Air.Inst.Ref,
3807) CompileError!Air.Inst.Ref {
3808 const pt = sema.pt;
3809 const zcu = pt.zcu;
3810 const comp = zcu.comp;
3811 const gpa = comp.gpa;
3812 const io = comp.io;
3813 const operand_ty = sema.typeOf(operand);
3814 try checkMemOperand(sema, block, src, operand_ty);
3815 switch (operand_ty.ptrSize(zcu)) {
3816 .many, .c => return .none,
3817 .one, .slice => {},
3818 }
3819 const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "len", .no_embedded_nulls);
3820 return sema.fieldVal(block, src, operand, field_name, src);
3821}
3822
3823fn zirAllocExtended(
3824 sema: *Sema,
3825 block: *Block,
3826 extended: Zir.Inst.Extended.InstData,
3827) CompileError!Air.Inst.Ref {
3828 const pt = sema.pt;
3829 const gpa = sema.gpa;
3830 const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand);
3831 const var_src = block.nodeOffset(extra.data.src_node);
3832 const ty_src = block.src(.{ .node_offset_var_decl_ty = extra.data.src_node });
3833 const align_src = block.src(.{ .node_offset_var_decl_align = extra.data.src_node });
3834 const small: Zir.Inst.AllocExtended.Small = @bitCast(extended.small);
3835
3836 var extra_index: usize = extra.end;
3837
3838 const var_ty: Type = if (small.has_type) blk: {
3839 const type_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
3840 extra_index += 1;
3841 break :blk try sema.resolveType(block, ty_src, type_ref);
3842 } else undefined;
3843
3844 const alignment = if (small.has_align) blk: {
3845 const align_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
3846 extra_index += 1;
3847 break :blk try sema.resolveAlign(block, align_src, align_ref);
3848 } else .none;
3849
3850 if (block.isComptime() or small.is_comptime) {
3851 if (small.has_type) {
3852 return sema.analyzeComptimeAlloc(block, var_src, var_ty, alignment);
3853 } else {
3854 try sema.air_instructions.append(gpa, .{
3855 .tag = .inferred_alloc_comptime,
3856 .data = .{ .inferred_alloc_comptime = .{
3857 .alignment = alignment,
3858 .is_const = small.is_const,
3859 .ptr = undefined,
3860 } },
3861 });
3862 return @as(Air.Inst.Index, @enumFromInt(sema.air_instructions.len - 1)).toRef();
3863 }
3864 }
3865
3866 if (small.has_type and try var_ty.comptimeOnlySema(pt)) {
3867 return sema.analyzeComptimeAlloc(block, var_src, var_ty, alignment);
3868 }
3869
3870 if (small.has_type) {
3871 if (!small.is_const) {
3872 try sema.validateVarType(block, ty_src, var_ty, false);
3873 }
3874 const target = pt.zcu.getTarget();
3875 try var_ty.resolveLayout(pt);
3876 if (sema.func_is_naked and try var_ty.hasRuntimeBitsSema(pt)) {
3877 const store_src = block.src(.{ .node_offset_store_ptr = extra.data.src_node });
3878 return sema.fail(block, store_src, "local variable in naked function", .{});
3879 }
3880 const ptr_type = try sema.pt.ptrTypeSema(.{
3881 .child = var_ty.toIntern(),
3882 .flags = .{
3883 .alignment = alignment,
3884 .address_space = target_util.defaultAddressSpace(target, .local),
3885 },
3886 });
3887 const ptr = try block.addTy(.alloc, ptr_type);
3888 if (small.is_const) {
3889 const ptr_inst = ptr.toIndex().?;
3890 try sema.maybe_comptime_allocs.put(gpa, ptr_inst, .{ .runtime_index = block.runtime_index });
3891 try sema.base_allocs.put(gpa, ptr_inst, ptr_inst);
3892 }
3893 return ptr;
3894 }
3895
3896 const result_index = try block.addInstAsIndex(.{
3897 .tag = .inferred_alloc,
3898 .data = .{ .inferred_alloc = .{
3899 .alignment = alignment,
3900 .is_const = small.is_const,
3901 } },
3902 });
3903 try sema.unresolved_inferred_allocs.putNoClobber(gpa, result_index, .{});
3904 if (small.is_const) {
3905 try sema.maybe_comptime_allocs.put(gpa, result_index, .{ .runtime_index = block.runtime_index });
3906 try sema.base_allocs.put(gpa, result_index, result_index);
3907 }
3908 return result_index.toRef();
3909}
3910
3911fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
3912 const tracy = trace(@src());
3913 defer tracy.end();
3914
3915 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3916 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
3917 const var_src = block.nodeOffset(inst_data.src_node);
3918 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
3919 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);
3920}
3921
3922fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
3923 const pt = sema.pt;
3924 const zcu = pt.zcu;
3925 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
3926 const alloc = try sema.resolveInst(inst_data.operand);
3927 const alloc_ty = sema.typeOf(alloc);
3928 const ptr_info = alloc_ty.ptrInfo(zcu);
3929 const elem_ty: Type = .fromInterned(ptr_info.child);
3930
3931 // If the alloc was created in a comptime scope, we already created a comptime alloc for it.
3932 // However, if the final constructed value does not reference comptime-mutable memory, we wish
3933 // to promote it to an anon decl.
3934 already_ct: {
3935 const ptr_val = try sema.resolveValue(alloc) orelse break :already_ct;
3342 // If the alloc was created in a comptime scope, we already created a comptime alloc for it.
3343 // However, if the final constructed value does not reference comptime-mutable memory, we wish
3344 // to promote it to an anon decl.
3345 already_ct: {
3346 const ptr_val = sema.resolveValue(alloc) orelse break :already_ct;
39363347
39373348 // If this was a comptime inferred alloc, then `storeToInferredAllocComptime`
39383349 // might have already done our job and created an anon decl ref.
......@@ -3978,7 +3389,7 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
39783389 return sema.makePtrConst(block, Air.internedToRef(ptr_val));
39793390 }
39803391
3981 if (try elem_ty.comptimeOnlySema(pt)) {
3392 if (elem_ty.comptimeOnly(zcu)) {
39823393 // The value was initialized through RLS, so we didn't detect the runtime condition earlier.
39833394 // TODO: source location of runtime control flow
39843395 const init_src = block.src(.{ .node_offset_var_decl_init = inst_data.src_node });
......@@ -4001,20 +3412,23 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
40013412 const alloc_ty = resolved_alloc_ty orelse sema.typeOf(alloc);
40023413 const ptr_info = alloc_ty.ptrInfo(zcu);
40033414 const elem_ty: Type = .fromInterned(ptr_info.child);
3415 elem_ty.assertHasLayout(zcu);
40043416
40053417 const alloc_inst = alloc.toIndex() orelse return null;
40063418 const comptime_info = sema.maybe_comptime_allocs.fetchRemove(alloc_inst) orelse return null;
40073419 const stores = comptime_info.value.stores.items(.inst);
40083420
3421 // If the elem type is OPV, no need to faff about with `stores`; just use the OPV.
3422 if (try elem_ty.onePossibleValue(pt)) |opv| {
3423 return sema.finishResolveComptimeKnownAllocPtr(block, alloc_ty, opv.toIntern(), null, alloc_inst, comptime_info.value);
3424 }
3425
3426 // Since the elem type isn't OPV, there should have been at least one store.
3427 assert(stores.len > 0);
3428
40093429 // Since the entry existed in `maybe_comptime_allocs`, the allocation is comptime-known.
40103430 // We will resolve and return its value.
40113431
4012 // We expect to have emitted at least one store, unless the elem type is OPV.
4013 if (stores.len == 0) {
4014 const val = (try sema.typeHasOnePossibleValue(elem_ty)).?.toIntern();
4015 return sema.finishResolveComptimeKnownAllocPtr(block, alloc_ty, val, null, alloc_inst, comptime_info.value);
4016 }
4017
40183432 // In general, we want to create a comptime alloc of the correct type and
40193433 // apply the stores to that alloc in order. However, before going to all
40203434 // that effort, let's optimize for the common case of a single store.
......@@ -4115,10 +3529,10 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
41153529 Air.Bin,
41163530 tmp_air.instructions.items(.data)[@intFromEnum(air_ptr)].ty_pl.payload,
41173531 ).data;
4118 const idx_val = (try sema.resolveValue(data.rhs)).?;
3532 const idx_val = sema.resolveValue(data.rhs).?;
41193533 break :blk .{
41203534 data.lhs,
4121 .{ .elem = try idx_val.toUnsignedIntSema(pt) },
3535 .{ .elem = idx_val.toUnsignedInt(zcu) },
41223536 };
41233537 },
41243538 .bitcast => .{
......@@ -4150,7 +3564,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
41503564 // If the payload is OPV, we must use that value instead of undef.
41513565 const opt_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);
41523566 const payload_ty = opt_ty.optionalChild(zcu);
4153 const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try pt.undefValue(payload_ty);
3567 const payload_val = try payload_ty.onePossibleValue(pt) orelse try pt.undefValue(payload_ty);
41543568 const opt_val = try pt.intern(.{ .opt = .{
41553569 .ty = opt_ty.toIntern(),
41563570 .val = payload_val.toIntern(),
......@@ -4163,7 +3577,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
41633577 // If the payload is OPV, we must use that value instead of undef.
41643578 const eu_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);
41653579 const payload_ty = eu_ty.errorUnionPayload(zcu);
4166 const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try pt.undefValue(payload_ty);
3580 const payload_val = try payload_ty.onePossibleValue(pt) orelse try pt.undefValue(payload_ty);
41673581 const eu_val = try pt.intern(.{ .error_union = .{
41683582 .ty = eu_ty.toIntern(),
41693583 .val = .{ .payload = payload_val.toIntern() },
......@@ -4173,18 +3587,31 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
41733587 },
41743588 .field => |idx| ptr: {
41753589 const maybe_union_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);
4176 if (zcu.typeToUnion(maybe_union_ty)) |union_obj| {
3590 if (zcu.typeToUnion(maybe_union_ty)) |union_obj| if (union_obj.layout == .auto) {
41773591 // As this is a union field, we must store to the pointer now to set the tag.
41783592 // The payload value will be stored later, so undef is a sufficent payload for now.
41793593 const payload_ty: Type = .fromInterned(union_obj.field_types.get(&zcu.intern_pool)[idx]);
41803594 const payload_val = try pt.undefValue(payload_ty);
4181 const tag_val = try pt.enumValueFieldIndex(.fromInterned(union_obj.enum_tag_ty), idx);
3595 const tag_val = try pt.enumValueFieldIndex(.fromInterned(union_obj.enum_tag_type), idx);
41823596 const store_val = try pt.unionValue(maybe_union_ty, tag_val, payload_val);
41833597 try sema.storePtrVal(block, .unneeded, .fromInterned(decl_parent_ptr), store_val, maybe_union_ty);
4184 }
3598 };
41853599 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrField(idx, pt)).toIntern();
41863600 },
4187 .elem => |idx| (try Value.fromInterned(decl_parent_ptr).ptrElem(idx, pt)).toIntern(),
3601 .elem => |idx| ptr: {
3602 const parent_ptr_val: Value = .fromInterned(decl_parent_ptr);
3603 if (parent_ptr_val.typeOf(zcu).childType(zcu).zigTypeTag(zcu) == .vector) {
3604 const elem_ptr_ty: Type = .fromInterned(new_ptr_ty);
3605 // Vectors are a bit weird; see logic in `elemPtrVector`.
3606 if (elem_ptr_ty.ptrInfo(zcu).flags.vector_index != .none) {
3607 break :ptr (try pt.getCoerced(parent_ptr_val, elem_ptr_ty)).toIntern();
3608 } else {
3609 const bit_offset = idx * @divExact(elem_ptr_ty.childType(zcu).bitSize(zcu), 8);
3610 break :ptr (try parent_ptr_val.getOffsetPtr(bit_offset, elem_ptr_ty, pt)).toIntern();
3611 }
3612 }
3613 break :ptr (try parent_ptr_val.ptrElem(idx, pt)).toIntern();
3614 },
41883615 };
41893616 try ptr_mapping.put(air_ptr, new_ptr);
41903617 }
......@@ -4207,14 +3634,14 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
42073634 const tag_val: Value = .fromInterned(store_inst.data.bin_op.rhs.toInterned().?);
42083635 const union_ty = union_ptr_val.typeOf(zcu).childType(zcu);
42093636 const field_ty = union_ty.unionFieldType(tag_val, zcu).?;
4210 if (try sema.typeHasOnePossibleValue(field_ty)) |payload_val| {
3637 if (try field_ty.onePossibleValue(pt)) |payload_val| {
42113638 const new_union_val = try pt.unionValue(union_ty, tag_val, payload_val);
42123639 try sema.storePtrVal(block, .unneeded, union_ptr_val, new_union_val, union_ty);
42133640 }
42143641 },
42153642 .store, .store_safe => {
42163643 const air_ptr_inst = store_inst.data.bin_op.lhs.toIndex().?;
4217 const store_val = (try sema.resolveValue(store_inst.data.bin_op.rhs)).?;
3644 const store_val = sema.resolveValue(store_inst.data.bin_op.rhs).?;
42183645 const new_ptr = ptr_mapping.get(air_ptr_inst).?;
42193646 try sema.storePtrVal(block, .unneeded, .fromInterned(new_ptr), store_val, store_val.typeOf(zcu));
42203647 },
......@@ -4289,7 +3716,7 @@ fn finishResolveComptimeKnownAllocPtr(
42893716fn makePtrTyConst(sema: *Sema, ptr_ty: Type) CompileError!Type {
42903717 var ptr_info = ptr_ty.ptrInfo(sema.pt.zcu);
42913718 ptr_info.flags.is_const = true;
4292 return sema.pt.ptrTypeSema(ptr_info);
3719 return sema.pt.ptrType(ptr_info);
42933720}
42943721
42953722fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Air.Inst.Ref {
......@@ -4297,7 +3724,7 @@ fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Ai
42973724 const const_ptr_ty = try sema.makePtrTyConst(alloc_ty);
42983725
42993726 // Detect if a comptime value simply needs to have its type changed.
4300 if (try sema.resolveValue(alloc)) |val| {
3727 if (sema.resolveValue(alloc)) |val| {
43013728 return Air.internedToRef((try sema.pt.getCoerced(val, const_ptr_ty)).toIntern());
43023729 }
43033730
......@@ -4326,21 +3753,23 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
43263753 defer tracy.end();
43273754
43283755 const pt = sema.pt;
3756 const zcu = pt.zcu;
43293757
43303758 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
43313759 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
43323760 const var_src = block.nodeOffset(inst_data.src_node);
43333761
43343762 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
4335 if (block.isComptime() or try var_ty.comptimeOnlySema(pt)) {
3763 try sema.ensureLayoutResolved(var_ty, var_src, .constant);
3764 if (block.isComptime() or var_ty.comptimeOnly(zcu)) {
43363765 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);
43373766 }
4338 if (sema.func_is_naked and try var_ty.hasRuntimeBitsSema(pt)) {
3767 if (sema.func_is_naked and var_ty.hasRuntimeBits(zcu)) {
43393768 const mut_src = block.src(.{ .node_offset_store_ptr = inst_data.src_node });
43403769 return sema.fail(block, mut_src, "local variable in naked function", .{});
43413770 }
4342 const target = pt.zcu.getTarget();
4343 const ptr_type = try pt.ptrTypeSema(.{
3771 const target = zcu.getTarget();
3772 const ptr_type = try pt.ptrType(.{
43443773 .child = var_ty.toIntern(),
43453774 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
43463775 });
......@@ -4356,21 +3785,24 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
43563785 defer tracy.end();
43573786
43583787 const pt = sema.pt;
3788 const zcu = pt.zcu;
43593789
43603790 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
43613791 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
43623792 const var_src = block.nodeOffset(inst_data.src_node);
3793
43633794 const var_ty = try sema.resolveType(block, ty_src, inst_data.operand);
3795 try sema.ensureLayoutResolved(var_ty, var_src, .variable);
43643796 if (block.isComptime()) {
43653797 return sema.analyzeComptimeAlloc(block, var_src, var_ty, .none);
43663798 }
4367 if (sema.func_is_naked and try var_ty.hasRuntimeBitsSema(pt)) {
3799 if (sema.func_is_naked and var_ty.hasRuntimeBits(zcu)) {
43683800 const store_src = block.src(.{ .node_offset_store_ptr = inst_data.src_node });
43693801 return sema.fail(block, store_src, "local variable in naked function", .{});
43703802 }
43713803 try sema.validateVarType(block, ty_src, var_ty, false);
4372 const target = pt.zcu.getTarget();
4373 const ptr_type = try pt.ptrTypeSema(.{
3804 const target = zcu.getTarget();
3805 const ptr_type = try pt.ptrType(.{
43743806 .child = var_ty.toIntern(),
43753807 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
43763808 });
......@@ -4424,14 +3856,15 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
44243856 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
44253857 const src = block.nodeOffset(inst_data.src_node);
44263858 const ty_src = block.src(.{ .node_offset_var_decl_ty = inst_data.src_node });
4427 const ptr = try sema.resolveInst(inst_data.operand);
3859 const ptr = sema.resolveInst(inst_data.operand);
44283860 const ptr_inst = ptr.toIndex().?;
44293861 const target = zcu.getTarget();
44303862
44313863 switch (sema.air_instructions.items(.tag)[@intFromEnum(ptr_inst)]) {
44323864 .inferred_alloc_comptime => {
4433 // The work was already done for us by `Sema.storeToInferredAllocComptime`.
4434 // All we need to do is return the pointer.
3865 // The work was already done for us by `Sema.storeToInferredAllocComptime`. Also, since
3866 // we had a value of the exact correct type to store, the result type's layout must be
3867 // already resolved. So all we need to do here is return the pointer.
44353868 const iac = sema.air_instructions.items(.data)[@intFromEnum(ptr_inst)].inferred_alloc_comptime;
44363869 const resolved_ptr = iac.ptr;
44373870
......@@ -4450,7 +3883,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
44503883 };
44513884 if (zcu.intern_pool.isFuncBody(val)) {
44523885 const ty: Type = .fromInterned(zcu.intern_pool.typeOf(val));
4453 if (try ty.fnHasRuntimeBitsSema(pt)) {
3886 if (ty.fnHasRuntimeBits(zcu)) {
44543887 const orig_fn_index = zcu.intern_pool.unwrapCoercedFunc(val);
44553888 try sema.addReferenceEntry(block, src, .wrap(.{ .func = orig_fn_index }));
44563889 try zcu.ensureFuncBodyAnalysisQueued(orig_fn_index);
......@@ -4469,8 +3902,10 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
44693902 peer_val.* = bin_op.rhs;
44703903 }
44713904 const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_vals, .none);
3905 // The layout of the peers is already resolved, so the layout of `final_elem_ty` is too.
3906 final_elem_ty.assertHasLayout(zcu);
44723907
4473 const final_ptr_ty = try pt.ptrTypeSema(.{
3908 const final_ptr_ty = try pt.ptrType(.{
44743909 .child = final_elem_ty.toIntern(),
44753910 .flags = .{
44763911 .alignment = ia1.alignment,
......@@ -4484,21 +3919,16 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
44843919 const const_ptr_ty = try sema.makePtrTyConst(final_ptr_ty);
44853920 const new_const_ptr = try pt.getCoerced(Value.fromInterned(ptr_val), const_ptr_ty);
44863921
4487 // Unless the block is comptime, `alloc_inferred` always produces
4488 // a runtime constant. The final inferred type needs to be
4489 // fully resolved so it can be lowered in codegen.
4490 try final_elem_ty.resolveFully(pt);
4491
44923922 return Air.internedToRef(new_const_ptr.toIntern());
44933923 }
44943924
4495 if (try final_elem_ty.comptimeOnlySema(pt)) {
3925 if (final_elem_ty.comptimeOnly(zcu)) {
44963926 // The alloc wasn't comptime-known per the above logic, so the
44973927 // type cannot be comptime-only.
44983928 // TODO: source location of runtime control flow
44993929 return sema.fail(block, src, "value with comptime-only type '{f}' depends on runtime control flow", .{final_elem_ty.fmt(pt)});
45003930 }
4501 if (sema.func_is_naked and try final_elem_ty.hasRuntimeBitsSema(pt)) {
3931 if (sema.func_is_naked and final_elem_ty.hasRuntimeBits(zcu)) {
45023932 const mut_src = block.src(.{ .node_offset_store_ptr = inst_data.src_node });
45033933 return sema.fail(block, mut_src, "local variable in naked function", .{});
45043934 }
......@@ -4591,7 +4021,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
45914021
45924022 const arg_len_uncoerced = if (zir_arg_pair[1] == .none) l: {
45934023 // This argument is an indexable.
4594 const object = try sema.resolveInst(zir_arg_pair[0]);
4024 const object = sema.resolveInst(zir_arg_pair[0]);
45954025 const object_ty = sema.typeOf(object);
45964026 if (!object_ty.isIndexable(zcu)) {
45974027 // Instead of using checkIndexable we customize this error.
......@@ -4612,8 +4042,8 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
46124042 break :l try sema.fieldVal(block, arg_src, object, try ip.getOrPutString(gpa, io, pt.tid, "len", .no_embedded_nulls), arg_src);
46134043 } else l: {
46144044 // This argument is a range.
4615 const range_start = try sema.resolveInst(zir_arg_pair[0]);
4616 const range_end = try sema.resolveInst(zir_arg_pair[1]);
4045 const range_start = sema.resolveInst(zir_arg_pair[0]);
4046 const range_end = sema.resolveInst(zir_arg_pair[1]);
46174047 if (try sema.resolveDefinedValue(block, arg_src, range_start)) |start| {
46184048 if (try sema.valuesEqual(start, .zero_usize, .usize)) break :l range_end;
46194049 }
......@@ -4663,7 +4093,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
46634093 const i: u32 = @intCast(i_usize);
46644094 if (zir_arg_pair[0] == .none) continue;
46654095 if (zir_arg_pair[1] != .none) continue;
4666 const object = try sema.resolveInst(zir_arg_pair[0]);
4096 const object = sema.resolveInst(zir_arg_pair[0]);
46674097 const object_ty = sema.typeOf(object);
46684098 const arg_src = block.src(.{ .for_input = .{
46694099 .for_node_offset = inst_data.src_node,
......@@ -4701,9 +4131,11 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
47014131/// or error union pointed to, initializing these pointers along the way.
47024132/// Given a `*E!?T`, returns a (valid) `*T`.
47034133/// May invalidate already-stored payload data.
4134/// Asserts that the layout of the pointer child type is already resolved.
47044135fn optEuBasePtrInit(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, src: LazySrcLoc) CompileError!Air.Inst.Ref {
47054136 const pt = sema.pt;
47064137 const zcu = pt.zcu;
4138 sema.typeOf(ptr).childType(zcu).assertHasLayout(zcu);
47074139 var base_ptr = ptr;
47084140 while (true) switch (sema.typeOf(base_ptr).childType(zcu).zigTypeTag(zcu)) {
47094141 .error_union => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false, true),
......@@ -4716,8 +4148,10 @@ fn optEuBasePtrInit(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, src: LazySrcL
47164148
47174149fn zirOptEuBasePtrInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
47184150 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
4719 const ptr = try sema.resolveInst(un_node.operand);
4720 return sema.optEuBasePtrInit(block, ptr, block.nodeOffset(un_node.src_node));
4151 const ptr = sema.resolveInst(un_node.operand);
4152 const src = block.nodeOffset(un_node.src_node);
4153 try sema.ensureLayoutResolved(sema.typeOf(ptr).childType(sema.pt.zcu), src, .init);
4154 return sema.optEuBasePtrInit(block, ptr, src);
47214155}
47224156
47234157fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -4726,7 +4160,7 @@ fn zirCoercePtrElemTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
47264160 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
47274161 const src = block.nodeOffset(pl_node.src_node);
47284162 const extra = sema.code.extraData(Zir.Inst.Bin, pl_node.payload_index).data;
4729 const uncoerced_val = try sema.resolveInst(extra.rhs);
4163 const uncoerced_val = sema.resolveInst(extra.rhs);
47304164 const maybe_wrapped_ptr_ty = try sema.resolveTypeOrPoison(block, LazySrcLoc.unneeded, extra.lhs) orelse return uncoerced_val;
47314165 const ptr_ty = maybe_wrapped_ptr_ty.optEuBaseType(zcu);
47324166 assert(ptr_ty.zigTypeTag(zcu) == .pointer); // validated by a previous instruction
......@@ -4812,7 +4246,7 @@ fn zirTryOperandTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: boo
48124246 if (is_ref) {
48134247 var ptr_info = operand_ty.ptrInfo(zcu);
48144248 ptr_info.child = eu_ty.toIntern();
4815 const eu_ptr_ty = try pt.ptrTypeSema(ptr_info);
4249 const eu_ptr_ty = try pt.ptrType(ptr_info);
48164250 return Air.internedToRef(eu_ptr_ty.toIntern());
48174251 } else {
48184252 return Air.internedToRef(eu_ty.toIntern());
......@@ -4842,7 +4276,7 @@ fn zirValidateConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
48424276
48434277 const un_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
48444278 const src = block.nodeOffset(un_node.src_node);
4845 const init_ref = try sema.resolveInst(un_node.operand);
4279 const init_ref = sema.resolveInst(un_node.operand);
48464280 if (!try sema.isComptimeKnown(init_ref)) {
48474281 return sema.failWithNeededComptime(block, src, null);
48484282 }
......@@ -4935,7 +4369,6 @@ fn validateArrayInitTy(
49354369 return;
49364370 },
49374371 .@"struct" => if (ty.isTuple(zcu)) {
4938 try ty.resolveFields(pt);
49394372 const array_len = ty.arrayLen(zcu);
49404373 if (init_count > array_len) {
49414374 return sema.fail(block, src, "expected at most {d} tuple fields; found {d}", .{
......@@ -4986,7 +4419,7 @@ fn zirValidatePtrStructInit(
49864419 const instrs = sema.code.bodySlice(validate_extra.end, validate_extra.data.body_len);
49874420 const field_ptr_data = sema.code.instructions.items(.data)[@intFromEnum(instrs[0])].pl_node;
49884421 const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;
4989 const object_ptr = try sema.resolveInst(field_ptr_extra.lhs);
4422 const object_ptr = sema.resolveInst(field_ptr_extra.lhs);
49904423 const agg_ty = sema.typeOf(object_ptr).childType(zcu).optEuBaseType(zcu);
49914424 switch (agg_ty.zigTypeTag(zcu)) {
49924425 .@"struct" => return sema.validateStructInit(
......@@ -5097,12 +4530,16 @@ fn validateStructInit(
50974530 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
50984531
50994532 for (found_fields, 0..) |explicit, i_usize| {
5100 if (explicit) continue;
51014533 const i: u32 = @intCast(i_usize);
51024534
5103 try struct_ty.resolveStructFieldInits(pt);
5104 const default_val = struct_ty.structFieldDefaultValue(i, zcu);
5105 if (default_val.toIntern() == .unreachable_value) {
4535 if (explicit) continue;
4536 if (struct_ty.structFieldIsComptime(i, zcu)) continue;
4537
4538 if (!struct_ty.isTuple(zcu)) {
4539 try sema.ensureStructDefaultsResolved(struct_ty, init_src);
4540 }
4541
4542 const default_val = struct_ty.structFieldDefaultValue(i, zcu) orelse {
51064543 const field_name = struct_ty.structFieldName(i, zcu).unwrap() orelse {
51074544 const template = "missing tuple field with index {d}";
51084545 if (root_msg) |msg| {
......@@ -5120,13 +4557,10 @@ fn validateStructInit(
51204557 root_msg = try sema.errMsg(init_src, template, args);
51214558 }
51224559 continue;
5123 }
4560 };
51244561
51254562 const field_src = init_src; // TODO better source location
5126 const default_field_ptr = if (struct_ty.isTuple(zcu))
5127 try sema.tupleFieldPtr(block, init_src, struct_ptr, field_src, @intCast(i), true)
5128 else
5129 try sema.structFieldPtrByIndex(block, init_src, struct_ptr, @intCast(i), struct_ty);
4563 const default_field_ptr = try sema.structFieldPtrByIndex(block, init_src, struct_ptr, @intCast(i), struct_ty);
51304564 try sema.checkKnownAllocPtr(block, struct_ptr, default_field_ptr);
51314565 try sema.storePtr2(block, init_src, default_field_ptr, init_src, .fromValue(default_val), field_src, .store);
51324566 }
......@@ -5151,7 +4585,7 @@ fn zirValidatePtrArrayInit(
51514585 const instrs = sema.code.bodySlice(validate_extra.end, validate_extra.data.body_len);
51524586 const first_elem_ptr_data = sema.code.instructions.items(.data)[@intFromEnum(instrs[0])].pl_node;
51534587 const elem_ptr_extra = sema.code.extraData(Zir.Inst.ElemPtrImm, first_elem_ptr_data.payload_index).data;
5154 const array_ptr = try sema.resolveInst(elem_ptr_extra.ptr);
4588 const array_ptr = sema.resolveInst(elem_ptr_extra.ptr);
51554589 const array_ty = sema.typeOf(array_ptr).childType(zcu).optEuBaseType(zcu);
51564590 const array_len = array_ty.arrayLen(zcu);
51574591
......@@ -5166,11 +4600,9 @@ fn zirValidatePtrArrayInit(
51664600 var root_msg: ?*Zcu.ErrorMsg = null;
51674601 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
51684602
5169 try array_ty.resolveStructFieldInits(pt);
51704603 var i = instrs.len;
51714604 while (i < array_len) : (i += 1) {
5172 const default_val = array_ty.structFieldDefaultValue(i, zcu).toIntern();
5173 if (default_val == .unreachable_value) {
4605 if (array_ty.structFieldDefaultValue(i, zcu) == null) {
51744606 const template = "missing tuple field with index {d}";
51754607 if (root_msg) |msg| {
51764608 try sema.errNote(init_src, msg, template, .{i});
......@@ -5213,7 +4645,7 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
52134645 const zcu = pt.zcu;
52144646 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
52154647 const src = block.nodeOffset(inst_data.src_node);
5216 const operand = try sema.resolveInst(inst_data.operand);
4648 const operand = sema.resolveInst(inst_data.operand);
52174649 const operand_ty = sema.typeOf(operand);
52184650
52194651 if (operand_ty.zigTypeTag(zcu) != .pointer) {
......@@ -5224,40 +4656,14 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
52244656 .slice => return sema.fail(block, src, "index syntax required for slice type '{f}'", .{operand_ty.fmt(pt)}),
52254657 }
52264658
5227 if ((try sema.typeHasOnePossibleValue(operand_ty.childType(zcu))) != null) {
5228 // No need to validate the actual pointer value, we don't need it!
5229 return;
5230 }
5231
5232 const elem_ty = operand_ty.elemType2(zcu);
5233 if (try sema.resolveValue(operand)) |val| {
5234 if (val.isUndef(zcu)) {
4659 if (sema.resolveValue(operand)) |val| {
4660 // Error for deref of undef pointer, unless the pointee is OPV in which case it's legal.
4661 if (val.isUndef(zcu) and operand_ty.childType(zcu).classify(zcu) != .one_possible_value) {
52354662 return sema.fail(block, src, "cannot dereference undefined value", .{});
52364663 }
5237 } else if (try elem_ty.comptimeOnlySema(pt)) {
5238 const msg = msg: {
5239 const msg = try sema.errMsg(
5240 src,
5241 "values of type '{f}' must be comptime-known, but operand value is runtime-known",
5242 .{elem_ty.fmt(pt)},
5243 );
5244 errdefer msg.destroy(sema.gpa);
5245
5246 try sema.explainWhyTypeIsComptime(msg, src, elem_ty);
5247 break :msg msg;
5248 };
5249 return sema.failWithOwnedErrorMsg(block, msg);
52504664 }
52514665}
52524666
5253fn typeIsDestructurable(ty: Type, zcu: *const Zcu) bool {
5254 return switch (ty.zigTypeTag(zcu)) {
5255 .array, .vector => true,
5256 .@"struct" => ty.isTuple(zcu),
5257 else => false,
5258 };
5259}
5260
52614667fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
52624668 const pt = sema.pt;
52634669 const zcu = pt.zcu;
......@@ -5265,17 +4671,17 @@ fn zirValidateDestructure(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
52654671 const extra = sema.code.extraData(Zir.Inst.ValidateDestructure, inst_data.payload_index).data;
52664672 const src = block.nodeOffset(inst_data.src_node);
52674673 const destructure_src = block.nodeOffset(extra.destructure_node);
5268 const operand = try sema.resolveInst(extra.operand);
4674 const operand = sema.resolveInst(extra.operand);
52694675 const operand_ty = sema.typeOf(operand);
52704676
5271 if (!typeIsDestructurable(operand_ty, zcu)) {
4677 if (!operand_ty.destructurable(zcu)) {
52724678 return sema.failWithOwnedErrorMsg(block, msg: {
52734679 const msg = try sema.errMsg(src, "type '{f}' cannot be destructured", .{operand_ty.fmt(pt)});
52744680 errdefer msg.destroy(sema.gpa);
52754681 try sema.errNote(destructure_src, msg, "result destructured here", .{});
52764682 if (operand_ty.zigTypeTag(pt.zcu) == .error_union) {
52774683 const base_op_ty = operand_ty.errorUnionPayload(zcu);
5278 if (typeIsDestructurable(base_op_ty, zcu))
4684 if (base_op_ty.destructurable(zcu))
52794685 try sema.errNote(src, msg, "consider using 'try', 'catch', or 'if'", .{});
52804686 }
52814687 break :msg msg;
......@@ -5373,7 +4779,7 @@ fn failWithBadUnionFieldAccess(
53734779 return sema.failWithOwnedErrorMsg(block, msg);
53744780}
53754781
5376fn addDeclaredHereNote(sema: *Sema, parent: *Zcu.ErrorMsg, decl_ty: Type) !void {
4782pub fn addDeclaredHereNote(sema: *Sema, parent: *Zcu.ErrorMsg, decl_ty: Type) !void {
53774783 const zcu = sema.pt.zcu;
53784784 const src_loc = decl_ty.srcLocOrNull(zcu) orelse return;
53794785 const category = switch (decl_ty.zigTypeTag(zcu)) {
......@@ -5393,8 +4799,8 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi
53934799 const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
53944800 const src = block.nodeOffset(pl_node.src_node);
53954801 const bin = sema.code.extraData(Zir.Inst.Bin, pl_node.payload_index).data;
5396 const ptr = try sema.resolveInst(bin.lhs);
5397 const operand = try sema.resolveInst(bin.rhs);
4802 const ptr = sema.resolveInst(bin.lhs);
4803 const operand = sema.resolveInst(bin.rhs);
53984804 const ptr_inst = ptr.toIndex().?;
53994805 const air_datas = sema.air_instructions.items(.data);
54004806
......@@ -5440,17 +4846,19 @@ fn storeToInferredAllocComptime(
54404846 const operand_ty = sema.typeOf(operand);
54414847 // There will be only one store_to_inferred_ptr because we are running at comptime.
54424848 // The alloc will turn into a Decl or a ComptimeAlloc.
5443 const operand_val = try sema.resolveValue(operand) orelse {
4849 const operand_val = sema.resolveValue(operand) orelse {
54444850 return sema.failWithNeededComptime(block, src, .{ .simple = .stored_to_comptime_var });
54454851 };
5446 const alloc_ty = try pt.ptrTypeSema(.{
4852 const alloc_ty = try pt.ptrType(.{
54474853 .child = operand_ty.toIntern(),
54484854 .flags = .{
54494855 .alignment = iac.alignment,
54504856 .is_const = iac.is_const,
54514857 },
54524858 });
5453 if (iac.is_const and !operand_val.canMutateComptimeVarState(zcu)) {
4859 if (operand_ty.classify(zcu) == .one_possible_value or
4860 (iac.is_const and !operand_val.canMutateComptimeVarState(zcu)))
4861 {
54544862 iac.ptr = try pt.intern(.{ .ptr = .{
54554863 .ty = alloc_ty.toIntern(),
54564864 .base_addr = .{ .uav = .{
......@@ -5487,8 +4895,8 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v
54874895 const inst_data = zir_datas[@intFromEnum(inst)].pl_node;
54884896 const src = block.nodeOffset(inst_data.src_node);
54894897 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
5490 const ptr = try sema.resolveInst(extra.lhs);
5491 const operand = try sema.resolveInst(extra.rhs);
4898 const ptr = sema.resolveInst(extra.lhs);
4899 const operand = sema.resolveInst(extra.rhs);
54924900
54934901 const is_ret = if (extra.lhs.toIndex()) |ptr_index|
54944902 zir_tags[@intFromEnum(ptr_index)] == .ret_ptr
......@@ -5535,11 +4943,11 @@ pub fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!
55354943 .ty = array_ty.toIntern(),
55364944 .storage = .{ .bytes = string },
55374945 } });
5538 return sema.uavRef(val);
4946 return sema.uavRef(.fromInterned(val));
55394947}
55404948
5541fn uavRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {
5542 return Air.internedToRef(try sema.pt.refValue(val));
4949fn uavRef(sema: *Sema, val: Value) CompileError!Air.Inst.Ref {
4950 return .fromValue(try sema.pt.uavValue(val));
55434951}
55444952
55454953fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -5622,9 +5030,9 @@ fn zirCompileLog(
56225030 for (args, 0..) |arg_ref, i| {
56235031 if (i != 0) writer.writeAll(", ") catch return error.OutOfMemory;
56245032
5625 const arg = try sema.resolveInst(arg_ref);
5033 const arg = sema.resolveInst(arg_ref);
56265034 const arg_ty = sema.typeOf(arg);
5627 if (try sema.resolveValueResolveLazy(arg)) |val| {
5035 if (sema.resolveValue(arg)) |val| {
56285036 writer.print("@as({f}, {f})", .{
56295037 arg_ty.fmt(pt), val.fmtValueSema(pt, sema),
56305038 }) catch return error.OutOfMemory;
......@@ -5672,7 +5080,7 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
56725080
56735081 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
56745082 const src = block.nodeOffset(inst_data.src_node);
5675 const msg_inst = try sema.resolveInst(inst_data.operand);
5083 const msg_inst = sema.resolveInst(inst_data.operand);
56765084
56775085 const arg_src = block.builtinCallArgSrc(inst_data.src_node, 0);
56785086 const coerced_msg = try sema.coerce(block, .slice_const_u8, msg_inst, arg_src);
......@@ -5752,9 +5160,9 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
57525160 var label: Block.Label = .{
57535161 .zir_block = inst,
57545162 .merges = .{
5755 .src_locs = .{},
5756 .results = .{},
5757 .br_list = .{},
5163 .src_locs = .empty,
5164 .results = .empty,
5165 .br_list = .empty,
57585166 .block_inst = block_inst,
57595167 },
57605168 };
......@@ -5826,7 +5234,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
58265234 .parent = parent_block,
58275235 .sema = sema,
58285236 .namespace = parent_block.namespace,
5829 .instructions = .{},
5237 .instructions = .empty,
58305238 .inlining = parent_block.inlining,
58315239 .comptime_reason = .{ .reason = .{
58325240 .src = src,
......@@ -5927,11 +5335,10 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
59275335 pt.updateFile(new_file_index, zcu.fileByIndex(new_file_index)) catch |err|
59285336 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
59295337
5930 try pt.ensureFileAnalyzed(new_file_index);
5931 const ty = zcu.fileRootType(new_file_index);
5932 try sema.declareDependency(.{ .interned = ty });
5338 try pt.ensureFilePopulated(new_file_index);
5339 const ty: Type = .fromInterned(zcu.fileRootType(new_file_index));
59335340 try sema.addTypeReferenceEntry(src, ty);
5934 return Air.internedToRef(ty);
5341 return .fromType(ty);
59355342}
59365343
59375344fn zirSuspendBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -5962,9 +5369,9 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro
59625369 var label: Block.Label = .{
59635370 .zir_block = inst,
59645371 .merges = .{
5965 .src_locs = .{},
5966 .results = .{},
5967 .br_list = .{},
5372 .src_locs = .empty,
5373 .results = .empty,
5374 .br_list = .empty,
59685375 .block_inst = block_inst,
59695376 },
59705377 };
......@@ -5973,7 +5380,7 @@ fn zirBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErro
59735380 .parent = parent_block,
59745381 .sema = sema,
59755382 .namespace = parent_block.namespace,
5976 .instructions = .{},
5383 .instructions = .empty,
59775384 .label = &label,
59785385 .inlining = parent_block.inlining,
59795386 .comptime_reason = parent_block.comptime_reason,
......@@ -6043,7 +5450,7 @@ fn resolveBlockBody(
60435450 const break_data = sema.code.instructions.items(.data)[@intFromEnum(break_inst)].@"break";
60445451 const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;
60455452 if (extra.block_inst == body_inst) {
6046 return try sema.resolveInst(break_data.operand);
5453 return sema.resolveInst(break_data.operand);
60475454 } else {
60485455 return error.ComptimeBreak;
60495456 }
......@@ -6134,7 +5541,7 @@ fn resolveAnalyzedBlock(
61345541 // Okay, we need a runtime block. If the value is comptime-known, the
61355542 // block should just return void, and we return the merge result
61365543 // directly. Otherwise, we can defer to the logic below.
6137 if (try sema.resolveValue(merges.results.items[0])) |result_val| {
5544 if (sema.resolveValue(merges.results.items[0])) |result_val| {
61385545 // Create a block containing all instruction from the body.
61395546 try parent_block.instructions.append(gpa, merges.block_inst);
61405547 switch (block_tag) {
......@@ -6177,10 +5584,11 @@ fn resolveAnalyzedBlock(
61775584 // to emit a jump instruction to after the block when it encounters the break.
61785585 try parent_block.instructions.append(gpa, merges.block_inst);
61795586 const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items, .{ .override = merges.src_locs.items });
5587 resolved_ty.assertHasLayout(zcu);
61805588 // TODO add note "missing else causes void value"
61815589
61825590 const type_src = src; // TODO: better source location
6183 if (try resolved_ty.comptimeOnlySema(pt)) {
5591 if (resolved_ty.comptimeOnly(zcu)) {
61845592 const msg = msg: {
61855593 const msg = try sema.errMsg(type_src, "value with comptime-only type '{f}' depends on runtime control flow", .{resolved_ty.fmt(pt)});
61865594 errdefer msg.destroy(sema.gpa);
......@@ -6274,10 +5682,7 @@ fn resolveAnalyzedBlock(
62745682 });
62755683 }
62765684
6277 if (try sema.typeHasOnePossibleValue(resolved_ty)) |block_only_value| {
6278 return Air.internedToRef(block_only_value.toIntern());
6279 }
6280
5685 if (try resolved_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
62815686 return merges.block_inst.toRef();
62825687}
62835688
......@@ -6295,7 +5700,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
62955700 const ptr_src = block.builtinCallArgSrc(inst_data.src_node, 0);
62965701 const options_src = block.builtinCallArgSrc(inst_data.src_node, 1);
62975702
6298 const ptr = try sema.resolveInst(extra.exported);
5703 const ptr = sema.resolveInst(extra.exported);
62995704 const ptr_val = try sema.resolveConstDefinedValue(block, ptr_src, ptr, .{ .simple = .export_target });
63005705 const ptr_ty = ptr_val.typeOf(zcu);
63015706
......@@ -6314,91 +5719,95 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
63145719 }
63155720 }
63165721
5722 const export_ty = ptr_ty.childType(zcu);
5723 try sema.ensureLayoutResolved(export_ty, src, .@"export");
5724 if (!export_ty.validateExtern(.other, zcu)) {
5725 return sema.failWithOwnedErrorMsg(block, msg: {
5726 const msg = try sema.errMsg(src, "unable to export type '{f}'", .{export_ty.fmt(pt)});
5727 errdefer msg.destroy(sema.gpa);
5728 try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other);
5729 try sema.addDeclaredHereNote(msg, export_ty);
5730 break :msg msg;
5731 });
5732 }
5733
63175734 const ptr_info = ip.indexToKey(ptr_val.toIntern()).ptr;
6318 switch (ptr_info.base_addr) {
5735 const target: Zcu.Exported = switch (ptr_info.base_addr) {
63195736 .comptime_alloc, .int, .comptime_field => return sema.fail(block, ptr_src, "export target must be a global variable or a comptime-known constant", .{}),
63205737 .eu_payload, .opt_payload, .field, .arr_elem => return sema.fail(block, ptr_src, "TODO: export pointer in middle of value", .{}),
6321 .uav => |uav| {
6322 if (ptr_info.byte_offset != 0) {
6323 return sema.fail(block, ptr_src, "TODO: export pointer in middle of value", .{});
6324 }
6325 if (zcu.llvm_object != null and options.linkage == .internal) return;
6326 const export_ty = Value.fromInterned(uav.val).typeOf(zcu);
6327 if (!try sema.validateExternType(export_ty, .other)) {
6328 return sema.failWithOwnedErrorMsg(block, msg: {
6329 const msg = try sema.errMsg(src, "unable to export type '{f}'", .{export_ty.fmt(pt)});
6330 errdefer msg.destroy(sema.gpa);
6331 try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other);
6332 try sema.addDeclaredHereNote(msg, export_ty);
6333 break :msg msg;
6334 });
6335 }
6336 try sema.exports.append(zcu.gpa, .{
6337 .opts = options,
6338 .src = src,
6339 .exported = .{ .uav = uav.val },
6340 .status = .in_progress,
6341 });
6342 },
6343 .nav => |nav| {
6344 if (ptr_info.byte_offset != 0) {
6345 return sema.fail(block, ptr_src, "TODO: export pointer in middle of value", .{});
5738 .uav => |uav| .{ .uav = uav.val },
5739 .nav => |orig_nav| target: {
5740 try sema.ensureNavResolved(block, src, orig_nav, .fully);
5741 const export_nav = switch (ip.indexToKey(ip.getNav(orig_nav).status.fully_resolved.val)) {
5742 .variable => |v| v.owner_nav,
5743 .@"extern" => |e| e.owner_nav,
5744 .func => |f| f.owner_nav,
5745 else => orig_nav,
5746 };
5747 if (ip.getNav(export_nav).getExtern(ip) != null) {
5748 return sema.fail(block, src, "export target cannot be extern", .{});
63465749 }
6347 try sema.analyzeExport(block, src, options, nav);
5750 try sema.maybeQueueFuncBodyAnalysis(block, src, export_nav);
5751 break :target .{ .nav = export_nav };
63485752 },
5753 };
5754 if (ptr_info.byte_offset != 0) {
5755 return sema.fail(block, ptr_src, "TODO: export pointer in middle of value", .{});
63495756 }
5757 if (zcu.llvm_object != null and options.linkage == .internal) return;
5758 try sema.exports.append(zcu.gpa, .{
5759 .opts = options,
5760 .src = src,
5761 .exported = target,
5762 .status = .in_progress,
5763 });
63505764}
63515765
6352pub fn analyzeExport(
5766/// Asserts that `sema.owner` is a `.nav_val` whose value is resolved.
5767///
5768/// Exports that `Nav` by the given name with all other options set to default.
5769pub fn analyzeExportSelfNav(
63535770 sema: *Sema,
63545771 block: *Block,
63555772 src: LazySrcLoc,
6356 options: Zcu.Export.Options,
6357 orig_nav_index: InternPool.Nav.Index,
5773 name: InternPool.NullTerminatedString,
63585774) !void {
63595775 const gpa = sema.gpa;
63605776 const pt = sema.pt;
63615777 const zcu = pt.zcu;
63625778 const ip = &zcu.intern_pool;
63635779
6364 if (zcu.llvm_object != null and options.linkage == .internal)
6365 return;
6366
6367 try sema.ensureNavResolved(block, src, orig_nav_index, .fully);
6368
6369 const exported_nav_index = switch (ip.indexToKey(ip.getNav(orig_nav_index).status.fully_resolved.val)) {
6370 .variable => |v| v.owner_nav,
6371 .@"extern" => |e| e.owner_nav,
6372 .func => |f| f.owner_nav,
6373 else => orig_nav_index,
6374 };
6375
6376 const exported_nav = ip.getNav(exported_nav_index);
6377 const export_ty: Type = .fromInterned(exported_nav.typeOf(ip));
5780 const orig_nav = sema.owner.unwrap().nav_val;
5781 const export_val: Value = .fromInterned(ip.getNav(orig_nav).status.fully_resolved.val);
5782 const export_ty = export_val.typeOf(zcu);
63785783
6379 if (!try sema.validateExternType(export_ty, .other)) {
5784 if (!export_ty.validateExtern(.other, zcu)) {
63805785 return sema.failWithOwnedErrorMsg(block, msg: {
63815786 const msg = try sema.errMsg(src, "unable to export type '{f}'", .{export_ty.fmt(pt)});
63825787 errdefer msg.destroy(gpa);
6383
63845788 try sema.explainWhyTypeIsNotExtern(msg, src, export_ty, .other);
6385
63865789 try sema.addDeclaredHereNote(msg, export_ty);
63875790 break :msg msg;
63885791 });
63895792 }
63905793
6391 // TODO: some backends might support re-exporting extern decls
6392 if (exported_nav.getExtern(ip) != null) {
6393 return sema.fail(block, src, "export target cannot be extern", .{});
6394 }
6395
6396 try sema.maybeQueueFuncBodyAnalysis(block, src, exported_nav_index);
5794 const export_nav = switch (ip.indexToKey(export_val.toIntern())) {
5795 .variable => |v| v.owner_nav,
5796 .@"extern" => |e| e.owner_nav,
5797 .func => |f| export_nav: {
5798 assert(export_ty.fnHasRuntimeBits(zcu)); // otherwise `validateExtern` failed above
5799 const orig_fn_index = ip.unwrapCoercedFunc(export_val.toIntern());
5800 try sema.addReferenceEntry(block, src, .wrap(.{ .func = orig_fn_index }));
5801 try zcu.ensureFuncBodyAnalysisQueued(orig_fn_index);
5802 break :export_nav f.owner_nav;
5803 },
5804 else => orig_nav,
5805 };
63975806
63985807 try sema.exports.append(gpa, .{
6399 .opts = options,
5808 .opts = .{ .name = name },
64005809 .src = src,
6401 .exported = .{ .nav = exported_nav_index },
5810 .exported = .{ .nav = export_nav },
64025811 .status = .in_progress,
64035812 });
64045813}
......@@ -6413,7 +5822,8 @@ fn zirDisableInstrumentation(sema: *Sema) CompileError!void {
64135822 .@"comptime",
64145823 .nav_val,
64155824 .nav_ty,
6416 .type,
5825 .type_layout,
5826 .struct_defaults,
64175827 .memoized_state,
64185828 => return, // does nothing outside a function
64195829 };
......@@ -6431,7 +5841,8 @@ fn zirDisableIntrinsics(sema: *Sema) CompileError!void {
64315841 .@"comptime",
64325842 .nav_val,
64335843 .nav_ty,
6434 .type,
5844 .type_layout,
5845 .struct_defaults,
64355846 .memoized_state,
64365847 => return, // does nothing outside a function
64375848 };
......@@ -6457,7 +5868,7 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError
64575868
64585869 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"break";
64595870 const extra = sema.code.extraData(Zir.Inst.Break, inst_data.payload_index).data;
6460 const operand = try sema.resolveInst(inst_data.operand);
5871 const operand = sema.resolveInst(inst_data.operand);
64615872 const zir_block = extra.block_inst;
64625873
64635874 var block = start_block;
......@@ -6491,7 +5902,7 @@ fn zirSwitchContinue(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) Com
64915902 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].@"break";
64925903 const extra = sema.code.extraData(Zir.Inst.Break, inst_data.payload_index).data;
64935904 const operand_src = start_block.nodeOffset(extra.operand_src_node.unwrap().?);
6494 const uncoerced_operand = try sema.resolveInst(inst_data.operand);
5905 const uncoerced_operand = sema.resolveInst(inst_data.operand);
64955906 const switch_inst = extra.block_inst;
64965907
64975908 switch (sema.code.instructions.items(.tag)[@intFromEnum(switch_inst)]) {
......@@ -6500,7 +5911,7 @@ fn zirSwitchContinue(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) Com
65005911 else => unreachable, // assertion failure
65015912 }
65025913
6503 const operand_ty = (try sema.resolveInst(switch_inst.toRef())).toType();
5914 const operand_ty = (sema.resolveInst(switch_inst.toRef())).toType();
65045915 const operand = try sema.coerce(start_block, operand_ty, uncoerced_operand, operand_src);
65055916 try sema.validateRuntimeValue(start_block, operand_src, operand);
65065917
......@@ -6567,7 +5978,7 @@ fn zirDbgVar(
65675978 air_tag: Air.Inst.Tag,
65685979) CompileError!void {
65695980 const str_op = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_op;
6570 const operand = try sema.resolveInst(str_op.operand);
5981 const operand = sema.resolveInst(str_op.operand);
65715982 const name = str_op.getStr(sema.code);
65725983 try sema.addDbgVar(block, operand, air_tag, name);
65735984}
......@@ -6589,9 +6000,9 @@ fn addDbgVar(
65896000 .dbg_var_val, .dbg_arg_inline => operand_ty,
65906001 else => unreachable,
65916002 };
6592 if (try val_ty.comptimeOnlySema(pt)) return;
6593 if (!(try val_ty.hasRuntimeBitsSema(pt))) return;
6594 if (try sema.resolveValue(operand)) |operand_val| {
6003 if (val_ty.comptimeOnly(zcu)) return;
6004 if (!val_ty.hasRuntimeBits(zcu)) return;
6005 if (sema.resolveValue(operand)) |operand_val| {
65956006 if (operand_val.canMutateComptimeVarState(zcu)) return;
65966007 }
65976008
......@@ -6730,7 +6141,7 @@ fn funcDeclSrcInst(sema: *Sema, func_inst: Air.Inst.Ref) !?InternPool.TrackedIns
67306141 const pt = sema.pt;
67316142 const zcu = pt.zcu;
67326143 const ip = &zcu.intern_pool;
6733 const func_val = try sema.resolveValue(func_inst) orelse return null;
6144 const func_val = sema.resolveValue(func_inst) orelse return null;
67346145 if (func_val.isUndef(zcu)) return null;
67356146 const nav = switch (ip.indexToKey(func_val.toIntern())) {
67366147 .@"extern" => |e| e.owner_nav,
......@@ -6759,7 +6170,6 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref
67596170 if (!block.ownerModule().error_tracing) return .none;
67606171
67616172 const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(.zero), .StackTrace);
6762 try stack_trace_ty.resolveFields(pt);
67636173 const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "index", .no_embedded_nulls);
67646174 const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) {
67656175 error.AnalysisFail => @panic("std.builtin.StackTrace is corrupt"),
......@@ -6803,11 +6213,10 @@ fn popErrorReturnTrace(
68036213 // the result is comptime-known to be a non-error. Either way, pop unconditionally.
68046214
68056215 const stack_trace_ty = try sema.getBuiltinType(src, .StackTrace);
6806 try stack_trace_ty.resolveFields(pt);
68076216 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
68086217 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
68096218 const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "index", .no_embedded_nulls);
6810 const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, field_name, src, stack_trace_ty, true);
6219 const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, field_name, src, stack_trace_ty);
68116220 try sema.storePtr2(block, src, field_ptr, src, saved_error_trace_index, src, .store);
68126221 } else if (is_non_error == null) {
68136222 // The result might be an error. If it is, we leave the error trace alone. If it isn't, we need
......@@ -6829,11 +6238,10 @@ fn popErrorReturnTrace(
68296238
68306239 // If non-error, then pop the error return trace by restoring the index.
68316240 const stack_trace_ty = try sema.getBuiltinType(src, .StackTrace);
6832 try stack_trace_ty.resolveFields(pt);
68336241 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
68346242 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);
68356243 const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "index", .no_embedded_nulls);
6836 const field_ptr = try sema.structFieldPtr(&then_block, src, err_return_trace, field_name, src, stack_trace_ty, true);
6244 const field_ptr = try sema.structFieldPtr(&then_block, src, err_return_trace, field_name, src, stack_trace_ty);
68376245 try sema.storePtr2(&then_block, src, field_ptr, src, saved_error_trace_index, src, .store);
68386246 _ = try then_block.addBr(cond_block_inst, .void_value);
68396247
......@@ -6905,9 +6313,9 @@ fn zirCall(
69056313 const pop_error_return_trace = extra.data.flags.pop_error_return_trace;
69066314
69076315 const callee: ResolvedFieldCallee = switch (kind) {
6908 .direct => .{ .direct = try sema.resolveInst(extra.data.callee) },
6316 .direct => .{ .direct = sema.resolveInst(extra.data.callee) },
69096317 .field => blk: {
6910 const object_ptr = try sema.resolveInst(extra.data.obj_ptr);
6318 const object_ptr = sema.resolveInst(extra.data.obj_ptr);
69116319 const field_name = try zcu.intern_pool.getOrPutString(
69126320 gpa,
69136321 io,
......@@ -6969,7 +6377,6 @@ fn zirCall(
69696377 // need to clean-up our own trace if we were passed to a non-error-handling expression.
69706378 if (input_is_error or (pop_error_return_trace and return_ty.isError(zcu))) {
69716379 const stack_trace_ty = try sema.getBuiltinType(call_src, .StackTrace);
6972 try stack_trace_ty.resolveFields(pt);
69736380 const field_name = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, "index", .no_embedded_nulls);
69746381 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);
69756382
......@@ -7255,7 +6662,7 @@ const CallArgsInfo = union(enum) {
72556662 return sema.failWithNeededComptime(block, cai.argSrc(block, arg_index), null);
72566663 }
72576664
7258 if (sema.typeOf(uncoerced_arg).zigTypeTag(zcu) == .noreturn) {
6665 if (sema.typeOf(uncoerced_arg).classify(zcu) == .no_possible_value) {
72596666 // This terminates resolution of arguments. The caller should
72606667 // propagate this.
72616668 return uncoerced_arg;
......@@ -7318,6 +6725,21 @@ fn analyzeCall(
73186725 } else func_src;
73196726
73206727 const func_ty_info = zcu.typeToFunc(func_ty).?;
6728
6729 for (func_ty_info.param_types.get(ip), 0..) |param_ty_ip, param_index| {
6730 const arg_src = args_info.argSrc(block, param_index);
6731 try sema.ensureLayoutResolved(.fromInterned(param_ty_ip), arg_src, .init);
6732 }
6733 try sema.ensureLayoutResolved(.fromInterned(func_ty_info.return_type), func_ret_ty_src, .return_type);
6734 try sema.validateResolvedFuncType(
6735 block,
6736 func_ty_info.cc,
6737 func_ty_info.param_types.get(ip),
6738 .fromInterned(func_ty_info.return_type),
6739 func_src,
6740 maybe_func_inst,
6741 );
6742
73216743 if (!callConvIsCallable(func_ty_info.cc)) {
73226744 return sema.failWithOwnedErrorMsg(block, msg: {
73236745 const msg = try sema.errMsg(
......@@ -7334,6 +6756,28 @@ fn analyzeCall(
73346756 });
73356757 }
73366758
6759 const any_comptime_params = func_ty_info.comptime_bits != 0 or ct: {
6760 for (func_ty_info.param_types.get(ip)) |param_ty| {
6761 if (Type.fromInterned(param_ty).comptimeOnly(zcu)) break :ct true;
6762 }
6763 break :ct Type.fromInterned(func_ty_info.return_type).comptimeOnly(zcu);
6764 };
6765 const any_generic_types = generic: {
6766 for (func_ty_info.param_types.get(ip)) |param_ty| {
6767 if (param_ty == .generic_poison_type) break :generic true;
6768 }
6769 const ret_ty: Type = .fromInterned(func_ty_info.return_type);
6770 if (ret_ty.toIntern() == .generic_poison_type) {
6771 break :generic true;
6772 }
6773 if (ret_ty.zigTypeTag(zcu) == .error_union and
6774 ret_ty.errorUnionPayload(zcu).toIntern() == .generic_poison_type)
6775 {
6776 break :generic true;
6777 }
6778 break :generic false;
6779 };
6780
73376781 // We need this value in a few code paths.
73386782 const callee_val = try sema.resolveDefinedValue(block, call_src, callee);
73396783 // If the callee is a comptime-known *non-extern* function, `func_val` is populated.
......@@ -7353,7 +6797,7 @@ fn analyzeCall(
73536797 else => unreachable,
73546798 } else .{ null, false };
73556799
7356 if (func_ty_info.is_generic and func_val == null) {
6800 if ((any_generic_types or any_comptime_params) and func_val == null) {
73576801 return sema.failWithNeededComptime(block, func_src, .{ .simple = .generic_call_target });
73586802 }
73596803
......@@ -7369,19 +6813,18 @@ fn analyzeCall(
73696813 .src = call_src,
73706814 .r = .{ .simple = .comptime_call_modifier },
73716815 } };
7372 } else if (!inline_requested and try Type.fromInterned(func_ty_info.return_type).comptimeOnlySema(pt)) {
7373 block.comptime_reason = .{
7374 .reason = .{
6816 } else if (!inline_requested) {
6817 const ret_ty: Type = .fromInterned(func_ty_info.return_type);
6818 if (ret_ty.comptimeOnly(zcu)) {
6819 block.comptime_reason = .{ .reason = .{
73756820 .src = call_src,
7376 .r = .{
7377 .comptime_only_ret_ty = .{
7378 .ty = .fromInterned(func_ty_info.return_type),
7379 .is_generic_inst = false,
7380 .ret_ty_src = func_ret_ty_src,
7381 },
7382 },
7383 },
7384 };
6821 .r = .{ .comptime_only_ret_ty = .{
6822 .ty = .fromInterned(func_ty_info.return_type),
6823 .is_generic_inst = false,
6824 .ret_ty_src = func_ret_ty_src,
6825 } },
6826 } };
6827 }
73856828 }
73866829 }
73876830
......@@ -7403,13 +6846,13 @@ fn analyzeCall(
74036846 // This is the `inst_map` used when evaluating generic parameters and return types.
74046847 var generic_inst_map: InstMap = .{};
74056848 defer generic_inst_map.deinit(gpa);
7406 if (func_ty_info.is_generic) {
6849 if (any_generic_types) {
74076850 try generic_inst_map.ensureSpaceForInstructions(gpa, fn_zir_info.param_body);
74086851 }
74096852
74106853 // This exists so that `generic_block` below can include a "called from here" note back to this
74116854 // call site when analyzing generic parameter/return types.
7412 var generic_inlining: Block.Inlining = if (func_ty_info.is_generic) .{
6855 var generic_inlining: Block.Inlining = if (any_generic_types) .{
74136856 .call_block = block,
74146857 .call_src = call_src,
74156858 .func = func_val.?.toIntern(),
......@@ -7422,18 +6865,18 @@ fn analyzeCall(
74226865 // This is the block in which we evaluate generic function components: that is, generic parameter
74236866 // types and the generic return type. This must not be used if the function is not generic.
74246867 // `comptime_reason` is set as needed.
7425 var generic_block: Block = if (func_ty_info.is_generic) .{
6868 var generic_block: Block = if (any_generic_types) .{
74266869 .parent = null,
74276870 .sema = sema,
74286871 .namespace = fn_nav.analysis.?.namespace,
7429 .instructions = .{},
6872 .instructions = .empty,
74306873 .inlining = &generic_inlining,
74316874 .src_base_inst = fn_nav.analysis.?.zir_index,
74326875 .type_name_ctx = fn_nav.fqn,
74336876 } else undefined;
7434 defer if (func_ty_info.is_generic) generic_block.instructions.deinit(gpa);
6877 defer if (any_generic_types) generic_block.instructions.deinit(gpa);
74356878
7436 if (func_ty_info.is_generic) {
6879 if (any_generic_types) {
74376880 // We certainly depend on the generic owner's signature!
74386881 try sema.declareDependency(.{ .src_hash = fn_tracked_inst });
74396882 }
......@@ -7445,7 +6888,7 @@ fn analyzeCall(
74456888 if (raw != .generic_poison_type) break :ty .fromInterned(raw);
74466889
74476890 // We must discover the generic parameter type.
7448 assert(func_ty_info.is_generic);
6891 assert(any_generic_types);
74496892 const param_inst_idx = fn_zir_info.param_body[arg_idx];
74506893 const param_inst = fn_zir.instructions.get(@intFromEnum(param_inst_idx));
74516894 switch (param_inst.tag) {
......@@ -7476,7 +6919,7 @@ fn analyzeCall(
74766919 } };
74776920
74786921 const ty_ref = try sema.resolveInlineBody(&generic_block, body, param_inst_idx);
7479 const param_ty = try sema.analyzeAsType(&generic_block, param_src, ty_ref);
6922 const param_ty = try sema.analyzeAsType(&generic_block, param_src, .fn_param_types, ty_ref);
74806923
74816924 if (!param_ty.isValidParamType(zcu)) {
74826925 const opaque_str = if (param_ty.zigTypeTag(zcu) == .@"opaque") "opaque " else "";
......@@ -7490,15 +6933,15 @@ fn analyzeCall(
74906933
74916934 arg.* = try args_info.analyzeArg(sema, block, arg_idx, param_ty, func_ty_info, callee, maybe_func_inst);
74926935 const arg_ty = sema.typeOf(arg.*);
7493 if (arg_ty.zigTypeTag(zcu) == .noreturn) {
6936 if (arg_ty.classify(zcu) == .no_possible_value) {
74946937 return arg.*; // terminate analysis here
74956938 }
74966939
7497 if (func_ty_info.is_generic) {
6940 if (any_generic_types) {
74986941 // We need to put the argument into `generic_inst_map` so that other parameters can refer to it.
74996942 const param_inst_idx = fn_zir_info.param_body[arg_idx];
75006943 const declared_comptime = if (std.math.cast(u5, arg_idx)) |i| func_ty_info.paramIsComptime(i) else false;
7501 const param_is_comptime = declared_comptime or try arg_ty.comptimeOnlySema(pt);
6944 const param_is_comptime = declared_comptime or arg_ty.comptimeOnly(zcu);
75026945 // We allow comptime-known arguments to propagate to generic types not only for comptime
75036946 // parameters, but if the call is known to be inline.
75046947 if (param_is_comptime or early_known_inline) {
......@@ -7516,6 +6959,10 @@ fn analyzeCall(
75166959 );
75176960 }
75186961 generic_inst_map.putAssumeCapacityNoClobber(param_inst_idx, arg.*);
6962 } else if (try arg_ty.onePossibleValue(pt)) |opv| {
6963 // The argument is comptime-known, even though this is a generic instantiation (as
6964 // opposed to an inline call), because the parameter type is OPV.
6965 generic_inst_map.putAssumeCapacityNoClobber(param_inst_idx, .fromValue(opv));
75196966 } else {
75206967 // We need a dummy instruction with this type. It doesn't actually need to be in any block,
75216968 // since it will never be referenced at runtime!
......@@ -7532,7 +6979,7 @@ fn analyzeCall(
75326979 // calls (where it should be the IES of the instantiation). However, it's how we print this
75336980 // in error messages.
75346981 const resolved_ret_ty: Type = ret_ty: {
7535 if (!func_ty_info.is_generic) break :ret_ty .fromInterned(func_ty_info.return_type);
6982 if (!any_generic_types) break :ret_ty .fromInterned(func_ty_info.return_type);
75366983
75376984 const maybe_poison_bare = if (fn_zir_info.inferred_error_set) maybe_poison: {
75386985 break :maybe_poison ip.errorUnionPayload(func_ty_info.return_type);
......@@ -7542,7 +6989,7 @@ fn analyzeCall(
75426989
75436990 // Evaluate the generic return type. As with generic parameters, we switch out `sema.code` and `sema.inst_map`.
75446991
7545 assert(func_ty_info.is_generic);
6992 assert(any_generic_types);
75466993
75476994 const old_code = sema.code;
75486995 const old_inst_map = sema.inst_map;
......@@ -7565,7 +7012,7 @@ fn analyzeCall(
75657012 } else bare: {
75667013 assert(fn_zir_info.ret_ty_body.len != 0);
75677014 const ty_ref = try sema.resolveInlineBody(&generic_block, fn_zir_info.ret_ty_body, fn_zir_inst);
7568 break :bare try sema.analyzeAsType(&generic_block, func_ret_ty_src, ty_ref);
7015 break :bare try sema.analyzeAsType(&generic_block, func_ret_ty_src, .fn_ret_ty, ty_ref);
75697016 };
75707017 assert(bare_ty.toIntern() != .generic_poison_type);
75717018
......@@ -7584,10 +7031,11 @@ fn analyzeCall(
75847031
75857032 break :ret_ty full_ty;
75867033 };
7034 try sema.ensureLayoutResolved(resolved_ret_ty, func_ret_ty_src, .return_type);
75877035
75887036 // If we've discovered after evaluating arguments that a generic function instantiation is
75897037 // comptime-only, then we can mark the block as comptime *now*.
7590 if (!inline_requested and !block.isComptime() and try resolved_ret_ty.comptimeOnlySema(pt)) {
7038 if (!inline_requested and !block.isComptime() and resolved_ret_ty.comptimeOnly(zcu)) {
75917039 block.comptime_reason = .{
75927040 .reason = .{
75937041 .src = call_src,
......@@ -7618,15 +7066,23 @@ fn analyzeCall(
76187066 });
76197067 if (func_ty_info.cc == .auto) {
76207068 switch (sema.owner.unwrap()) {
7621 .@"comptime", .nav_ty, .nav_val, .type, .memoized_state => {},
7069 .@"comptime",
7070 .nav_ty,
7071 .nav_val,
7072 .type_layout,
7073 .struct_defaults,
7074 .memoized_state,
7075 => {},
7076
76227077 .func => |owner_func| ip.funcSetHasErrorTrace(io, owner_func, true),
76237078 }
76247079 }
76257080 for (args, 0..) |arg, arg_idx| {
7626 try sema.validateRuntimeValue(block, args_info.argSrc(block, arg_idx), arg);
7081 const arg_src = args_info.argSrc(block, arg_idx);
7082 try sema.validateRuntimeValue(block, arg_src, arg);
76277083 }
76287084 const runtime_func: Air.Inst.Ref, const runtime_args: []const Air.Inst.Ref = func: {
7629 if (!func_ty_info.is_generic) break :func .{ callee, args };
7085 if (!any_generic_types and !any_comptime_params) break :func .{ callee, args };
76307086
76317087 // Instantiate the generic function!
76327088
......@@ -7648,13 +7104,13 @@ fn analyzeCall(
76487104 break :c true;
76497105 }
76507106 }
7651 break :c try arg_ty.comptimeOnlySema(pt);
7107 break :c arg_ty.comptimeOnly(zcu);
76527108 };
76537109 const is_noalias = if (std.math.cast(u5, arg_idx)) |i| func_ty_info.paramIsNoalias(i) else false;
76547110
76557111 if (is_comptime) {
76567112 // We already emitted an error if the argument isn't comptime-known.
7657 comptime_arg.* = (try sema.resolveValue(arg)).?.toIntern();
7113 comptime_arg.* = sema.resolveValue(arg).?.toIntern();
76587114 } else {
76597115 comptime_arg.* = .none;
76607116 if (is_noalias) {
......@@ -7695,7 +7151,7 @@ fn analyzeCall(
76957151 };
76967152
76977153 ref_func: {
7698 const runtime_func_val = try sema.resolveValue(runtime_func) orelse break :ref_func;
7154 const runtime_func_val = sema.resolveValue(runtime_func) orelse break :ref_func;
76997155 if (!ip.isFuncBody(runtime_func_val.toIntern())) break :ref_func;
77007156 const orig_fn_index = ip.unwrapCoercedFunc(runtime_func_val.toIntern());
77017157 try sema.addReferenceEntry(block, call_src, .wrap(.{ .func = orig_fn_index }));
......@@ -7714,7 +7170,7 @@ fn analyzeCall(
77147170 };
77157171
77167172 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).@"struct".fields.len + runtime_args.len);
7717 const maybe_opv = try block.addInst(.{
7173 const call_ref = try block.addInst(.{
77187174 .tag = call_tag,
77197175 .data = .{ .pl_op = .{
77207176 .operand = runtime_func,
......@@ -7725,8 +7181,10 @@ fn analyzeCall(
77257181 });
77267182 sema.appendRefsAssumeCapacity(runtime_args);
77277183
7184 const actual_ret_ty = sema.typeOf(call_ref);
7185
77287186 if (ensure_result_used) {
7729 try sema.ensureResultUsed(block, sema.typeOf(maybe_opv), call_src);
7187 try sema.ensureResultUsed(block, actual_ret_ty, call_src);
77307188 }
77317189
77327190 if (call_tag == .call_always_tail) {
......@@ -7736,29 +7194,32 @@ fn analyzeCall(
77367194 .pointer => func_or_ptr_ty.childType(zcu),
77377195 else => unreachable,
77387196 };
7739 return sema.handleTailCall(block, call_src, runtime_func_ty, maybe_opv);
7197 return sema.handleTailCall(block, call_src, runtime_func_ty, call_ref);
77407198 }
77417199
7742 if (ip.isNoReturn(resolved_ret_ty.toIntern())) {
7743 const want_check = c: {
7744 if (!block.wantSafety()) break :c false;
7745 if (func_val != null) break :c false;
7746 break :c true;
7747 };
7748 if (want_check) {
7749 try sema.safetyPanic(block, call_src, .noreturn_returned);
7750 } else {
7751 _ = try block.addNoOp(.unreach);
7752 }
7753 return .unreachable_value;
7200 switch (actual_ret_ty.classify(zcu)) {
7201 .no_possible_value => {
7202 const want_check = c: {
7203 if (!block.wantSafety()) break :c false;
7204 if (func_val != null) break :c false;
7205 break :c true;
7206 };
7207 if (want_check) {
7208 try sema.safetyPanic(block, call_src, .noreturn_returned);
7209 } else {
7210 _ = try block.addNoOp(.unreach);
7211 }
7212 return .unreachable_value;
7213 },
7214 .one_possible_value => {
7215 return .fromValue((try actual_ret_ty.onePossibleValue(pt)).?);
7216 },
7217 .runtime => {
7218 return call_ref;
7219 },
7220 .partially_comptime => unreachable,
7221 .fully_comptime => unreachable,
77547222 }
7755
7756 const result: Air.Inst.Ref = if (try sema.typeHasOnePossibleValue(sema.typeOf(maybe_opv))) |opv|
7757 .fromValue(opv)
7758 else
7759 maybe_opv;
7760
7761 return result;
77627223 }
77637224
77647225 // This is an inline call. The function must be comptime-known. We will analyze its body directly using this `Sema`.
......@@ -7836,14 +7297,14 @@ fn analyzeCall(
78367297 if (zcu.comp.config.incremental) break :m false;
78377298 if (!block.isComptime()) break :m false;
78387299 for (args) |a| {
7839 const val = (try sema.resolveValue(a)).?;
7300 const val = sema.resolveValue(a).?;
78407301 if (val.canMutateComptimeVarState(zcu)) break :m false;
78417302 }
78427303 break :m true;
78437304 };
78447305 const memoized_arg_values: []const InternPool.Index = if (want_memoize) arg_vals: {
78457306 const vals = try sema.arena.alloc(InternPool.Index, args.len);
7846 for (vals, args) |*v, a| v.* = (try sema.resolveValue(a)).?.toIntern();
7307 for (vals, args) |*v, a| v.* = sema.resolveValue(a).?.toIntern();
78477308 break :arg_vals vals;
78487309 } else undefined;
78497310 if (want_memoize) memoize: {
......@@ -7927,7 +7388,7 @@ fn analyzeCall(
79277388 .parent = null,
79287389 .sema = sema,
79297390 .namespace = fn_nav.analysis.?.namespace,
7930 .instructions = .{},
7391 .instructions = .empty,
79317392 .inlining = &inlining,
79327393 .is_typeof = block.is_typeof,
79337394 .comptime_reason = if (block.isComptime()) .inlining_parent else null,
......@@ -8000,7 +7461,11 @@ fn analyzeCall(
80007461 break :result try sema.resolveAnalyzedBlock(block, call_src, &child_block, &inlining.merges, need_debug_scope);
80017462 };
80027463
8003 const maybe_opv: Air.Inst.Ref = if (try sema.resolveValue(result_raw)) |result_val| r: {
7464 if (sema.typeOf(result_raw).isNoReturn(zcu)) {
7465 return .unreachable_value;
7466 }
7467
7468 const maybe_opv: Air.Inst.Ref = if (sema.resolveValue(result_raw)) |result_val| r: {
80047469 const val_resolved = try sema.resolveAdHocInferredErrorSet(block, call_src, result_val.toIntern());
80057470 break :r Air.internedToRef(val_resolved);
80067471 } else r: {
......@@ -8012,7 +7477,7 @@ fn analyzeCall(
80127477 };
80137478
80147479 if (block.isComptime()) {
8015 const result_val = (try sema.resolveValue(maybe_opv)).?;
7480 const result_val = sema.resolveValue(maybe_opv).?;
80167481 if (want_memoize and sema.allow_memoize and !result_val.canMutateComptimeVarState(zcu)) {
80177482 _ = try pt.intern(.{ .memoized_call = .{
80187483 .func = func_val.?.toIntern(),
......@@ -8081,15 +7546,12 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
80817546 const bin = sema.code.instructions.items(.data)[@intFromEnum(inst)].bin;
80827547 const maybe_wrapped_indexable_ty = try sema.resolveTypeOrPoison(block, LazySrcLoc.unneeded, bin.lhs) orelse return .generic_poison_type;
80837548 const indexable_ty = maybe_wrapped_indexable_ty.optEuBaseType(zcu);
8084 try indexable_ty.resolveFields(pt);
80857549 assert(indexable_ty.isIndexable(zcu)); // validated by a previous instruction
8086 if (indexable_ty.zigTypeTag(zcu) == .@"struct") {
8087 const elem_type = indexable_ty.fieldType(@intFromEnum(bin.rhs), zcu);
8088 return Air.internedToRef(elem_type.toIntern());
8089 } else {
8090 const elem_type = indexable_ty.elemType2(zcu);
8091 return Air.internedToRef(elem_type.toIntern());
8092 }
7550 const elem_ty = switch (indexable_ty.zigTypeTag(zcu)) {
7551 .@"struct" => indexable_ty.fieldType(@intFromEnum(bin.rhs), zcu),
7552 else => indexable_ty.indexableElem(zcu),
7553 };
7554 return .fromType(elem_ty);
80937555}
80947556
80957557fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -8190,7 +7652,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
81907652 const len = try sema.resolveInt(block, len_src, extra.len, .usize, .{ .simple = .array_length });
81917653 const elem_type = try sema.resolveType(block, elem_src, extra.elem_type);
81927654 try sema.validateArrayElemType(block, elem_type, elem_src);
8193 const uncasted_sentinel = try sema.resolveInst(extra.sentinel);
7655 const uncasted_sentinel = sema.resolveInst(extra.sentinel);
81947656 const sentinel = try sema.coerce(block, elem_type, uncasted_sentinel, sentinel_src);
81957657 const sentinel_val = try sema.resolveConstDefinedValue(block, sentinel_src, sentinel, .{ .simple = .array_sentinel });
81967658 if (sentinel_val.canMutateComptimeVarState(zcu)) {
......@@ -8306,11 +7768,11 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
83067768 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
83077769 const src = block.nodeOffset(extra.node);
83087770 const operand_src = block.builtinCallArgSrc(extra.node, 0);
8309 const uncasted_operand = try sema.resolveInst(extra.operand);
7771 const uncasted_operand = sema.resolveInst(extra.operand);
83107772 const operand = try sema.coerce(block, .anyerror, uncasted_operand, operand_src);
83117773 const err_int_ty = try pt.errorIntType();
83127774
8313 if (try sema.resolveValue(operand)) |val| {
7775 if (sema.resolveValue(operand)) |val| {
83147776 if (val.isUndef(zcu)) {
83157777 return pt.undefRef(err_int_ty);
83167778 }
......@@ -8350,12 +7812,12 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
83507812 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
83517813 const src = block.nodeOffset(extra.node);
83527814 const operand_src = block.builtinCallArgSrc(extra.node, 0);
8353 const uncasted_operand = try sema.resolveInst(extra.operand);
7815 const uncasted_operand = sema.resolveInst(extra.operand);
83547816 const err_int_ty = try pt.errorIntType();
83557817 const operand = try sema.coerce(block, err_int_ty, uncasted_operand, operand_src);
83567818
83577819 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {
8358 const int = try sema.usizeCast(block, operand_src, try value.toUnsignedIntSema(pt));
7820 const int = try sema.usizeCast(block, operand_src, value.toUnsignedInt(zcu));
83597821 if (int > len: {
83607822 const mutate = &ip.global_error_set.mutate;
83617823 mutate.map.mutex.lockUncancelable(io);
......@@ -8397,8 +7859,8 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
83977859 const src = block.src(.{ .node_offset_bin_op = inst_data.src_node });
83987860 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
83997861 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
8400 const lhs = try sema.resolveInst(extra.lhs);
8401 const rhs = try sema.resolveInst(extra.rhs);
7862 const lhs = sema.resolveInst(extra.lhs);
7863 const rhs = sema.resolveInst(extra.rhs);
84027864 if (sema.typeOf(lhs).zigTypeTag(zcu) == .bool and sema.typeOf(rhs).zigTypeTag(zcu) == .bool) {
84037865 const msg = msg: {
84047866 const msg = try sema.errMsg(lhs_src, "expected error set type, found 'bool'", .{});
......@@ -8408,8 +7870,8 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
84087870 };
84097871 return sema.failWithOwnedErrorMsg(block, msg);
84107872 }
8411 const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs);
8412 const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs);
7873 const lhs_ty = try sema.analyzeAsType(block, lhs_src, .type, lhs);
7874 const rhs_ty = try sema.analyzeAsType(block, rhs_src, .type, rhs);
84137875 if (lhs_ty.zigTypeTag(zcu) != .error_set)
84147876 return sema.fail(block, lhs_src, "expected error set type, found '{f}'", .{lhs_ty.fmt(pt)});
84157877 if (rhs_ty.zigTypeTag(zcu) != .error_set)
......@@ -8420,21 +7882,21 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
84207882 return .anyerror_type;
84217883 }
84227884
8423 if (ip.isInferredErrorSetType(lhs_ty.toIntern())) {
8424 switch (try sema.resolveInferredErrorSet(block, src, lhs_ty.toIntern())) {
8425 // isAnyError might have changed from a false negative to a true
8426 // positive after resolution.
8427 .anyerror_type => return .anyerror_type,
8428 else => {},
8429 }
7885 switch (ip.indexToKey(lhs_ty.toIntern())) {
7886 .inferred_error_set_type => |func_index| {
7887 try sema.ensureFuncIesResolved(block, src, func_index);
7888 if (ip.funcIesResolvedUnordered(func_index) == .anyerror_type) return .anyerror_type;
7889 },
7890 .error_set_type => {},
7891 else => unreachable,
84307892 }
8431 if (ip.isInferredErrorSetType(rhs_ty.toIntern())) {
8432 switch (try sema.resolveInferredErrorSet(block, src, rhs_ty.toIntern())) {
8433 // isAnyError might have changed from a false negative to a true
8434 // positive after resolution.
8435 .anyerror_type => return .anyerror_type,
8436 else => {},
8437 }
7893 switch (ip.indexToKey(rhs_ty.toIntern())) {
7894 .inferred_error_set_type => |func_index| {
7895 try sema.ensureFuncIesResolved(block, src, func_index);
7896 if (ip.funcIesResolvedUnordered(func_index) == .anyerror_type) return .anyerror_type;
7897 },
7898 .error_set_type => {},
7899 else => unreachable,
84387900 }
84397901
84407902 const err_set_ty = try sema.errorSetMerge(lhs_ty, rhs_ty);
......@@ -8533,23 +7995,22 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
85337995 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
85347996 const src = block.nodeOffset(inst_data.src_node);
85357997 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
8536 const operand = try sema.resolveInst(inst_data.operand);
7998 const operand = sema.resolveInst(inst_data.operand);
85377999 const operand_ty = sema.typeOf(operand);
85388000
85398001 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(zcu)) {
85408002 .@"enum" => operand,
85418003 .@"union" => blk: {
8542 try operand_ty.resolveFields(pt);
8543 const tag_ty = operand_ty.unionTagType(zcu) orelse {
8004 if (operand_ty.unionTagType(zcu) == null) {
85448005 return sema.fail(
85458006 block,
85468007 operand_src,
85478008 "untagged union '{f}' cannot be converted to integer",
85488009 .{operand_ty.fmt(pt)},
85498010 );
8550 };
8011 }
85518012
8552 break :blk try sema.unionToTag(block, tag_ty, operand, operand_src);
8013 break :blk try sema.unionToTag(block, operand);
85538014 },
85548015 else => {
85558016 return sema.fail(block, operand_src, "expected enum or tagged union, found '{f}'", .{
......@@ -8568,17 +8029,9 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
85688029 });
85698030 }
85708031
8571 if (try sema.typeHasOnePossibleValue(enum_tag_ty)) |opv| {
8572 return Air.internedToRef((try pt.getCoerced(opv, int_tag_ty)).toIntern());
8573 }
8574
8575 if (try sema.resolveValue(enum_tag)) |enum_tag_val| {
8576 if (enum_tag_val.isUndef(zcu)) {
8577 return pt.undefRef(int_tag_ty);
8578 }
8579
8580 const val = try enum_tag_val.intFromEnum(enum_tag_ty, pt);
8581 return Air.internedToRef(val.toIntern());
8032 if (sema.resolveValue(enum_tag)) |enum_tag_val| {
8033 if (enum_tag_val.isUndef(zcu)) return pt.undefRef(int_tag_ty);
8034 return .fromValue(enum_tag_val.intFromEnum(zcu));
85828035 }
85838036
85848037 try sema.requireRuntimeBlock(block, src, operand_src);
......@@ -8593,18 +8046,19 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
85938046 const src = block.nodeOffset(inst_data.src_node);
85948047 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
85958048 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@enumFromInt");
8596 const operand = try sema.resolveInst(extra.rhs);
8049 const operand = sema.resolveInst(extra.rhs);
85978050 const operand_ty = sema.typeOf(operand);
85988051
85998052 if (dest_ty.zigTypeTag(zcu) != .@"enum") {
86008053 return sema.fail(block, src, "expected enum, found '{f}'", .{dest_ty.fmt(pt)});
86018054 }
8055 try sema.ensureLayoutResolved(dest_ty, src, .init);
86028056 _ = try sema.checkIntType(block, operand_src, operand_ty);
86038057
8604 if (try sema.resolveValue(operand)) |int_val| {
8058 if (sema.resolveValue(operand)) |int_val| {
86058059 if (dest_ty.isNonexhaustiveEnum(zcu)) {
86068060 const int_tag_ty = dest_ty.intTagType(zcu);
8607 if (try sema.intFitsInType(int_val, int_tag_ty, null)) {
8061 if (int_val.intFitsInType(int_tag_ty, null, zcu)) {
86088062 return Air.internedToRef((try pt.getCoerced(int_val, dest_ty)).toIntern());
86098063 }
86108064 return sema.fail(block, src, "int value '{f}' out of range of non-exhaustive enum '{f}'", .{
......@@ -8626,19 +8080,15 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
86268080 return sema.failWithNeededComptime(block, operand_src, .{ .simple = .casted_to_comptime_enum });
86278081 }
86288082
8629 if (try sema.typeHasOnePossibleValue(dest_ty)) |opv| {
8083 if (try dest_ty.onePossibleValue(pt)) |opv| {
86308084 if (block.wantSafety()) {
86318085 // The operand is runtime-known but the result is comptime-known. In
86328086 // this case we still need a safety check.
8633 const expect_int_val = switch (zcu.intern_pool.indexToKey(opv.toIntern())) {
8634 .enum_tag => |enum_tag| enum_tag.int,
8635 else => unreachable,
8636 };
8637 const expect_int_coerced = try pt.getCoerced(.fromInterned(expect_int_val), operand_ty);
8638 const ok = try block.addBinOp(.cmp_eq, operand, Air.internedToRef(expect_int_coerced.toIntern()));
8087 const expect_int = try pt.getCoerced(opv.intFromEnum(zcu), operand_ty);
8088 const ok = try block.addBinOp(.cmp_eq, operand, .fromValue(expect_int));
86398089 try sema.addSafetyCheck(block, src, ok, .invalid_enum_value);
86408090 }
8641 return Air.internedToRef(opv.toIntern());
8091 return .fromValue(opv);
86428092 }
86438093
86448094 try sema.requireRuntimeBlock(block, src, operand_src);
......@@ -8660,12 +8110,17 @@ fn zirOptionalPayloadPtr(
86608110 defer tracy.end();
86618111
86628112 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
8663 const optional_ptr = try sema.resolveInst(inst_data.operand);
8113 const optional_ptr = sema.resolveInst(inst_data.operand);
86648114 const src = block.nodeOffset(inst_data.src_node);
86658115
8116 const ptr_ty = sema.typeOf(optional_ptr);
8117 assert(ptr_ty.zigTypeTag(sema.pt.zcu) == .pointer);
8118 try sema.ensureLayoutResolved(ptr_ty.childType(sema.pt.zcu), src, .ptr_access);
8119
86668120 return sema.analyzeOptionalPayloadPtr(block, src, optional_ptr, safety_check, false);
86678121}
86688122
8123/// Asserts that the layout of the pointer child type is already resolved.
86698124fn analyzeOptionalPayloadPtr(
86708125 sema: *Sema,
86718126 block: *Block,
......@@ -8680,12 +8135,13 @@ fn analyzeOptionalPayloadPtr(
86808135 assert(optional_ptr_ty.zigTypeTag(zcu) == .pointer);
86818136
86828137 const opt_type = optional_ptr_ty.childType(zcu);
8138 opt_type.assertHasLayout(zcu);
86838139 if (opt_type.zigTypeTag(zcu) != .optional) {
86848140 return sema.failWithExpectedOptionalType(block, src, opt_type);
86858141 }
86868142
86878143 const child_type = opt_type.optionalChild(zcu);
8688 const child_pointer = try pt.ptrTypeSema(.{
8144 const child_pointer = try pt.ptrType(.{
86898145 .child = child_type.toIntern(),
86908146 .flags = .{
86918147 .is_const = optional_ptr_ty.isConstPtr(zcu),
......@@ -8698,7 +8154,7 @@ fn analyzeOptionalPayloadPtr(
86988154 if (sema.isComptimeMutablePtr(ptr_val)) {
86998155 // Set the optional to non-null at comptime.
87008156 // If the payload is OPV, we must use that value instead of undef.
8701 const payload_val = try sema.typeHasOnePossibleValue(child_type) orelse try pt.undefValue(child_type);
8157 const payload_val = try child_type.onePossibleValue(pt) orelse try pt.undefValue(child_type);
87028158 const opt_val = try pt.intern(.{ .opt = .{
87038159 .ty = opt_type.toIntern(),
87048160 .val = payload_val.toIntern(),
......@@ -8748,33 +8204,27 @@ fn zirOptionalPayload(
87488204 const zcu = pt.zcu;
87498205 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
87508206 const src = block.nodeOffset(inst_data.src_node);
8751 const operand = try sema.resolveInst(inst_data.operand);
8207 const operand = sema.resolveInst(inst_data.operand);
87528208 const operand_ty = sema.typeOf(operand);
87538209 const result_ty = switch (operand_ty.zigTypeTag(zcu)) {
87548210 .optional => operand_ty.optionalChild(zcu),
8755 .pointer => t: {
8756 if (operand_ty.ptrSize(zcu) != .c) {
8757 return sema.failWithExpectedOptionalType(block, src, operand_ty);
8758 }
8759 // TODO https://github.com/ziglang/zig/issues/6597
8760 if (true) break :t operand_ty;
8761 const ptr_info = operand_ty.ptrInfo(zcu);
8762 break :t try pt.ptrTypeSema(.{
8763 .child = ptr_info.child,
8764 .flags = .{
8765 .alignment = ptr_info.flags.alignment,
8766 .is_const = ptr_info.flags.is_const,
8767 .is_volatile = ptr_info.flags.is_volatile,
8768 .is_allowzero = ptr_info.flags.is_allowzero,
8769 .address_space = ptr_info.flags.address_space,
8770 },
8771 });
8211 // TODO: https://github.com/ziglang/zig/issues/6597 will eliminate this branch so that we only need to handle optionals.
8212 .pointer => switch (operand_ty.ptrSize(zcu)) {
8213 .c => operand_ty, // if `ptr` is a `[*c]T`, then `ptr.?` is also a `[*c]T`
8214 .one, .many, .slice => return sema.failWithExpectedOptionalType(block, src, operand_ty),
87728215 },
87738216 else => return sema.failWithExpectedOptionalType(block, src, operand_ty),
87748217 };
87758218
8776 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
8777 if (val.optionalValue(zcu)) |payload| return Air.internedToRef(payload.toIntern());
8219 ct: {
8220 if (try sema.resolveDefinedValue(block, src, operand)) |val| {
8221 if (val.optionalValue(zcu)) |payload| return .fromValue(payload); // comptime-known payload
8222 } else if (try sema.resolveIsNullFromType(block, src, operand_ty)) |is_null| {
8223 if (!is_null) break :ct; // fully runtime-known
8224 } else {
8225 break :ct; // fully runtime-known
8226 }
8227 // Comptime-known to be `null`.
87788228 if (block.isComptime()) return sema.fail(block, src, "unable to unwrap null", .{});
87798229 if (safety_check and block.wantSafety()) {
87808230 try sema.safetyPanic(block, src, .unwrap_null);
......@@ -8784,11 +8234,14 @@ fn zirOptionalPayload(
87848234 return .unreachable_value;
87858235 }
87868236
8787 try sema.requireRuntimeBlock(block, src, null);
87888237 if (safety_check and block.wantSafety()) {
87898238 const is_non_null = try block.addUnOp(.is_non_null, operand);
87908239 try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null);
87918240 }
8241
8242 // If the payload is OPV, we need the safety check but have a comptime-known result.
8243 if (try result_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
8244
87928245 return block.addTyOp(.optional_payload, result_ty, operand);
87938246}
87948247
......@@ -8805,7 +8258,7 @@ fn zirErrUnionPayload(
88058258 const zcu = pt.zcu;
88068259 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
88078260 const src = block.nodeOffset(inst_data.src_node);
8808 const operand = try sema.resolveInst(inst_data.operand);
8261 const operand = sema.resolveInst(inst_data.operand);
88098262 const operand_src = src;
88108263 const err_union_ty = sema.typeOf(operand);
88118264 if (err_union_ty.zigTypeTag(zcu) != .error_union) {
......@@ -8844,8 +8297,8 @@ fn analyzeErrUnionPayload(
88448297 try sema.addSafetyCheckUnwrapError(block, src, operand, .unwrap_errunion_err, .is_non_err);
88458298 }
88468299
8847 if (try sema.typeHasOnePossibleValue(payload_ty)) |payload_only_value| {
8848 return Air.internedToRef(payload_only_value.toIntern());
8300 if (try payload_ty.onePossibleValue(pt)) |payload_opv| {
8301 return .fromValue(payload_opv);
88498302 }
88508303
88518304 return block.addTyOp(.unwrap_errunion_payload, payload_ty, operand);
......@@ -8861,12 +8314,17 @@ fn zirErrUnionPayloadPtr(
88618314 defer tracy.end();
88628315
88638316 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
8864 const operand = try sema.resolveInst(inst_data.operand);
8317 const operand = sema.resolveInst(inst_data.operand);
88658318 const src = block.nodeOffset(inst_data.src_node);
88668319
8320 const ptr_ty = sema.typeOf(operand);
8321 assert(ptr_ty.zigTypeTag(sema.pt.zcu) == .pointer);
8322 try sema.ensureLayoutResolved(ptr_ty.childType(sema.pt.zcu), src, .ptr_access);
8323
88678324 return sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false);
88688325}
88698326
8327/// Asserts that the layout of the pointer child type is already resolved.
88708328fn analyzeErrUnionPayloadPtr(
88718329 sema: *Sema,
88728330 block: *Block,
......@@ -8887,8 +8345,9 @@ fn analyzeErrUnionPayloadPtr(
88878345 }
88888346
88898347 const err_union_ty = operand_ty.childType(zcu);
8348 err_union_ty.assertHasLayout(zcu);
88908349 const payload_ty = err_union_ty.errorUnionPayload(zcu);
8891 const operand_pointer_ty = try pt.ptrTypeSema(.{
8350 const operand_pointer_ty = try pt.ptrType(.{
88928351 .child = payload_ty.toIntern(),
88938352 .flags = .{
88948353 .is_const = operand_ty.isConstPtr(zcu),
......@@ -8901,7 +8360,7 @@ fn analyzeErrUnionPayloadPtr(
89018360 if (sema.isComptimeMutablePtr(ptr_val)) {
89028361 // Set the error union to non-error at comptime.
89038362 // If the payload is OPV, we must use that value instead of undef.
8904 const payload_val = try sema.typeHasOnePossibleValue(payload_ty) orelse try pt.undefValue(payload_ty);
8363 const payload_val = try payload_ty.onePossibleValue(pt) orelse try pt.undefValue(payload_ty);
89058364 const eu_val = try pt.intern(.{ .error_union = .{
89068365 .ty = err_union_ty.toIntern(),
89078366 .val = .{ .payload = payload_val.toIntern() },
......@@ -8948,7 +8407,7 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
89488407
89498408 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
89508409 const src = block.nodeOffset(inst_data.src_node);
8951 const operand = try sema.resolveInst(inst_data.operand);
8410 const operand = sema.resolveInst(inst_data.operand);
89528411 return sema.analyzeErrUnionCode(block, src, operand);
89538412}
89548413
......@@ -8984,7 +8443,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
89848443
89858444 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
89868445 const src = block.nodeOffset(inst_data.src_node);
8987 const operand = try sema.resolveInst(inst_data.operand);
8446 const operand = sema.resolveInst(inst_data.operand);
89888447 return sema.analyzeErrUnionCodePtr(block, src, operand);
89898448}
89908449
......@@ -9302,11 +8761,12 @@ fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc:
93028761 }
93038762}
93048763
9305fn checkParamTypeCommon(
8764fn checkParamType(
93068765 sema: *Sema,
93078766 block: *Block,
93088767 param_idx: u32,
93098768 param_ty: Type,
8769 param_is_comptime: bool,
93108770 param_is_noalias: bool,
93118771 param_src: LazySrcLoc,
93128772 cc: std.builtin.CallingConvention,
......@@ -9321,29 +8781,22 @@ fn checkParamTypeCommon(
93218781 opaque_str, param_ty.fmt(pt),
93228782 });
93238783 }
9324 if (!param_ty.isGenericPoison() and
9325 !target_util.fnCallConvAllowsZigTypes(cc) and
9326 !try sema.validateExternType(param_ty, .param_ty))
9327 {
9328 return sema.failWithOwnedErrorMsg(block, msg: {
9329 const msg = try sema.errMsg(param_src, "parameter of type '{f}' not allowed in function with calling convention '{s}'", .{
9330 param_ty.fmt(pt), @tagName(cc),
9331 });
9332 errdefer msg.destroy(sema.gpa);
9333
9334 try sema.explainWhyTypeIsNotExtern(msg, param_src, param_ty, .param_ty);
9335
9336 try sema.addDeclaredHereNote(msg, param_ty);
9337 break :msg msg;
9338 });
8784 if (!target_util.fnCallConvAllowsZigTypes(cc)) {
8785 if (param_is_comptime) {
8786 return sema.fail(block, param_src, "comptime parameters not allowed in function with calling convention '{t}'", .{cc});
8787 }
8788 if (param_ty.isGenericPoison()) {
8789 return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{t}'", .{cc});
8790 }
8791 // The `validateExtern` check happens later, in `validateResolvedFuncType`.
93398792 }
93408793 switch (cc) {
93418794 .x86_64_interrupt, .x86_interrupt => {
93428795 const err_code_size = target.ptrBitWidth();
93438796 switch (param_idx) {
9344 0 => if (param_ty.zigTypeTag(zcu) != .pointer) return sema.fail(block, param_src, "first parameter of function with '{s}' calling convention must be a pointer type", .{@tagName(cc)}),
9345 1 => if (param_ty.bitSize(zcu) != err_code_size) return sema.fail(block, param_src, "second parameter of function with '{s}' calling convention must be a {d}-bit integer", .{ @tagName(cc), err_code_size }),
9346 else => return sema.fail(block, param_src, "'{s}' calling convention supports up to 2 parameters, found {d}", .{ @tagName(cc), param_idx + 1 }),
8797 0 => if (param_ty.zigTypeTag(zcu) != .pointer) return sema.fail(block, param_src, "first parameter of function with '{t}' calling convention must be a pointer type", .{cc}),
8798 1 => if (param_ty.bitSize(zcu) != err_code_size) return sema.fail(block, param_src, "second parameter of function with '{t}' calling convention must be a {d}-bit integer", .{ cc, err_code_size }),
8799 else => return sema.fail(block, param_src, "'{t}' calling convention supports up to 2 parameters, found {d}", .{ cc, param_idx + 1 }),
93478800 }
93488801 },
93498802 .arc_interrupt,
......@@ -9359,7 +8812,7 @@ fn checkParamTypeCommon(
93598812 .m68k_interrupt,
93608813 .msp430_interrupt,
93618814 .avr_signal,
9362 => return sema.fail(block, param_src, "parameters are not allowed with '{s}' calling convention", .{@tagName(cc)}),
8815 => return sema.fail(block, param_src, "parameters are not allowed with '{t}' calling convention", .{cc}),
93638816 else => {},
93648817 }
93658818 if (param_is_noalias and !param_ty.isGenericPoison() and !param_ty.isPtrAtRuntime(zcu) and !param_ty.isSliceAtRuntime(zcu)) {
......@@ -9367,7 +8820,7 @@ fn checkParamTypeCommon(
93678820 }
93688821}
93698822
9370fn checkReturnTypeAndCallConvCommon(
8823fn checkReturnTypeAndCallConv(
93718824 sema: *Sema,
93728825 block: *Block,
93738826 bare_ret_ty: Type,
......@@ -9381,7 +8834,6 @@ fn checkReturnTypeAndCallConvCommon(
93818834) CompileError!void {
93828835 const pt = sema.pt;
93838836 const zcu = pt.zcu;
9384 const gpa = zcu.gpa;
93858837 if (opt_varargs_src) |varargs_src| {
93868838 try sema.checkCallConvSupportsVarArgs(block, varargs_src, @"callconv");
93878839 }
......@@ -9395,21 +8847,14 @@ fn checkReturnTypeAndCallConvCommon(
93958847 opaque_str, ies_ret_ty_prefix, bare_ret_ty.fmt(pt),
93968848 });
93978849 }
9398 if (!bare_ret_ty.isGenericPoison() and
9399 !target_util.fnCallConvAllowsZigTypes(@"callconv") and
9400 (inferred_error_set or !try sema.validateExternType(bare_ret_ty, .ret_ty)))
9401 {
9402 return sema.failWithOwnedErrorMsg(block, msg: {
9403 const msg = try sema.errMsg(ret_ty_src, "return type '{s}{f}' not allowed in function with calling convention '{s}'", .{
9404 ies_ret_ty_prefix, bare_ret_ty.fmt(pt), @tagName(@"callconv"),
9405 });
9406 errdefer msg.destroy(gpa);
9407 if (!inferred_error_set) {
9408 try sema.explainWhyTypeIsNotExtern(msg, ret_ty_src, bare_ret_ty, .ret_ty);
9409 try sema.addDeclaredHereNote(msg, bare_ret_ty);
9410 }
9411 break :msg msg;
9412 });
8850 if (!target_util.fnCallConvAllowsZigTypes(@"callconv")) {
8851 if (inferred_error_set) {
8852 return sema.fail(block, ret_ty_src, "return type '!{f}' not allowed in function with calling convention '{t}'", .{ bare_ret_ty.fmt(pt), @"callconv" });
8853 }
8854 if (bare_ret_ty.isGenericPoison()) {
8855 return sema.fail(block, ret_ty_src, "generic return type not allowed in function with calling convention '{t}'", .{@"callconv"});
8856 }
8857 // The `validateExtern` check happens later, in `validateResolvedFuncType`.
94138858 }
94148859 validate_incoming_stack_align: {
94158860 const a: u64 = switch (@"callconv") {
......@@ -9444,7 +8889,7 @@ fn checkReturnTypeAndCallConvCommon(
94448889 else => false,
94458890 };
94468891 if (!ret_ok) {
9447 return sema.fail(block, ret_ty_src, "function with calling convention '{s}' must return 'void' or 'noreturn'", .{@tagName(@"callconv")});
8892 return sema.fail(block, ret_ty_src, "function with calling convention '{t}' must return 'void' or 'noreturn'", .{@"callconv"});
94488893 }
94498894 },
94508895 .@"inline" => if (is_noinline) {
......@@ -9465,18 +8910,76 @@ fn checkReturnTypeAndCallConvCommon(
94658910 }
94668911 }
94678912 };
9468 return sema.fail(block, callconv_src, "calling convention '{s}' only available on architectures {f}", .{
9469 @tagName(@"callconv"),
9470 ArchListFormatter{ .archs = allowed_archs },
8913 return sema.fail(block, callconv_src, "calling convention '{t}' only available on architectures {f}", .{
8914 @"callconv", ArchListFormatter{ .archs = allowed_archs },
94718915 });
94728916 },
9473 .bad_backend => |bad_backend| return sema.fail(block, callconv_src, "calling convention '{s}' not supported by compiler backend '{s}'", .{
9474 @tagName(@"callconv"),
9475 @tagName(bad_backend),
8917 .bad_backend => |bad_backend| return sema.fail(block, callconv_src, "calling convention '{t}' not supported by compiler backend '{t}'", .{
8918 @"callconv", bad_backend,
94768919 }),
94778920 }
94788921}
94798922
8923/// To avoid forcing type layout resolution too quickly, some validation of function types cannot be
8924/// performed when the type is first constructed, and instead must happen when either (a) a function
8925/// with that type is declared, or (b) a function with that type is called. That validation is
8926/// handled here.
8927///
8928/// Asserts that all parameter types and return types have their layout fully resolved.
8929fn validateResolvedFuncType(
8930 sema: *Sema,
8931 block: *Block,
8932 @"callconv": std.builtin.CallingConvention,
8933 param_types: []const InternPool.Index,
8934 ret_ty: Type,
8935 src: LazySrcLoc,
8936 maybe_func_decl_inst: ?InternPool.TrackedInst.Index,
8937) SemaError!void {
8938 const pt = sema.pt;
8939 const zcu = pt.zcu;
8940 const gpa = zcu.comp.gpa;
8941 if (!target_util.fnCallConvAllowsZigTypes(@"callconv")) {
8942 // Check that all parameter types are extern-compatible.
8943 for (param_types, 0..) |param_ty_ip, param_index| {
8944 const param_ty: Type = .fromInterned(param_ty_ip);
8945 if (!param_ty.validateExtern(.param_ty, zcu)) {
8946 const param_src: LazySrcLoc = if (maybe_func_decl_inst) |inst| .{
8947 .base_node_inst = inst,
8948 .offset = .{ .fn_proto_param = .{
8949 .fn_proto_node_offset = .zero,
8950 .param_index = @intCast(param_index),
8951 } },
8952 } else src;
8953 return sema.failWithOwnedErrorMsg(block, msg: {
8954 const msg = try sema.errMsg(param_src, "parameter of type '{f}' not allowed in function with calling convention '{t}'", .{
8955 param_ty.fmt(pt), @"callconv",
8956 });
8957 errdefer msg.destroy(gpa);
8958 try sema.explainWhyTypeIsNotExtern(msg, param_src, param_ty, .param_ty);
8959 try sema.addDeclaredHereNote(msg, param_ty);
8960 break :msg msg;
8961 });
8962 }
8963 }
8964 // Check that the return type is extern-compatible.
8965 if (!ret_ty.validateExtern(.ret_ty, zcu)) {
8966 const ret_ty_src: LazySrcLoc = if (maybe_func_decl_inst) |inst| .{
8967 .base_node_inst = inst,
8968 .offset = .{ .node_offset_fn_type_ret_ty = .zero },
8969 } else src;
8970 return sema.failWithOwnedErrorMsg(block, msg: {
8971 const msg = try sema.errMsg(ret_ty_src, "return type '{f}' not allowed in function with calling convention '{t}'", .{
8972 ret_ty.fmt(pt), @"callconv",
8973 });
8974 errdefer msg.destroy(gpa);
8975 try sema.explainWhyTypeIsNotExtern(msg, ret_ty_src, ret_ty, .ret_ty);
8976 try sema.addDeclaredHereNote(msg, ret_ty);
8977 break :msg msg;
8978 });
8979 }
8980 }
8981}
8982
94808983fn callConvIsCallable(cc: std.builtin.CallingConvention.Tag) bool {
94818984 return switch (cc) {
94828985 .naked,
......@@ -9569,12 +9072,9 @@ fn funcCommon(
95699072 const io = comp.io;
95709073 const ip = &zcu.intern_pool;
95719074
9075 const src = block.nodeOffset(src_node_offset);
95729076 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset });
95739077 const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset });
9574 const func_src = block.nodeOffset(src_node_offset);
9575
9576 const ret_ty_requires_comptime = try bare_return_type.comptimeOnlySema(pt);
9577 var is_generic = bare_return_type.isGenericPoison() or ret_ty_requires_comptime;
95789078
95799079 var comptime_bits: u32 = 0;
95809080 for (block.params.items(.ty), block.params.items(.is_comptime), 0..) |param_ty_ip, param_is_comptime, i| {
......@@ -9587,49 +9087,21 @@ fn funcCommon(
95879087 .fn_proto_node_offset = src_node_offset,
95889088 .param_index = @intCast(i),
95899089 } });
9590 const param_ty_comptime = try param_ty.comptimeOnlySema(pt);
9591 const param_ty_generic = param_ty.isGenericPoison();
9592 if (param_is_comptime or param_ty_comptime or param_ty_generic) {
9593 is_generic = true;
9594 }
95959090 if (param_is_comptime) {
95969091 comptime_bits |= @as(u32, 1) << @intCast(i); // TODO: handle cast error
95979092 }
9598 if (param_is_comptime and !target_util.fnCallConvAllowsZigTypes(cc)) {
9599 return sema.fail(block, param_src, "comptime parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)});
9600 }
9601 if (param_ty_generic and !target_util.fnCallConvAllowsZigTypes(cc)) {
9602 return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)});
9603 }
9604 try sema.checkParamTypeCommon(
9093 try sema.checkParamType(
96059094 block,
96069095 @intCast(i),
96079096 param_ty,
9097 param_is_comptime,
96089098 is_noalias,
96099099 param_src,
96109100 cc,
96119101 );
9612 if (param_ty_comptime and !param_is_comptime and has_body and !block.isComptime()) {
9613 const msg = msg: {
9614 const msg = try sema.errMsg(param_src, "parameter of type '{f}' must be declared comptime", .{
9615 param_ty.fmt(pt),
9616 });
9617 errdefer msg.destroy(sema.gpa);
9618
9619 try sema.explainWhyTypeIsComptime(msg, param_src, param_ty);
9620
9621 try sema.addDeclaredHereNote(msg, param_ty);
9622 break :msg msg;
9623 };
9624 return sema.failWithOwnedErrorMsg(block, msg);
9625 }
9626 }
9627
9628 if (var_args and is_generic) {
9629 return sema.fail(block, func_src, "generic function cannot be variadic", .{});
96309102 }
96319103
9632 try sema.checkReturnTypeAndCallConvCommon(
9104 try sema.checkReturnTypeAndCallConv(
96339105 block,
96349106 bare_return_type,
96359107 ret_ty_src,
......@@ -9643,48 +9115,28 @@ fn funcCommon(
96439115 is_noinline,
96449116 );
96459117
9646 // If the return type is comptime-only but not dependent on parameters then
9647 // all parameter types also need to be comptime.
9648 if (has_body and ret_ty_requires_comptime and !block.isComptime()) comptime_check: {
9649 for (block.params.items(.is_comptime)) |is_comptime| {
9650 if (!is_comptime) break;
9651 } else break :comptime_check;
9652 const ies_ret_ty_prefix: []const u8 = if (inferred_error_set) "!" else "";
9653 const msg = try sema.errMsg(
9654 ret_ty_src,
9655 "function with comptime-only return type '{s}{f}' requires all parameters to be comptime",
9656 .{ ies_ret_ty_prefix, bare_return_type.fmt(pt) },
9118 const param_types = block.params.items(.ty);
9119
9120 if (has_body) {
9121 for (param_types, 0..) |param_ty_ip, param_index| {
9122 const param_ty: Type = .fromInterned(param_ty_ip);
9123 const param_src = block.src(.{ .fn_proto_param = .{
9124 .fn_proto_node_offset = src_node_offset,
9125 .param_index = @intCast(param_index),
9126 } });
9127 try sema.ensureLayoutResolved(param_ty, param_src, .parameter);
9128 }
9129 try sema.ensureLayoutResolved(bare_return_type, ret_ty_src, .return_type);
9130 try sema.validateResolvedFuncType(
9131 block,
9132 cc,
9133 param_types,
9134 bare_return_type,
9135 src,
9136 ip.getNav(sema.owner.unwrap().nav_val).srcInst(ip),
96579137 );
9658 errdefer msg.destroy(sema.gpa);
9659 try sema.explainWhyTypeIsComptime(msg, ret_ty_src, bare_return_type);
9660
9661 const tags = sema.code.instructions.items(.tag);
9662 const data = sema.code.instructions.items(.data);
9663 const param_body = sema.code.getParamBody(func_inst);
9664 for (
9665 block.params.items(.is_comptime),
9666 block.params.items(.name),
9667 param_body[0..block.params.len],
9668 ) |is_comptime, name_nts, param_index| {
9669 if (!is_comptime) {
9670 const param_src = block.tokenOffset(switch (tags[@intFromEnum(param_index)]) {
9671 .param => data[@intFromEnum(param_index)].pl_tok.src_tok,
9672 .param_anytype => data[@intFromEnum(param_index)].str_tok.src_tok,
9673 else => unreachable,
9674 });
9675 const name = sema.code.nullTerminatedString(name_nts);
9676 if (name.len != 0) {
9677 try sema.errNote(param_src, msg, "param '{s}' is required to be comptime", .{name});
9678 } else {
9679 try sema.errNote(param_src, msg, "param is required to be comptime", .{});
9680 }
9681 }
9682 }
9683 return sema.failWithOwnedErrorMsg(block, msg);
96849138 }
96859139
9686 const param_types = block.params.items(.ty);
9687
96889140 if (inferred_error_set) {
96899141 assert(has_body);
96909142 return .fromIntern(try ip.getFuncDeclIes(gpa, io, pt.tid, .{
......@@ -9696,7 +9148,6 @@ fn funcCommon(
96969148 .bare_return_type = bare_return_type.toIntern(),
96979149 .cc = cc,
96989150 .is_var_args = var_args,
9699 .is_generic = is_generic,
97009151 .is_noinline = is_noinline,
97019152
97029153 .zir_body_inst = try block.trackZir(func_inst),
......@@ -9714,7 +9165,6 @@ fn funcCommon(
97149165 .return_type = bare_return_type.toIntern(),
97159166 .cc = cc,
97169167 .is_var_args = var_args,
9717 .is_generic = is_generic,
97189168 .is_noinline = is_noinline,
97199169 });
97209170
......@@ -9756,7 +9206,7 @@ fn zirParam(
97569206 }
97579207
97589208 const param_ty_inst = try sema.resolveInlineBody(block, body, inst);
9759 break :ty try sema.analyzeAsType(block, src, param_ty_inst);
9209 break :ty try sema.analyzeAsType(block, src, .fn_param_types, param_ty_inst);
97609210 };
97619211
97629212 try block.params.append(sema.arena, .{
......@@ -9812,7 +9262,7 @@ fn analyzeAs(
98129262) CompileError!Air.Inst.Ref {
98139263 const pt = sema.pt;
98149264 const zcu = pt.zcu;
9815 const operand = try sema.resolveInst(zir_operand);
9265 const operand = sema.resolveInst(zir_operand);
98169266 const dest_ty = try sema.resolveTypeOrPoison(block, src, zir_dest_type) orelse return operand;
98179267 switch (dest_ty.zigTypeTag(zcu)) {
98189268 .@"opaque" => return sema.fail(block, src, "cannot cast to opaque type '{f}'", .{dest_ty.fmt(pt)}),
......@@ -9838,32 +9288,23 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
98389288 const zcu = pt.zcu;
98399289 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
98409290 const ptr_src = block.builtinCallArgSrc(inst_data.src_node, 0);
9841 const operand = try sema.resolveInst(inst_data.operand);
9291 const operand = sema.resolveInst(inst_data.operand);
98429292 const operand_ty = sema.typeOf(operand);
98439293 const ptr_ty = operand_ty.scalarType(zcu);
98449294 const is_vector = operand_ty.zigTypeTag(zcu) == .vector;
98459295 if (!ptr_ty.isPtrAtRuntime(zcu)) {
98469296 return sema.fail(block, ptr_src, "expected pointer, found '{f}'", .{ptr_ty.fmt(pt)});
98479297 }
9848 const pointee_ty = ptr_ty.childType(zcu);
9849 if (try ptr_ty.comptimeOnlySema(pt)) {
9850 const msg = msg: {
9851 const msg = try sema.errMsg(ptr_src, "comptime-only type '{f}' has no pointer address", .{pointee_ty.fmt(pt)});
9852 errdefer msg.destroy(sema.gpa);
9853 try sema.explainWhyTypeIsComptime(msg, ptr_src, pointee_ty);
9854 break :msg msg;
9855 };
9856 return sema.failWithOwnedErrorMsg(block, msg);
9857 }
9298
98589299 const len = if (is_vector) operand_ty.vectorLen(zcu) else undefined;
98599300 const dest_ty: Type = if (is_vector) try pt.vectorType(.{ .child = .usize_type, .len = len }) else .usize;
98609301
9861 if (try sema.resolveValue(operand)) |operand_val| ct: {
9302 if (sema.resolveValue(operand)) |operand_val| ct: {
98629303 if (!is_vector) {
98639304 if (operand_val.isUndef(zcu)) {
98649305 return .undef_usize;
98659306 }
9866 const addr = try operand_val.getUnsignedIntSema(pt) orelse {
9307 const addr = operand_val.getUnsignedInt(zcu) orelse {
98679308 // Wasn't an integer pointer. This is a runtime operation.
98689309 break :ct;
98699310 };
......@@ -9879,7 +9320,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
98799320 new_elem.* = .undef_usize;
98809321 continue;
98819322 }
9882 const addr = try ptr_val.getUnsignedIntSema(pt) orelse {
9323 const addr = ptr_val.getUnsignedInt(zcu) orelse {
98839324 // A vector element wasn't an integer pointer. This is a runtime operation.
98849325 break :ct;
98859326 };
......@@ -9917,7 +9358,7 @@ fn zirFieldPtrLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
99179358 sema.code.nullTerminatedString(extra.field_name_start),
99189359 .no_embedded_nulls,
99199360 );
9920 const object_ptr = try sema.resolveInst(extra.lhs);
9361 const object_ptr = sema.resolveInst(extra.lhs);
99219362 return fieldPtrLoad(sema, block, src, object_ptr, field_name, field_name_src);
99229363}
99239364
......@@ -9942,7 +9383,7 @@ fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
99429383 sema.code.nullTerminatedString(extra.field_name_start),
99439384 .no_embedded_nulls,
99449385 );
9945 const object_ptr = try sema.resolveInst(extra.lhs);
9386 const object_ptr = sema.resolveInst(extra.lhs);
99469387 return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src, false);
99479388}
99489389
......@@ -9967,7 +9408,7 @@ fn zirStructInitFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi
99679408 sema.code.nullTerminatedString(extra.field_name_start),
99689409 .no_embedded_nulls,
99699410 );
9970 const object_ptr = try sema.resolveInst(extra.lhs);
9411 const object_ptr = sema.resolveInst(extra.lhs);
99719412 const struct_ty = sema.typeOf(object_ptr).childType(zcu);
99729413 switch (struct_ty.zigTypeTag(zcu)) {
99739414 .@"struct", .@"union" => {
......@@ -9987,7 +9428,7 @@ fn zirFieldPtrNamedLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
99879428 const src = block.nodeOffset(inst_data.src_node);
99889429 const field_name_src = block.builtinCallArgSrc(inst_data.src_node, 1);
99899430 const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;
9990 const object_ptr = try sema.resolveInst(extra.lhs);
9431 const object_ptr = sema.resolveInst(extra.lhs);
99919432 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{ .simple = .field_name });
99929433 return fieldPtrLoad(sema, block, src, object_ptr, field_name, field_name_src);
99939434}
......@@ -10000,7 +9441,7 @@ fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
100009441 const src = block.nodeOffset(inst_data.src_node);
100019442 const field_name_src = block.builtinCallArgSrc(inst_data.src_node, 1);
100029443 const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;
10003 const object_ptr = try sema.resolveInst(extra.lhs);
9444 const object_ptr = sema.resolveInst(extra.lhs);
100049445 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{ .simple = .field_name });
100059446 return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src, false);
100069447}
......@@ -10015,7 +9456,7 @@ fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
100159456 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
100169457
100179458 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@intCast");
10018 const operand = try sema.resolveInst(extra.rhs);
9459 const operand = sema.resolveInst(extra.rhs);
100199460
100209461 return sema.intCast(block, block.nodeOffset(inst_data.src_node), dest_ty, src, operand, operand_src);
100219462}
......@@ -10044,7 +9485,7 @@ fn intCast(
100449485 try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, operand_ty, dest_ty_src, operand_src);
100459486 const is_vector = dest_ty.zigTypeTag(zcu) == .vector;
100469487
10047 if ((try sema.typeHasOnePossibleValue(dest_ty))) |opv| {
9488 if (try dest_ty.onePossibleValue(pt)) |opv| {
100489489 // requirement: intCast(u0, input) iff input == 0
100499490 if (block.wantSafety()) {
100509491 try sema.requireRuntimeBlock(block, src, operand_src);
......@@ -10090,7 +9531,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
100909531 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
100919532
100929533 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@bitCast");
10093 const operand = try sema.resolveInst(extra.rhs);
9534 const operand = sema.resolveInst(extra.rhs);
100949535 const operand_ty = sema.typeOf(operand);
100959536 switch (dest_ty.zigTypeTag(zcu)) {
100969537 .@"anyframe",
......@@ -10258,7 +9699,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
102589699 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@floatCast");
102599700 const dest_scalar_ty = dest_ty.scalarType(zcu);
102609701
10261 const operand = try sema.resolveInst(extra.rhs);
9702 const operand = sema.resolveInst(extra.rhs);
102629703 const operand_ty = sema.typeOf(operand);
102639704 const operand_scalar_ty = operand_ty.scalarType(zcu);
102649705
......@@ -10287,7 +9728,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
102879728 ),
102889729 }
102899730
10290 if (try sema.resolveValue(operand)) |operand_val| {
9731 if (sema.resolveValue(operand)) |operand_val| {
102919732 if (!is_vector) {
102929733 return Air.internedToRef((try operand_val.floatCast(dest_ty, pt)).toIntern());
102939734 }
......@@ -10319,8 +9760,8 @@ fn zirElemVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
103199760 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
103209761 const src = block.nodeOffset(inst_data.src_node);
103219762 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
10322 const array = try sema.resolveInst(extra.lhs);
10323 const elem_index = try sema.resolveInst(extra.rhs);
9763 const array = sema.resolveInst(extra.lhs);
9764 const elem_index = sema.resolveInst(extra.rhs);
103249765 return sema.elemVal(block, src, array, elem_index, src, false);
103259766}
103269767
......@@ -10332,8 +9773,8 @@ fn zirElemPtrLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
103329773 const src = block.nodeOffset(inst_data.src_node);
103339774 const elem_index_src = block.src(.{ .node_offset_array_access_index = inst_data.src_node });
103349775 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
10335 const array_ptr = try sema.resolveInst(extra.lhs);
10336 const uncoerced_elem_index = try sema.resolveInst(extra.rhs);
9776 const array_ptr = sema.resolveInst(extra.lhs);
9777 const uncoerced_elem_index = sema.resolveInst(extra.rhs);
103379778 if (try sema.resolveDefinedValue(block, src, array_ptr)) |array_ptr_val| {
103389779 const array_ptr_ty = sema.typeOf(array_ptr);
103399780 if (try sema.pointerDeref(block, src, array_ptr_val, array_ptr_ty)) |array_val| {
......@@ -10351,7 +9792,7 @@ fn zirElemValImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
103519792 defer tracy.end();
103529793
103539794 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].elem_val_imm;
10354 const array = try sema.resolveInst(inst_data.operand);
9795 const array = sema.resolveInst(inst_data.operand);
103559796 const elem_index = try sema.pt.intRef(.usize, inst_data.idx);
103569797 return sema.elemVal(block, LazySrcLoc.unneeded, array, elem_index, LazySrcLoc.unneeded, false);
103579798}
......@@ -10365,8 +9806,8 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
103659806 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
103669807 const src = block.nodeOffset(inst_data.src_node);
103679808 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
10368 const array_ptr = try sema.resolveInst(extra.lhs);
10369 const elem_index = try sema.resolveInst(extra.rhs);
9809 const array_ptr = sema.resolveInst(extra.lhs);
9810 const elem_index = sema.resolveInst(extra.rhs);
103709811 const indexable_ty = sema.typeOf(array_ptr);
103719812 if (indexable_ty.zigTypeTag(zcu) != .pointer) {
103729813 const capture_src = block.src(.{ .for_capture_from_input = inst_data.src_node });
......@@ -10382,6 +9823,8 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
103829823 };
103839824 return sema.failWithOwnedErrorMsg(block, msg);
103849825 }
9826 try sema.checkIndexable(block, src, indexable_ty);
9827 try sema.ensureLayoutResolved(indexable_ty.childType(zcu), src, .ptr_access);
103859828 return sema.elemPtrOneLayerOnly(block, src, array_ptr, elem_index, src, false, false);
103869829}
103879830
......@@ -10393,8 +9836,8 @@ fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
103939836 const src = block.nodeOffset(inst_data.src_node);
103949837 const elem_index_src = block.src(.{ .node_offset_array_access_index = inst_data.src_node });
103959838 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
10396 const array_ptr = try sema.resolveInst(extra.lhs);
10397 const uncoerced_elem_index = try sema.resolveInst(extra.rhs);
9839 const array_ptr = sema.resolveInst(extra.lhs);
9840 const uncoerced_elem_index = sema.resolveInst(extra.rhs);
103989841 const elem_index = try sema.coerce(block, .usize, uncoerced_elem_index, elem_index_src);
103999842 return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src, false, true);
104009843}
......@@ -10408,7 +9851,7 @@ fn zirArrayInitElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile
104089851 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
104099852 const src = block.nodeOffset(inst_data.src_node);
104109853 const extra = sema.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data;
10411 const array_ptr = try sema.resolveInst(extra.ptr);
9854 const array_ptr = sema.resolveInst(extra.ptr);
104129855 const elem_index = try pt.intRef(.usize, extra.index);
104139856 const array_ty = sema.typeOf(array_ptr).childType(zcu);
104149857 switch (array_ty.zigTypeTag(zcu)) {
......@@ -10427,8 +9870,8 @@ fn zirSliceStart(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
104279870 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
104289871 const src = block.nodeOffset(inst_data.src_node);
104299872 const extra = sema.code.extraData(Zir.Inst.SliceStart, inst_data.payload_index).data;
10430 const array_ptr = try sema.resolveInst(extra.lhs);
10431 const start = try sema.resolveInst(extra.start);
9873 const array_ptr = sema.resolveInst(extra.lhs);
9874 const start = sema.resolveInst(extra.start);
104329875 const ptr_src = block.src(.{ .node_offset_slice_ptr = inst_data.src_node });
104339876 const start_src = block.src(.{ .node_offset_slice_start = inst_data.src_node });
104349877 const end_src = block.src(.{ .node_offset_slice_end = inst_data.src_node });
......@@ -10443,9 +9886,9 @@ fn zirSliceEnd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
104439886 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
104449887 const src = block.nodeOffset(inst_data.src_node);
104459888 const extra = sema.code.extraData(Zir.Inst.SliceEnd, inst_data.payload_index).data;
10446 const array_ptr = try sema.resolveInst(extra.lhs);
10447 const start = try sema.resolveInst(extra.start);
10448 const end = try sema.resolveInst(extra.end);
9889 const array_ptr = sema.resolveInst(extra.lhs);
9890 const start = sema.resolveInst(extra.start);
9891 const end = sema.resolveInst(extra.end);
104499892 const ptr_src = block.src(.{ .node_offset_slice_ptr = inst_data.src_node });
104509893 const start_src = block.src(.{ .node_offset_slice_start = inst_data.src_node });
104519894 const end_src = block.src(.{ .node_offset_slice_end = inst_data.src_node });
......@@ -10461,10 +9904,10 @@ fn zirSliceSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
104619904 const src = block.nodeOffset(inst_data.src_node);
104629905 const sentinel_src = block.src(.{ .node_offset_slice_sentinel = inst_data.src_node });
104639906 const extra = sema.code.extraData(Zir.Inst.SliceSentinel, inst_data.payload_index).data;
10464 const array_ptr = try sema.resolveInst(extra.lhs);
10465 const start = try sema.resolveInst(extra.start);
10466 const end: Air.Inst.Ref = if (extra.end == .none) .none else try sema.resolveInst(extra.end);
10467 const sentinel = try sema.resolveInst(extra.sentinel);
9907 const array_ptr = sema.resolveInst(extra.lhs);
9908 const start = sema.resolveInst(extra.start);
9909 const end: Air.Inst.Ref = if (extra.end == .none) .none else sema.resolveInst(extra.end);
9910 const sentinel = sema.resolveInst(extra.sentinel);
104689911 const ptr_src = block.src(.{ .node_offset_slice_ptr = inst_data.src_node });
104699912 const start_src = block.src(.{ .node_offset_slice_start = inst_data.src_node });
104709913 const end_src = block.src(.{ .node_offset_slice_end = inst_data.src_node });
......@@ -10479,10 +9922,10 @@ fn zirSliceLength(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
104799922 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
104809923 const src = block.nodeOffset(inst_data.src_node);
104819924 const extra = sema.code.extraData(Zir.Inst.SliceLength, inst_data.payload_index).data;
10482 const array_ptr = try sema.resolveInst(extra.lhs);
10483 const start = try sema.resolveInst(extra.start);
10484 const len = try sema.resolveInst(extra.len);
10485 const sentinel = if (extra.sentinel == .none) .none else try sema.resolveInst(extra.sentinel);
9925 const array_ptr = sema.resolveInst(extra.lhs);
9926 const start = sema.resolveInst(extra.start);
9927 const len = sema.resolveInst(extra.len);
9928 const sentinel = if (extra.sentinel == .none) .none else sema.resolveInst(extra.sentinel);
104869929 const ptr_src = block.src(.{ .node_offset_slice_ptr = inst_data.src_node });
104879930 const start_src = block.src(.{ .node_offset_slice_start = extra.start_src_node_offset });
104889931 const end_src = block.src(.{ .node_offset_slice_end = inst_data.src_node });
......@@ -10510,7 +9953,7 @@ fn zirSliceSentinelTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
105109953 // This is like the logic in `analyzeSlice`; since we've evaluated the LHS as an lvalue, we will
105119954 // have a double pointer if it was already a pointer.
105129955
10513 const lhs_ptr_ty = sema.typeOf(try sema.resolveInst(inst_data.operand));
9956 const lhs_ptr_ty = sema.typeOf(sema.resolveInst(inst_data.operand));
105149957 const lhs_ty = switch (lhs_ptr_ty.zigTypeTag(zcu)) {
105159958 .pointer => lhs_ptr_ty.childType(zcu),
105169959 else => return sema.fail(block, ptr_src, "expected pointer, found '{f}'", .{lhs_ptr_ty.fmt(pt)}),
......@@ -10557,9 +10000,9 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
1055710000 var label: Block.Label = .{
1055810001 .zir_block = inst,
1055910002 .merges = .{
10560 .src_locs = .{},
10561 .results = .{},
10562 .br_list = .{},
10003 .src_locs = .empty,
10004 .results = .empty,
10005 .br_list = .empty,
1056310006 .block_inst = block_inst,
1056410007 },
1056510008 };
......@@ -10590,12 +10033,14 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
1059010033 // Lastly, we analyze the error prong(s) as a regular switch.
1059110034
1059210035 const raw_switch_operand, const non_err_cond, const non_err_hint = non_err: {
10593 const eu_maybe_ptr = try sema.resolveInst(zir_switch.main_operand);
10036 const eu_maybe_ptr = sema.resolveInst(zir_switch.main_operand);
1059410037 const err_union_ty: Type = err_union_ty: {
1059510038 const raw_operand_ty = sema.typeOf(eu_maybe_ptr);
1059610039 if (!non_err_case.operand_is_ref) break :err_union_ty raw_operand_ty;
1059710040 try sema.checkPtrOperand(block, operand_src, raw_operand_ty);
10598 break :err_union_ty raw_operand_ty.childType(zcu);
10041 const child_ty = raw_operand_ty.childType(zcu);
10042 try sema.ensureLayoutResolved(child_ty, operand_src, .ptr_access);
10043 break :err_union_ty child_ty;
1059910044 };
1060010045 if (err_union_ty.zigTypeTag(zcu) != .error_union) {
1060110046 return sema.fail(block, operand_src, "expected error union type, found '{f}'", .{
......@@ -10711,9 +10156,9 @@ fn zirSwitchBlock(
1071110156 var label: Block.Label = .{
1071210157 .zir_block = inst,
1071310158 .merges = .{
10714 .src_locs = .{},
10715 .results = .{},
10716 .br_list = .{},
10159 .src_locs = .empty,
10160 .results = .empty,
10161 .br_list = .empty,
1071710162 .block_inst = block_inst,
1071810163 },
1071910164 };
......@@ -10723,7 +10168,7 @@ fn zirSwitchBlock(
1072310168 defer child_block.instructions.deinit(sema.gpa);
1072410169 defer merges.deinit(sema.gpa);
1072510170
10726 const raw_operand = try sema.resolveInst(zir_switch.main_operand);
10171 const raw_operand = sema.resolveInst(zir_switch.main_operand);
1072710172 const validated_switch = try sema.validateSwitchBlock(block, raw_operand, operand_is_ref, inst, &zir_switch);
1072810173 const maybe_ref = try sema.analyzeSwitchBlock(block, &child_block, raw_operand, operand_is_ref, merges, inst, &zir_switch, &validated_switch);
1072910174 return maybe_ref orelse {
......@@ -10764,18 +10209,19 @@ fn analyzeSwitchBlock(
1076410209 .{ raw_operand, .none };
1076510210
1076610211 const operand_ty = sema.typeOf(val);
10767 const maybe_operand_opv = try sema.typeHasOnePossibleValue(operand_ty);
10212 operand_ty.assertHasLayout(zcu);
10213 const maybe_operand_opv = try operand_ty.onePossibleValue(pt);
1076810214 const init_cond: Air.Inst.Ref, const item_ty: Type = switch (operand_ty.zigTypeTag(zcu)) {
1076910215 .@"union" => tag: {
10770 const tag_ty = operand_ty.unionTagType(zcu).?;
10771 const tag_val = try sema.unionToTag(block, tag_ty, val, operand_src);
10772 break :tag .{ tag_val, tag_ty };
10216 const tag_val = try sema.unionToTag(block, val);
10217 break :tag .{ tag_val, sema.typeOf(tag_val) };
1077310218 },
1077410219 else => .{
1077510220 if (maybe_operand_opv) |operand_opv| .fromValue(operand_opv) else val,
1077610221 operand_ty,
1077710222 },
1077810223 };
10224 item_ty.assertHasLayout(zcu);
1077910225
1078010226 if (zir_switch.has_continue and !block.isComptime()) {
1078110227 const operand_alloc: Air.Inst.Ref = if (zir_switch.any_maybe_runtime_capture and
......@@ -10849,7 +10295,7 @@ fn analyzeSwitchBlock(
1084910295 if (extra.block_inst != switch_inst) return error.ComptimeBreak;
1085010296 // This is a `switch_continue` targeting this block. Change the operand and start over.
1085110297 const new_operand_src = child_block.nodeOffset(extra.operand_src_node.unwrap().?);
10852 const new_operand_uncoerced = try sema.resolveInst(break_inst.data.@"break".operand);
10298 const new_operand_uncoerced = sema.resolveInst(break_inst.data.@"break".operand);
1085310299 const new_operand = try sema.coerce(child_block, raw_operand_ty, new_operand_uncoerced, new_operand_src);
1085410300
1085510301 try sema.emitBackwardBranch(child_block, src);
......@@ -10860,7 +10306,7 @@ fn analyzeSwitchBlock(
1086010306 .{ new_operand, .none };
1086110307
1086210308 const new_cond_ref = if (union_originally)
10863 try sema.unionToTag(child_block, item_ty, new_val, src)
10309 try sema.unionToTag(child_block, new_val)
1086410310 else
1086510311 new_val;
1086610312
......@@ -10881,7 +10327,7 @@ fn analyzeSwitchBlock(
1088110327 unreachable;
1088210328 }
1088310329
10884 if (try sema.typeHasOnePossibleValue(item_ty)) |item_opv| {
10330 if (try item_ty.onePossibleValue(pt)) |item_opv| {
1088510331 // We simplify conditions with OPV to either a `loop` or a `block` since
1088610332 // we cannot switch on a value which doesn't exist at runtime.
1088710333 assert(operand == .loop); // `simple` should have already been comptime-resolved above!
......@@ -10912,7 +10358,7 @@ fn analyzeSwitchBlock(
1091210358 assert(case.range_infos.len == 0);
1091310359 for (case.item_infos, item_refs) |item_info, item_ref| {
1091410360 if (item_info.bodyLen()) |body_len| extra_index += body_len;
10915 if (sema.wantSwitchProngBodyAnalysis(block, item_ref, operand_ty, false, true, prong_info.is_comptime_unreach)) {
10361 if (sema.wantSwitchProngBodyAnalysis(item_ref, operand_ty, false, true, prong_info.is_comptime_unreach)) {
1091610362 break :skip_case;
1091710363 }
1091810364 }
......@@ -10928,7 +10374,7 @@ fn analyzeSwitchBlock(
1092810374 unreachable; // malformed validated switch
1092910375 };
1093010376
10931 const analyze_body = sema.wantSwitchProngBodyAnalysis(block, .fromValue(item_opv), operand_ty, union_originally, err_set, false);
10377 const analyze_body = sema.wantSwitchProngBodyAnalysis(.fromValue(item_opv), operand_ty, union_originally, err_set, false);
1093210378 if (!analyze_body) return .unreachable_value;
1093310379
1093410380 if (!(err_set and
......@@ -10938,10 +10384,10 @@ fn analyzeSwitchBlock(
1093810384 const payload_inst: Zir.Inst.Index = if (capture != .none) inst: {
1093910385 const payload_inst = zir_switch.payload_capture_placeholder.unwrap() orelse switch_inst;
1094010386 const payload_ref: Air.Inst.Ref = payload_ref: {
10941 const item_val: InternPool.Index = switch (operand_ty.zigTypeTag(zcu)) {
10387 const item_val: Value = switch (operand_ty.zigTypeTag(zcu)) {
1094210388 .@"union" => item_val: {
1094310389 if (maybe_operand_opv) |operand_opv| {
10944 break :item_val zcu.intern_pool.indexToKey(operand_opv.toIntern()).un.val;
10390 break :item_val .fromInterned(zcu.intern_pool.indexToKey(operand_opv.toIntern()).un.val);
1094510391 }
1094610392 assert(union_originally); // operand type must be union, otherwise it would be an OPV type here
1094710393 assert(zir_switch.any_maybe_runtime_capture); // there's a payload capture
......@@ -10978,10 +10424,10 @@ fn analyzeSwitchBlock(
1097810424 validated_switch.else_err_ty,
1097910425 );
1098010426 },
10981 else => item_opv.toIntern(),
10427 else => item_opv,
1098210428 };
1098310429 break :payload_ref switch (capture) {
10984 .by_val => .fromIntern(item_val),
10430 .by_val => .fromValue(item_val),
1098510431 .by_ref => try sema.uavRef(item_val),
1098610432 .none => unreachable,
1098710433 };
......@@ -11186,7 +10632,7 @@ fn finishSwitchBr(
1118610632 if (item_ref == .none) is_under_prong = true;
1118710633 if (item_info.bodyLen()) |body_len| extra_index += body_len;
1118810634
11189 const analyze_body = sema.wantSwitchProngBodyAnalysis(block, item_ref, operand_ty, union_originally, err_set, prong_info.is_comptime_unreach);
10635 const analyze_body = sema.wantSwitchProngBodyAnalysis(item_ref, operand_ty, union_originally, err_set, prong_info.is_comptime_unreach);
1119010636 if (analyze_body) any_analyze_body = true;
1119110637
1119210638 if (prong_info.is_inline) {
......@@ -11246,11 +10692,11 @@ fn finishSwitchBr(
1124610692 any_analyze_body = true; // always an integer range, always needs analysis
1124710693
1124810694 if (prong_info.is_inline) {
11249 var item = sema.resolveConstDefinedValue(block, .unneeded, range_ref[0], undefined) catch unreachable;
11250 const item_last = sema.resolveConstDefinedValue(block, .unneeded, range_ref[1], undefined) catch unreachable;
10695 var item = sema.resolveValue(range_ref[0]).?;
10696 const item_last = sema.resolveValue(range_ref[1]).?;
1125110697
11252 if (try item.getUnsignedIntSema(pt)) |first_int| {
11253 if (try item_last.getUnsignedIntSema(pt)) |last_int| {
10698 if (item.getUnsignedInt(zcu)) |first_int| {
10699 if (item_last.getUnsignedInt(zcu)) |last_int| {
1125410700 if (std.math.cast(u32, last_int - first_int)) |range_len| {
1125510701 try branch_hints.ensureUnusedCapacity(gpa, range_len);
1125610702 }
......@@ -11259,7 +10705,6 @@ fn finishSwitchBr(
1125910705
1126010706 var prev_result_overflowed = false;
1126110707 while (item.compareScalar(.lte, item_last, operand_ty, zcu)) : ({
11262 // Previous validation has resolved any possible lazy values.
1126310708 const int_val: Value, const int_ty: Type = switch (operand_ty.zigTypeTag(zcu)) {
1126410709 .int => .{ item, operand_ty },
1126510710 .@"enum" => b: {
......@@ -11426,7 +10871,7 @@ fn finishSwitchBr(
1142610871
1142710872 const item_ref: Air.Inst.Ref = .fromValue(item_val);
1142810873
11429 const analyze_body = sema.wantSwitchProngBodyAnalysis(block, item_ref, operand_ty, union_originally, err_set, false);
10874 const analyze_body = sema.wantSwitchProngBodyAnalysis(item_ref, operand_ty, union_originally, err_set, false);
1143010875
1143110876 if (emit_bb) try sema.emitBackwardBranch(block, else_prong_src);
1143210877 emit_bb = true;
......@@ -11896,72 +11341,69 @@ fn validateSwitchBlock(
1189611341 try sema.inst_map.ensureSpaceForInstructions(gpa, &.{tag_capture_inst});
1189711342 }
1189811343
11899 const operand_ty: Type, const item_ty: Type = check_operand: {
11900 const operand_ty = operand_ty: {
11901 const raw_operand_ty = sema.typeOf(raw_operand);
11902 if (operand_is_ref) {
11903 try sema.checkPtrType(block, operand_src, raw_operand_ty, false);
11904 break :operand_ty raw_operand_ty.childType(zcu);
11905 }
11906 break :operand_ty raw_operand_ty;
11907 };
11908
11909 const item_ty: Type = item_ty: {
11910 switch (operand_ty.zigTypeTag(zcu)) {
11911 .@"enum",
11912 .error_set,
11913 .int,
11914 .comptime_int,
11915 .type,
11916 .enum_literal,
11917 .@"fn",
11918 .bool,
11919 .void,
11920 => break :item_ty operand_ty,
11344 const operand_ty = operand_ty: {
11345 const raw_operand_ty = sema.typeOf(raw_operand);
11346 if (operand_is_ref) {
11347 try sema.checkPtrType(block, operand_src, raw_operand_ty, false);
11348 const child_ty = raw_operand_ty.childType(zcu);
11349 try sema.ensureLayoutResolved(child_ty, operand_src, .ptr_access);
11350 break :operand_ty child_ty;
11351 }
11352 break :operand_ty raw_operand_ty;
11353 };
1192111354
11922 .@"union" => {
11923 try operand_ty.resolveFields(pt);
11924 const enum_ty = operand_ty.unionTagType(zcu) orelse {
11925 return sema.failWithOwnedErrorMsg(block, msg: {
11926 const msg = try sema.errMsg(operand_src, "switch on union with no attached enum", .{});
11927 errdefer msg.destroy(sema.gpa);
11928 if (operand_ty.srcLocOrNull(zcu)) |union_src| {
11929 try sema.errNote(union_src, msg, "consider 'union(enum)' here", .{});
11930 }
11931 break :msg msg;
11932 });
11933 };
11934 break :item_ty enum_ty;
11935 },
11355 const item_ty: Type = item_ty: {
11356 switch (operand_ty.zigTypeTag(zcu)) {
11357 .@"enum",
11358 .error_set,
11359 .int,
11360 .comptime_int,
11361 .type,
11362 .enum_literal,
11363 .@"fn",
11364 .bool,
11365 .void,
11366 => break :item_ty operand_ty,
1193611367
11937 .pointer => {
11938 if (!operand_ty.isSlice(zcu)) {
11939 break :item_ty operand_ty;
11940 }
11941 },
11368 .@"union" => {
11369 const enum_ty = operand_ty.unionTagType(zcu) orelse {
11370 return sema.failWithOwnedErrorMsg(block, msg: {
11371 const msg = try sema.errMsg(operand_src, "switch on union with no attached enum", .{});
11372 errdefer msg.destroy(sema.gpa);
11373 if (operand_ty.srcLocOrNull(zcu)) |union_src| {
11374 try sema.errNote(union_src, msg, "consider 'union(enum)' here", .{});
11375 }
11376 break :msg msg;
11377 });
11378 };
11379 break :item_ty enum_ty;
11380 },
1194211381
11943 else => {},
11944 }
11945 return sema.fail(block, operand_src, "switch on type '{f}'", .{operand_ty.fmt(pt)});
11946 };
11382 .pointer => {
11383 if (!operand_ty.isSlice(zcu)) {
11384 break :item_ty operand_ty;
11385 }
11386 },
1194711387
11948 if (zir_switch.has_continue and !block.isComptime()) {
11949 if (try operand_ty.comptimeOnlySema(pt)) {
11950 // Even if the operand is comptime-known, this `switch` is runtime.
11951 return sema.failWithOwnedErrorMsg(block, msg: {
11952 const msg = try sema.errMsg(operand_src, "operand of switch loop has comptime-only type '{f}'", .{operand_ty.fmt(pt)});
11953 errdefer msg.destroy(gpa);
11954 try sema.errNote(operand_src, msg, "switch loops are evaluated at runtime outside of comptime scopes", .{});
11955 try sema.explainWhyTypeIsComptime(msg, operand_src, operand_ty);
11956 break :msg msg;
11957 });
11958 }
11959 try sema.validateRuntimeValue(block, operand_src, raw_operand);
11388 else => {},
1196011389 }
11961
11962 break :check_operand .{ operand_ty, item_ty };
11390 return sema.fail(block, operand_src, "switch on type '{f}'", .{operand_ty.fmt(pt)});
1196311391 };
1196411392
11393 if (zir_switch.has_continue and !block.isComptime()) {
11394 if (operand_ty.comptimeOnly(zcu)) {
11395 // Even if the operand is comptime-known, this `switch` is runtime.
11396 return sema.failWithOwnedErrorMsg(block, msg: {
11397 const msg = try sema.errMsg(operand_src, "operand of switch loop has comptime-only type '{f}'", .{operand_ty.fmt(pt)});
11398 errdefer msg.destroy(gpa);
11399 try sema.errNote(operand_src, msg, "switch loops are evaluated at runtime outside of comptime scopes", .{});
11400 try sema.explainWhyTypeIsComptime(msg, operand_src, operand_ty);
11401 break :msg msg;
11402 });
11403 }
11404 try sema.validateRuntimeValue(block, operand_src, raw_operand);
11405 }
11406
1196511407 const has_else = zir_switch.else_case != null;
1196611408 const has_under = zir_switch.has_under;
1196711409
......@@ -12305,7 +11747,7 @@ fn resolveSwitchBlock(
1230511747 child_block: *Block,
1230611748 operand: SwitchOperand,
1230711749 raw_operand_ty: Type,
12308 maybe_lazy_cond_val: Value,
11750 cond_val: Value,
1230911751 merges: *Block.Merges,
1231011752 switch_inst: Zir.Inst.Index,
1231111753 zir_switch: *const Zir.UnwrappedSwitchBlock,
......@@ -12325,9 +11767,6 @@ fn resolveSwitchBlock(
1232511767 const err_set = item_ty.zigTypeTag(zcu) == .error_set;
1232611768
1232711769 const cond_ref = operand.simple.cond;
12328 // We have to resolve lazy values to ensure that comparisons with switch
12329 // prong items don't produce false negatives.
12330 const cond_val = try sema.resolveLazyValue(maybe_lazy_cond_val);
1233111770
1233211771 const case_vals = validated_switch.case_vals;
1233311772 var case_val_idx: usize = 0;
......@@ -12365,7 +11804,7 @@ fn resolveSwitchBlock(
1236511804 };
1236611805 continue;
1236711806 }
12368 const item_val = sema.resolveConstDefinedValue(child_block, .unneeded, item_ref, undefined) catch unreachable;
11807 const item_val = sema.resolveValue(item_ref).?;
1236911808 if (cond_val.eql(item_val, item_ty, zcu)) {
1237011809 if (err_set) try sema.maybeErrorUnwrapComptime(child_block, prong_body, cond_ref);
1237111810 if (union_originally and operand_ty.unionFieldType(item_val, zcu).?.isNoReturn(zcu)) {
......@@ -12398,8 +11837,8 @@ fn resolveSwitchBlock(
1239811837 }
1239911838 }
1240011839 for (range_refs) |range_ref| {
12401 const first_val = sema.resolveConstDefinedValue(child_block, .unneeded, range_ref[0], undefined) catch unreachable;
12402 const last_val = sema.resolveConstDefinedValue(child_block, .unneeded, range_ref[1], undefined) catch unreachable;
11840 const first_val = sema.resolveValue(range_ref[0]).?;
11841 const last_val = sema.resolveValue(range_ref[1]).?;
1240311842 if ((try sema.compareAll(cond_val, .gte, first_val, item_ty)) and
1240411843 (try sema.compareAll(cond_val, .lte, last_val, item_ty)))
1240511844 {
......@@ -12608,7 +12047,6 @@ fn resolveSwitchProng(
1260812047
1260912048fn wantSwitchProngBodyAnalysis(
1261012049 sema: *Sema,
12611 block: *Block,
1261212050 item_ref: Air.Inst.Ref,
1261312051 operand_ty: Type,
1261412052 union_originally: bool,
......@@ -12617,16 +12055,14 @@ fn wantSwitchProngBodyAnalysis(
1261712055) bool {
1261812056 const zcu = sema.pt.zcu;
1261912057 if (union_originally) {
12620 const unresolved_item_val = sema.resolveConstDefinedValue(block, .unneeded, item_ref, undefined) catch unreachable;
12621 const item_val = sema.resolveLazyValue(unresolved_item_val) catch unreachable;
12058 const item_val = sema.resolveValue(item_ref).?;
1262212059 const field_ty = operand_ty.unionFieldType(item_val, zcu).?;
1262312060 if (field_ty.isNoReturn(zcu)) return false;
1262412061 }
1262512062 if (err_set and prong_is_comptime_unreach) {
12626 const unresolved_item_val = sema.resolveConstDefinedValue(block, .unneeded, item_ref, undefined) catch unreachable;
12627 const item_val = sema.resolveLazyValue(unresolved_item_val) catch unreachable;
12063 const item_val = sema.resolveValue(item_ref).?;
1262812064 const err_name = item_val.getErrorName(zcu).unwrap().?;
12629 if (!Type.errorSetHasFieldIp(&zcu.intern_pool, operand_ty.toIntern(), err_name)) return false;
12065 if (!operand_ty.errorSetHasField(err_name, zcu)) return false;
1263012066 }
1263112067 return true;
1263212068}
......@@ -12772,8 +12208,7 @@ fn analyzeSwitchTagCapture(
1277212208 .item_refs => |refs| if (refs.len == 1) return refs[0],
1277312209 .special => {},
1277412210 }
12775 const tag_ty = operand_ty.unionTagType(zcu).?;
12776 return sema.unionToTag(case_block, tag_ty, operand_val, tag_capture_src);
12211 return sema.unionToTag(case_block, operand_val);
1277712212}
1277812213
1277912214fn analyzeSwitchPayloadCapture(
......@@ -12800,14 +12235,14 @@ fn analyzeSwitchPayloadCapture(
1280012235 const switch_node_offset = operand_src.offset.node_offset_switch_operand;
1280112236
1280212237 if (kind == .inline_ref) {
12803 const item_val = sema.resolveConstDefinedValue(case_block, .unneeded, kind.inline_ref, undefined) catch unreachable;
12238 const item_val = sema.resolveValue(kind.inline_ref).?;
1280412239 if (operand_ty.zigTypeTag(zcu) == .@"union") {
1280512240 const field_index: u32 = @intCast(operand_ty.unionTagFieldIndex(item_val, zcu).?);
1280612241 const union_obj = zcu.typeToUnion(operand_ty).?;
1280712242 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);
1280812243 if (capture_by_ref) {
1280912244 const operand_ptr_info = sema.typeOf(operand_ptr).ptrInfo(zcu);
12810 const ptr_field_ty = try pt.ptrTypeSema(.{
12245 const ptr_field_ty = try pt.ptrType(.{
1281112246 .child = field_ty.toIntern(),
1281212247 .flags = .{
1281312248 .is_const = operand_ptr_info.flags.is_const,
......@@ -12821,10 +12256,11 @@ fn analyzeSwitchPayloadCapture(
1282112256 const tag_and_val = ip.indexToKey(union_val.toIntern()).un;
1282212257 return .fromIntern(tag_and_val.val);
1282312258 }
12259 if (try field_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
1282412260 return case_block.addStructFieldVal(operand_val, field_index, field_ty);
1282512261 }
1282612262 } else if (capture_by_ref) {
12827 return sema.uavRef(item_val.toIntern());
12263 return sema.uavRef(item_val);
1282812264 } else {
1282912265 return kind.inline_ref;
1283012266 }
......@@ -12850,14 +12286,14 @@ fn analyzeSwitchPayloadCapture(
1285012286 const case_vals = kind.item_refs;
1285112287
1285212288 const union_obj = zcu.typeToUnion(operand_ty).?;
12853 const first_item_val = sema.resolveConstDefinedValue(case_block, .unneeded, case_vals[0], undefined) catch unreachable;
12289 const first_item_val = sema.resolveValue(case_vals[0]).?;
1285412290
1285512291 const first_field_index: u32 = zcu.unionTagFieldIndex(union_obj, first_item_val).?;
1285612292 const first_field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[first_field_index]);
1285712293
1285812294 const field_indices = try sema.arena.alloc(u32, case_vals.len);
1285912295 for (case_vals, field_indices) |item, *field_idx| {
12860 const item_val = sema.resolveConstDefinedValue(case_block, .unneeded, item, undefined) catch unreachable;
12296 const item_val = sema.resolveValue(item).?;
1286112297 field_idx.* = zcu.unionTagFieldIndex(union_obj, item_val).?;
1286212298 }
1286312299
......@@ -12906,23 +12342,14 @@ fn analyzeSwitchPayloadCapture(
1290612342
1290712343 // By-reference captures have some further restrictions which make them easier to emit
1290812344 if (capture_by_ref) {
12909 const operand_ptr_info = sema.typeOf(operand_ptr).ptrInfo(zcu);
12345 const operand_ptr_ty = sema.typeOf(operand_ptr);
1291012346 const capture_ptr_ty = resolve: {
1291112347 // By-ref captures of hetereogeneous types are only allowed if all field
1291212348 // pointer types are peer resolvable to each other.
1291312349 // We need values to run PTR on, so make a bunch of undef constants.
1291412350 const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len);
12915 for (field_indices, dummy_captures) |field_idx, *dummy| {
12916 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_idx]);
12917 const field_ptr_ty = try pt.ptrTypeSema(.{
12918 .child = field_ty.toIntern(),
12919 .flags = .{
12920 .is_const = operand_ptr_info.flags.is_const,
12921 .is_volatile = operand_ptr_info.flags.is_volatile,
12922 .address_space = operand_ptr_info.flags.address_space,
12923 .alignment = union_obj.fieldAlign(ip, field_idx),
12924 },
12925 });
12351 for (field_indices, dummy_captures) |field_index, *dummy| {
12352 const field_ptr_ty = try operand_ptr_ty.fieldPtrType(field_index, pt);
1292612353 dummy.* = try pt.undefRef(field_ptr_ty);
1292712354 }
1292812355 const case_srcs = try sema.arena.alloc(?LazySrcLoc, case_vals.len);
......@@ -12963,6 +12390,8 @@ fn analyzeSwitchPayloadCapture(
1296312390 return case_block.addStructFieldPtr(operand_ptr, first_field_index, capture_ptr_ty);
1296412391 }
1296512392
12393 if (try capture_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
12394
1296612395 if (try sema.resolveDefinedValue(case_block, operand_src, operand_val)) |operand_val_val| {
1296712396 if (operand_val_val.isUndef(zcu)) return pt.undefRef(capture_ty);
1296812397 const union_val = ip.indexToKey(operand_val_val.toIntern()).un;
......@@ -13119,7 +12548,7 @@ fn analyzeSwitchPayloadCapture(
1311912548 try sema.air_instructions.append(sema.gpa, .{
1312012549 .tag = .get_union_tag,
1312112550 .data = .{ .ty_op = .{
13122 .ty = .fromIntern(union_obj.enum_tag_ty),
12551 .ty = .fromIntern(union_obj.enum_tag_type),
1312312552 .operand = operand_val,
1312412553 } },
1312512554 });
......@@ -13146,7 +12575,7 @@ fn analyzeSwitchPayloadCapture(
1314612575
1314712576 const case_vals = kind.item_refs;
1314812577 if (case_vals.len == 1) {
13149 const item_val = sema.resolveConstDefinedValue(case_block, .unneeded, case_vals[0], undefined) catch unreachable;
12578 const item_val = sema.resolveValue(case_vals[0]).?;
1315012579 const item_ty = try pt.singleErrorSetType(item_val.getErrorName(zcu).unwrap().?);
1315112580 return sema.bitCast(case_block, item_ty, .fromValue(item_val), operand_src, null);
1315212581 }
......@@ -13154,7 +12583,7 @@ fn analyzeSwitchPayloadCapture(
1315412583 var names: InferredErrorSet.NameMap = .{};
1315512584 try names.ensureUnusedCapacity(sema.arena, case_vals.len);
1315612585 for (case_vals) |err| {
13157 const err_val = sema.resolveConstDefinedValue(case_block, .unneeded, err, undefined) catch unreachable;
12586 const err_val = sema.resolveValue(err).?;
1315812587 names.putAssumeCapacityNoClobber(err_val.getErrorName(zcu).unwrap().?, {});
1315912588 }
1316012589 const error_ty = try pt.errorSetFromUnsortedNames(names.keys());
......@@ -13249,7 +12678,7 @@ fn resolveSwitchItem(
1324912678 // We allow prongs with errors which are not part of the error set
1325012679 // being switched on if their prong body is `=> comptime unreachable,`.
1325112680 switch (try sema.coerceInMemoryAllowedErrorSets(block, item_ty, uncoerced_ty, item_src, item_src)) {
13252 .ok => if (try sema.resolveValue(uncoerced)) |uncoerced_val| {
12681 .ok => if (sema.resolveValue(uncoerced)) |uncoerced_val| {
1325312682 break :item_ref try sema.coerceInMemory(uncoerced_val, item_ty);
1325412683 },
1325512684 .missing_error => if (prong_is_comptime_unreach) {
......@@ -13261,17 +12690,8 @@ fn resolveSwitchItem(
1326112690 }
1326212691 break :item_ref try sema.coerce(block, item_ty, uncoerced, item_src);
1326312692 };
13264 const maybe_lazy = try sema.resolveConstDefinedValue(block, item_src, item_ref, .{ .simple = .switch_item });
13265
13266 // We have to resolve lazy values here to avoid false negatives when detecting
13267 // duplicate items and comparing items to a comptime-known switch operand.
13268
13269 const val = try sema.resolveLazyValue(maybe_lazy);
13270 const ref: Air.Inst.Ref = if (val.toIntern() == maybe_lazy.toIntern())
13271 item_ref
13272 else
13273 .fromValue(val);
13274 return .{ .{ .ref = ref, .val = val }, end };
12693 const val = try sema.resolveConstDefinedValue(block, item_src, item_ref, .{ .simple = .switch_item });
12694 return .{ .{ .ref = item_ref, .val = val }, end };
1327512695}
1327612696
1327712697fn validateSwitchItemOrRange(
......@@ -13422,7 +12842,7 @@ fn maybeErrorUnwrap(
1342212842 },
1342312843 .panic => {
1342412844 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
13425 const msg_inst = try sema.resolveInst(inst_data.operand);
12845 const msg_inst = sema.resolveInst(inst_data.operand);
1342612846
1342712847 const panic_fn = try getBuiltin(sema, operand_src, .@"panic.call");
1342812848 const args: [2]Air.Inst.Ref = .{ msg_inst, .null_value };
......@@ -13445,7 +12865,7 @@ fn maybeErrorUnwrapCondbr(sema: *Sema, block: *Block, body: []const Zir.Inst.Ind
1344512865 if (sema.code.instructions.items(.tag)[@intFromEnum(index)] != .is_non_err) return;
1344612866
1344712867 const err_inst_data = sema.code.instructions.items(.data)[@intFromEnum(index)].un_node;
13448 const err_operand = try sema.resolveInst(err_inst_data.operand);
12868 const err_operand = sema.resolveInst(err_inst_data.operand);
1344912869 const operand_ty = sema.typeOf(err_operand);
1345012870 if (operand_ty.zigTypeTag(zcu) == .error_set) {
1345112871 try sema.maybeErrorUnwrapComptime(block, body, err_operand);
......@@ -13488,7 +12908,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1348812908 const name_src = block.builtinCallArgSrc(inst_data.src_node, 1);
1348912909 const ty = try sema.resolveType(block, ty_src, extra.lhs);
1349012910 const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, .{ .simple = .field_name });
13491 try ty.resolveFields(pt);
12911 try sema.ensureLayoutResolved(ty, ty_src, .field_queried);
1349212912 const ip = &zcu.intern_pool;
1349312913
1349412914 const has_field = hf: {
......@@ -13510,7 +12930,8 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1351012930 },
1351112931 .union_type => {
1351212932 const union_type = ip.loadUnionType(ty.toIntern());
13513 break :hf union_type.loadTagType(ip).nameIndex(ip, field_name) != null;
12933 const enum_type = ip.loadEnumType(union_type.enum_tag_type);
12934 break :hf enum_type.nameIndex(ip, field_name) != null;
1351412935 },
1351512936 .enum_type => {
1351612937 break :hf ip.loadEnumType(ty.toIntern()).nameIndex(ip, field_name) != null;
......@@ -13568,17 +12989,18 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1356812989 const file = zcu.fileByIndex(file_index);
1356912990 switch (file.getMode()) {
1357012991 .zig => {
13571 try pt.ensureFileAnalyzed(file_index);
13572 const ty = zcu.fileRootType(file_index);
13573 try sema.declareDependency(.{ .interned = ty });
12992 try pt.ensureFilePopulated(file_index);
12993 const ty: Type = .fromInterned(zcu.fileRootType(file_index));
1357412994 try sema.addTypeReferenceEntry(operand_src, ty);
13575 return Air.internedToRef(ty);
12995 // No need for `ensureNamespaceUpToDate`, because `Zcu.PerThread.updateFileNamespace`
12996 // already made sure that all root file structs have up-to-date namespaces.
12997 return .fromType(ty);
1357612998 },
1357712999 .zon => {
1357813000 const res_ty: InternPool.Index = b: {
1357913001 if (extra.res_ty == .none) break :b .none;
13580 const res_ty_inst = try sema.resolveInst(extra.res_ty);
13581 const res_ty = try sema.analyzeAsType(block, operand_src, res_ty_inst);
13002 const res_ty_inst = sema.resolveInst(extra.res_ty);
13003 const res_ty = try sema.analyzeAsType(block, operand_src, .type, res_ty_inst);
1358213004 if (res_ty.isGenericPoison()) break :b .none;
1358313005 break :b res_ty.toIntern();
1358413006 };
......@@ -13665,8 +13087,8 @@ fn zirShl(
1366513087 const zcu = pt.zcu;
1366613088 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1366713089 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
13668 const lhs = try sema.resolveInst(extra.lhs);
13669 const rhs = try sema.resolveInst(extra.rhs);
13090 const lhs = sema.resolveInst(extra.lhs);
13091 const rhs = sema.resolveInst(extra.rhs);
1367013092 const lhs_ty = sema.typeOf(lhs);
1367113093 const rhs_ty = sema.typeOf(rhs);
1367213094
......@@ -13692,8 +13114,8 @@ fn zirShl(
1369213114 // we already know `scalar_rhs_ty` is valid for `.shl` -- we only need to validate for `.shl_sat`.
1369313115 if (air_tag == .shl_sat) _ = try sema.checkIntType(block, rhs_src, scalar_rhs_ty);
1369413116
13695 const maybe_lhs_val = try sema.resolveValueResolveLazy(lhs);
13696 const maybe_rhs_val = try sema.resolveValueResolveLazy(rhs);
13117 const maybe_lhs_val = sema.resolveValue(lhs);
13118 const maybe_rhs_val = sema.resolveValue(rhs);
1369713119
1369813120 const runtime_src = rs: {
1369913121 if (maybe_rhs_val) |rhs_val| {
......@@ -13713,11 +13135,11 @@ fn zirShl(
1371313135 const bits = scalar_ty.intInfo(zcu).bits;
1371413136 switch (rhs_ty.zigTypeTag(zcu)) {
1371513137 .int, .comptime_int => {
13716 switch (try rhs_val.orderAgainstZeroSema(pt)) {
13138 switch (Value.order(rhs_val, .zero_comptime_int, zcu)) {
1371713139 .gt => {
1371813140 if (air_tag != .shl_sat) {
1371913141 var rhs_space: Value.BigIntSpace = undefined;
13720 const rhs_bigint = try rhs_val.toBigIntSema(&rhs_space, pt);
13142 const rhs_bigint = rhs_val.toBigInt(&rhs_space, zcu);
1372113143 if (rhs_bigint.orderAgainstScalar(bits) != .lt) {
1372213144 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, null);
1372313145 }
......@@ -13736,11 +13158,11 @@ fn zirShl(
1373613158 .shl, .shl_exact => return sema.failWithUseOfUndef(block, rhs_src, elem_idx),
1373713159 else => unreachable,
1373813160 };
13739 switch (try rhs_elem.orderAgainstZeroSema(pt)) {
13161 switch (Value.order(rhs_elem, .zero_comptime_int, zcu)) {
1374013162 .gt => {
1374113163 if (air_tag != .shl_sat) {
1374213164 var rhs_elem_space: Value.BigIntSpace = undefined;
13743 const rhs_elem_bigint = try rhs_elem.toBigIntSema(&rhs_elem_space, pt);
13165 const rhs_elem_bigint = rhs_elem.toBigInt(&rhs_elem_space, zcu);
1374413166 if (rhs_elem_bigint.orderAgainstScalar(bits) != .lt) {
1374513167 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_elem, rhs_src, elem_idx);
1374613168 }
......@@ -13769,7 +13191,7 @@ fn zirShl(
1376913191 .shl, .shl_exact => try sema.checkAllScalarsDefined(block, lhs_src, lhs_val),
1377013192 else => unreachable,
1377113193 }
13772 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) return lhs;
13194 if (lhs_val.compareAllWithZero(.eq, zcu)) return lhs;
1377313195 }
1377413196 }
1377513197 break :rs rhs_src;
......@@ -13785,13 +13207,13 @@ fn zirShl(
1378513207 const rt_rhs_scalar_ty = try pt.smallestUnsignedInt(bit_count);
1378613208 if (!rhs_ty.isVector(zcu)) break :rt_rhs try pt.intValue(
1378713209 rt_rhs_scalar_ty,
13788 @min(try rhs_val.getUnsignedIntSema(pt) orelse bit_count, bit_count),
13210 @min(rhs_val.getUnsignedInt(zcu) orelse bit_count, bit_count),
1378913211 );
1379013212 const rhs_len = rhs_ty.vectorLen(zcu);
1379113213 const rhs_elems = try sema.arena.alloc(InternPool.Index, rhs_len);
1379213214 for (rhs_elems, 0..) |*rhs_elem, i| rhs_elem.* = (try pt.intValue(
1379313215 rt_rhs_scalar_ty,
13794 @min(try (try rhs_val.elemValue(pt, i)).getUnsignedIntSema(pt) orelse bit_count, bit_count),
13216 @min((try rhs_val.elemValue(pt, i)).getUnsignedInt(zcu) orelse bit_count, bit_count),
1379513217 )).toIntern();
1379613218 break :rt_rhs try pt.aggregateValue(try pt.vectorType(.{
1379713219 .len = rhs_len,
......@@ -13855,8 +13277,8 @@ fn zirShr(
1385513277 const zcu = pt.zcu;
1385613278 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1385713279 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
13858 const lhs = try sema.resolveInst(extra.lhs);
13859 const rhs = try sema.resolveInst(extra.rhs);
13280 const lhs = sema.resolveInst(extra.lhs);
13281 const rhs = sema.resolveInst(extra.rhs);
1386013282 const lhs_ty = sema.typeOf(lhs);
1386113283 const rhs_ty = sema.typeOf(rhs);
1386213284
......@@ -13875,8 +13297,8 @@ fn zirShr(
1387513297 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1387613298 const scalar_ty = lhs_ty.scalarType(zcu);
1387713299
13878 const maybe_lhs_val = try sema.resolveValueResolveLazy(lhs);
13879 const maybe_rhs_val = try sema.resolveValueResolveLazy(rhs);
13300 const maybe_lhs_val = sema.resolveValue(lhs);
13301 const maybe_rhs_val = sema.resolveValue(rhs);
1388013302
1388113303 const runtime_src = rs: {
1388213304 if (maybe_rhs_val) |rhs_val| {
......@@ -13893,10 +13315,10 @@ fn zirShr(
1389313315 const bits = scalar_ty.intInfo(zcu).bits;
1389413316 switch (rhs_ty.zigTypeTag(zcu)) {
1389513317 .int, .comptime_int => {
13896 switch (try rhs_val.orderAgainstZeroSema(pt)) {
13318 switch (Value.order(rhs_val, .zero_comptime_int, zcu)) {
1389713319 .gt => {
1389813320 var rhs_space: Value.BigIntSpace = undefined;
13899 const rhs_bigint = try rhs_val.toBigIntSema(&rhs_space, pt);
13321 const rhs_bigint = rhs_val.toBigInt(&rhs_space, zcu);
1390013322 if (rhs_bigint.orderAgainstScalar(bits) != .lt) {
1390113323 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, null);
1390213324 }
......@@ -13912,10 +13334,10 @@ fn zirShr(
1391213334 if (rhs_elem.isUndef(zcu)) {
1391313335 return sema.failWithUseOfUndef(block, rhs_src, elem_idx);
1391413336 }
13915 switch (try rhs_elem.orderAgainstZeroSema(pt)) {
13337 switch (Value.order(rhs_elem, .zero_comptime_int, zcu)) {
1391613338 .gt => {
1391713339 var rhs_elem_space: Value.BigIntSpace = undefined;
13918 const rhs_elem_bigint = try rhs_elem.toBigIntSema(&rhs_elem_space, pt);
13340 const rhs_elem_bigint = rhs_elem.toBigInt(&rhs_elem_space, zcu);
1391913341 if (rhs_elem_bigint.orderAgainstScalar(bits) != .lt) {
1392013342 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_elem, rhs_src, elem_idx);
1392113343 }
......@@ -13936,7 +13358,7 @@ fn zirShr(
1393613358 }
1393713359 if (maybe_lhs_val) |lhs_val| {
1393813360 try sema.checkAllScalarsDefined(block, lhs_src, lhs_val);
13939 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) return lhs;
13361 if (lhs_val.compareAllWithZero(.eq, zcu)) return lhs;
1394013362 }
1394113363 }
1394213364 break :rs rhs_src;
......@@ -13988,8 +13410,8 @@ fn zirBitwise(
1398813410 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
1398913411 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
1399013412 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
13991 const lhs = try sema.resolveInst(extra.lhs);
13992 const rhs = try sema.resolveInst(extra.rhs);
13413 const lhs = sema.resolveInst(extra.lhs);
13414 const rhs = sema.resolveInst(extra.rhs);
1399313415 const lhs_ty = sema.typeOf(lhs);
1399413416 const rhs_ty = sema.typeOf(rhs);
1399513417 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
......@@ -14011,8 +13433,8 @@ fn zirBitwise(
1401113433 const runtime_src = runtime: {
1401213434 // TODO: ask the linker what kind of relocations are available, and
1401313435 // in some cases emit a Value that means "this decl's address AND'd with this operand".
14014 if (try sema.resolveValueResolveLazy(casted_lhs)) |lhs_val| {
14015 if (try sema.resolveValueResolveLazy(casted_rhs)) |rhs_val| {
13436 if (sema.resolveValue(casted_lhs)) |lhs_val| {
13437 if (sema.resolveValue(casted_rhs)) |rhs_val| {
1401613438 const result_val = switch (air_tag) {
1401713439 // zig fmt: off
1401813440 .bit_and => try arith.bitwiseBin(sema, resolved_type, lhs_val, rhs_val, .@"and"),
......@@ -14040,7 +13462,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1404013462 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1404113463 const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
1404213464 const src = block.nodeOffset(inst_data.src_node);
14043 const operand = try sema.resolveInst(inst_data.operand);
13465 const operand = sema.resolveInst(inst_data.operand);
1404413466 const operand_ty = sema.typeOf(operand);
1404513467 const scalar_ty = operand_ty.scalarType(zcu);
1404613468 const scalar_tag = scalar_ty.zigTypeTag(zcu);
......@@ -14058,7 +13480,7 @@ fn analyzeBitNot(
1405813480 src: LazySrcLoc,
1405913481) CompileError!Air.Inst.Ref {
1406013482 const operand_ty = sema.typeOf(operand);
14061 if (try sema.resolveValue(operand)) |operand_val| {
13483 if (sema.resolveValue(operand)) |operand_val| {
1406213484 const result_val = try arith.bitwiseNot(sema, operand_ty, operand_val);
1406313485 return Air.internedToRef(result_val.toIntern());
1406413486 }
......@@ -14106,13 +13528,13 @@ fn analyzeTupleCat(
1410613528 var i: u32 = 0;
1410713529 while (i < lhs_len) : (i += 1) {
1410813530 types[i] = lhs_ty.fieldType(i, zcu).toIntern();
14109 const default_val = lhs_ty.structFieldDefaultValue(i, zcu);
14110 values[i] = default_val.toIntern();
1411113531 const operand_src = block.src(.{ .array_cat_lhs = .{
1411213532 .array_cat_offset = src_node,
1411313533 .elem_index = i,
1411413534 } });
14115 if (default_val.toIntern() == .unreachable_value) {
13535 if (lhs_ty.structFieldDefaultValue(i, zcu)) |default_val| {
13536 values[i] = default_val.toIntern();
13537 } else {
1411613538 runtime_src = operand_src;
1411713539 values[i] = .none;
1411813540 }
......@@ -14120,13 +13542,13 @@ fn analyzeTupleCat(
1412013542 i = 0;
1412113543 while (i < rhs_len) : (i += 1) {
1412213544 types[i + lhs_len] = rhs_ty.fieldType(i, zcu).toIntern();
14123 const default_val = rhs_ty.structFieldDefaultValue(i, zcu);
14124 values[i + lhs_len] = default_val.toIntern();
1412513545 const operand_src = block.src(.{ .array_cat_rhs = .{
1412613546 .array_cat_offset = src_node,
1412713547 .elem_index = i,
1412813548 } });
14129 if (default_val.toIntern() == .unreachable_value) {
13549 if (rhs_ty.structFieldDefaultValue(i, zcu)) |default_val| {
13550 values[i + lhs_len] = default_val.toIntern();
13551 } else {
1413013552 runtime_src = operand_src;
1413113553 values[i + lhs_len] = .none;
1413213554 }
......@@ -14168,8 +13590,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1416813590 const zcu = pt.zcu;
1416913591 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1417013592 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
14171 const lhs = try sema.resolveInst(extra.lhs);
14172 const rhs = try sema.resolveInst(extra.rhs);
13593 const lhs = sema.resolveInst(extra.lhs);
13594 const rhs = sema.resolveInst(extra.rhs);
1417313595 const lhs_ty = sema.typeOf(lhs);
1417413596 const rhs_ty = sema.typeOf(rhs);
1417513597 const src = block.nodeOffset(inst_data.src_node);
......@@ -14263,12 +13685,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1426313685 };
1426413686
1426513687 const runtime_src = if (switch (lhs_ty.zigTypeTag(zcu)) {
14266 .array, .@"struct" => try sema.resolveValue(lhs),
13688 .array, .@"struct" => sema.resolveValue(lhs),
1426713689 .pointer => try sema.resolveDefinedValue(block, lhs_src, lhs),
1426813690 else => unreachable,
1426913691 }) |lhs_val| rs: {
1427013692 if (switch (rhs_ty.zigTypeTag(zcu)) {
14271 .array, .@"struct" => try sema.resolveValue(rhs),
13693 .array, .@"struct" => sema.resolveValue(rhs),
1427213694 .pointer => try sema.resolveDefinedValue(block, rhs_src, rhs),
1427313695 else => unreachable,
1427413696 }) |rhs_val| {
......@@ -14290,32 +13712,30 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1429013712 var elem_i: u32 = 0;
1429113713 while (elem_i < lhs_len) : (elem_i += 1) {
1429213714 const lhs_elem_i = elem_i;
14293 const elem_default_val = if (lhs_is_tuple) lhs_ty.structFieldDefaultValue(lhs_elem_i, zcu) else Value.@"unreachable";
14294 const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try lhs_sub_val.elemValue(pt, lhs_elem_i) else elem_default_val;
14295 const elem_val_inst = Air.internedToRef(elem_val.toIntern());
13715 const elem_default_val: ?Value = if (lhs_is_tuple) lhs_ty.structFieldDefaultValue(lhs_elem_i, zcu) else null;
13716 const elem_val = elem_default_val orelse try lhs_sub_val.elemValue(pt, lhs_elem_i);
1429613717 const operand_src = block.src(.{ .array_cat_lhs = .{
1429713718 .array_cat_offset = inst_data.src_node,
1429813719 .elem_index = elem_i,
1429913720 } });
14300 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src);
14301 const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined);
13721 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, .fromValue(elem_val), operand_src);
13722 const coerced_elem_val = sema.resolveValue(coerced_elem_val_inst).?;
1430213723 element_vals[elem_i] = coerced_elem_val.toIntern();
1430313724 }
1430413725 while (elem_i < result_len) : (elem_i += 1) {
1430513726 const rhs_elem_i = elem_i - lhs_len;
14306 const elem_default_val = if (rhs_is_tuple) rhs_ty.structFieldDefaultValue(rhs_elem_i, zcu) else Value.@"unreachable";
14307 const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try rhs_sub_val.elemValue(pt, rhs_elem_i) else elem_default_val;
14308 const elem_val_inst = Air.internedToRef(elem_val.toIntern());
13727 const elem_default_val: ?Value = if (rhs_is_tuple) rhs_ty.structFieldDefaultValue(rhs_elem_i, zcu) else null;
13728 const elem_val = elem_default_val orelse try rhs_sub_val.elemValue(pt, rhs_elem_i);
1430913729 const operand_src = block.src(.{ .array_cat_rhs = .{
1431013730 .array_cat_offset = inst_data.src_node,
1431113731 .elem_index = @intCast(rhs_elem_i),
1431213732 } });
14313 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src);
14314 const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined);
13733 const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, .fromValue(elem_val), operand_src);
13734 const coerced_elem_val = sema.resolveValue(coerced_elem_val_inst).?;
1431513735 element_vals[elem_i] = coerced_elem_val.toIntern();
1431613736 }
1431713737 return sema.addConstantMaybeRef(
14318 (try pt.aggregateValue(result_ty, element_vals)).toIntern(),
13738 try pt.aggregateValue(result_ty, element_vals),
1431913739 ptr_addrspace != null,
1432013740 );
1432113741 } else break :rs rhs_src;
......@@ -14324,18 +13744,18 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1432413744 try sema.requireRuntimeBlock(block, src, runtime_src);
1432513745
1432613746 if (ptr_addrspace) |ptr_as| {
14327 const constant_alloc_ty = try pt.ptrTypeSema(.{
13747 const constant_alloc_ty = try pt.ptrType(.{
1432813748 .child = result_ty.toIntern(),
1432913749 .flags = .{
1433013750 .address_space = ptr_as,
1433113751 .is_const = true,
1433213752 },
1433313753 });
14334 const alloc_ty = try pt.ptrTypeSema(.{
13754 const alloc_ty = try pt.ptrType(.{
1433513755 .child = result_ty.toIntern(),
1433613756 .flags = .{ .address_space = ptr_as },
1433713757 });
14338 const elem_ptr_ty = try pt.ptrTypeSema(.{
13758 const elem_ptr_ty = try pt.ptrType(.{
1433913759 .child = resolved_elem_ty.toIntern(),
1434013760 .flags = .{ .address_space = ptr_as },
1434113761 });
......@@ -14347,7 +13767,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1434713767 if (lhs_ty.zigTypeTag(zcu) == .pointer and
1434813768 rhs_ty.zigTypeTag(zcu) == .pointer)
1434913769 {
14350 const slice_ty = try pt.ptrTypeSema(.{
13770 const slice_ty = try pt.ptrType(.{
1435113771 .child = resolved_elem_ty.toIntern(),
1435213772 .flags = .{
1435313773 .size = .slice,
......@@ -14359,45 +13779,44 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1435913779 const many_alloc = try block.addBitCast(many_ty, mutable_alloc);
1436013780
1436113781 // lhs_dest_slice = dest[0..lhs.len]
14362 const slice_ty_ref = Air.internedToRef(slice_ty.toIntern());
14363 const lhs_len_ref = try pt.intRef(.usize, lhs_len);
14364 const lhs_dest_slice = try block.addInst(.{
14365 .tag = .slice,
14366 .data = .{ .ty_pl = .{
14367 .ty = slice_ty_ref,
14368 .payload = try sema.addExtra(Air.Bin{
14369 .lhs = many_alloc,
14370 .rhs = lhs_len_ref,
14371 }),
14372 } },
14373 });
14374
14375 _ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs);
13782 if (lhs_len > 0) {
13783 const lhs_dest_slice = try block.addInst(.{
13784 .tag = .slice,
13785 .data = .{ .ty_pl = .{
13786 .ty = .fromType(slice_ty),
13787 .payload = try sema.addExtra(Air.Bin{
13788 .lhs = many_alloc,
13789 .rhs = try pt.intRef(.usize, lhs_len),
13790 }),
13791 } },
13792 });
13793 _ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs);
13794 }
1437613795
1437713796 // rhs_dest_slice = dest[lhs.len..][0..rhs.len]
14378 const rhs_len_ref = try pt.intRef(.usize, rhs_len);
14379 const rhs_dest_offset = try block.addInst(.{
14380 .tag = .ptr_add,
14381 .data = .{ .ty_pl = .{
14382 .ty = Air.internedToRef(many_ty.toIntern()),
14383 .payload = try sema.addExtra(Air.Bin{
14384 .lhs = many_alloc,
14385 .rhs = lhs_len_ref,
14386 }),
14387 } },
14388 });
14389 const rhs_dest_slice = try block.addInst(.{
14390 .tag = .slice,
14391 .data = .{ .ty_pl = .{
14392 .ty = slice_ty_ref,
14393 .payload = try sema.addExtra(Air.Bin{
14394 .lhs = rhs_dest_offset,
14395 .rhs = rhs_len_ref,
14396 }),
14397 } },
14398 });
14399
14400 _ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs);
13797 if (rhs_len > 0) {
13798 const rhs_dest_offset = try block.addInst(.{
13799 .tag = .ptr_add,
13800 .data = .{ .ty_pl = .{
13801 .ty = Air.internedToRef(many_ty.toIntern()),
13802 .payload = try sema.addExtra(Air.Bin{
13803 .lhs = many_alloc,
13804 .rhs = try pt.intRef(.usize, lhs_len),
13805 }),
13806 } },
13807 });
13808 const rhs_dest_slice = try block.addInst(.{
13809 .tag = .slice,
13810 .data = .{ .ty_pl = .{
13811 .ty = .fromType(slice_ty),
13812 .payload = try sema.addExtra(Air.Bin{
13813 .lhs = rhs_dest_offset,
13814 .rhs = try pt.intRef(.usize, rhs_len),
13815 }),
13816 } },
13817 });
13818 _ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs);
13819 }
1440113820
1440213821 if (res_sent_val) |sent_val| {
1440313822 const elem_index = try pt.intRef(.usize, result_len);
......@@ -14486,7 +13905,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
1448613905 .none => null,
1448713906 else => Value.fromInterned(ptr_info.sentinel),
1448813907 },
14489 .len = try val.sliceLen(pt),
13908 .len = val.sliceLen(zcu),
1449013909 };
1449113910 },
1449213911 .one => {
......@@ -14500,8 +13919,20 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
1450013919 .@"struct" => {
1450113920 if (operand_ty.isTuple(zcu) and peer_ty.isIndexable(zcu)) {
1450213921 assert(!peer_ty.isTuple(zcu));
13922 const peer_elem_ty = switch (peer_ty.zigTypeTag(zcu)) {
13923 .pointer => switch (peer_ty.ptrSize(zcu)) {
13924 .one => switch (peer_ty.childType(zcu).zigTypeTag(zcu)) {
13925 .array, .vector => peer_ty.childType(zcu).childType(zcu),
13926 .@"struct" => return null,
13927 else => unreachable,
13928 },
13929 .many, .c, .slice => peer_ty.childType(zcu),
13930 },
13931 .vector, .array => peer_ty.childType(zcu),
13932 else => unreachable,
13933 };
1450313934 return .{
14504 .elem_type = peer_ty.elemType2(zcu),
13935 .elem_type = peer_elem_ty,
1450513936 .sentinel = null,
1450613937 .len = operand_ty.arrayLen(zcu),
1450713938 };
......@@ -14543,12 +13974,13 @@ fn analyzeTupleMul(
1454313974 var runtime_src: ?LazySrcLoc = null;
1454413975 for (0..tuple_len) |i| {
1454513976 types[i] = operand_ty.fieldType(i, zcu).toIntern();
14546 values[i] = operand_ty.structFieldDefaultValue(i, zcu).toIntern();
1454713977 const operand_src = block.src(.{ .array_cat_lhs = .{
1454813978 .array_cat_offset = src_node,
1454913979 .elem_index = @intCast(i),
1455013980 } });
14551 if (values[i] == .unreachable_value) {
13981 if (operand_ty.structFieldDefaultValue(i, zcu)) |default_val| {
13982 values[i] = default_val.toIntern();
13983 } else {
1455213984 runtime_src = operand_src;
1455313985 values[i] = .none; // TODO don't treat unreachable_value as special
1455413986 }
......@@ -14593,7 +14025,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1459314025 const zcu = pt.zcu;
1459414026 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1459514027 const extra = sema.code.extraData(Zir.Inst.ArrayMul, inst_data.payload_index).data;
14596 const uncoerced_lhs = try sema.resolveInst(extra.lhs);
14028 const uncoerced_lhs = sema.resolveInst(extra.lhs);
1459714029 const uncoerced_lhs_ty = sema.typeOf(uncoerced_lhs);
1459814030 const src: LazySrcLoc = block.nodeOffset(inst_data.src_node);
1459914031 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
......@@ -14672,7 +14104,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1467214104 const ptr_addrspace = if (lhs_ty.zigTypeTag(zcu) == .pointer) lhs_ty.ptrAddressSpace(zcu) else null;
1467314105 const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len);
1467414106
14675 if (try sema.resolveValue(lhs)) |lhs_val| ct: {
14107 if (sema.resolveValue(lhs)) |lhs_val| ct: {
1467614108 const lhs_sub_val = if (lhs_ty.isSinglePointer(zcu))
1467714109 try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty) orelse break :ct
1467814110 else if (lhs_ty.isSlice(zcu))
......@@ -14700,7 +14132,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1470014132 }
1470114133 break :v try pt.aggregateValue(result_ty, element_vals);
1470214134 };
14703 return sema.addConstantMaybeRef(val.toIntern(), ptr_addrspace != null);
14135 return sema.addConstantMaybeRef(val, ptr_addrspace != null);
1470414136 }
1470514137
1470614138 try sema.requireRuntimeBlock(block, src, lhs_src);
......@@ -14714,7 +14146,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1471414146 }
1471514147
1471614148 if (ptr_addrspace) |ptr_as| {
14717 const alloc_ty = try pt.ptrTypeSema(.{
14149 const alloc_ty = try pt.ptrType(.{
1471814150 .child = result_ty.toIntern(),
1471914151 .flags = .{
1472014152 .address_space = ptr_as,
......@@ -14722,7 +14154,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1472214154 },
1472314155 });
1472414156 const alloc = try block.addTy(.alloc, alloc_ty);
14725 const elem_ptr_ty = try pt.ptrTypeSema(.{
14157 const elem_ptr_ty = try pt.ptrType(.{
1472614158 .child = lhs_info.elem_type.toIntern(),
1472714159 .flags = .{ .address_space = ptr_as },
1472814160 });
......@@ -14761,7 +14193,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1476114193 const lhs_src = src;
1476214194 const rhs_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
1476314195
14764 const rhs = try sema.resolveInst(inst_data.operand);
14196 const rhs = sema.resolveInst(inst_data.operand);
1476514197 const rhs_ty = sema.typeOf(rhs);
1476614198 const rhs_scalar_ty = rhs_ty.scalarType(zcu);
1476714199
......@@ -14774,7 +14206,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1477414206
1477514207 if (rhs_scalar_ty.isAnyFloat()) {
1477614208 // We handle float negation here to ensure negative zero is represented in the bits.
14777 if (try sema.resolveValue(rhs)) |rhs_val| {
14209 if (sema.resolveValue(rhs)) |rhs_val| {
1477814210 const result = try arith.negateFloat(sema, rhs_ty, rhs_val);
1477914211 return Air.internedToRef(result.toIntern());
1478014212 }
......@@ -14794,7 +14226,7 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1479414226 const lhs_src = src;
1479514227 const rhs_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
1479614228
14797 const rhs = try sema.resolveInst(inst_data.operand);
14229 const rhs = sema.resolveInst(inst_data.operand);
1479814230 const rhs_ty = sema.typeOf(rhs);
1479914231 const rhs_scalar_ty = rhs_ty.scalarType(zcu);
1480014232
......@@ -14822,8 +14254,8 @@ fn zirArithmetic(
1482214254 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
1482314255 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
1482414256 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
14825 const lhs = try sema.resolveInst(extra.lhs);
14826 const rhs = try sema.resolveInst(extra.rhs);
14257 const lhs = sema.resolveInst(extra.lhs);
14258 const rhs = sema.resolveInst(extra.rhs);
1482714259
1482814260 return sema.analyzeArithmetic(block, zir_tag, lhs, rhs, src, lhs_src, rhs_src, safety);
1482914261}
......@@ -14836,8 +14268,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1483614268 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
1483714269 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
1483814270 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
14839 const lhs = try sema.resolveInst(extra.lhs);
14840 const rhs = try sema.resolveInst(extra.rhs);
14271 const lhs = sema.resolveInst(extra.lhs);
14272 const rhs = sema.resolveInst(extra.rhs);
1484114273 const lhs_ty = sema.typeOf(lhs);
1484214274 const rhs_ty = sema.typeOf(rhs);
1484314275 const lhs_zig_ty_tag = lhs_ty.zigTypeTag(zcu);
......@@ -14859,8 +14291,8 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1485914291
1486014292 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div);
1486114293
14862 const maybe_lhs_val = try sema.resolveValueResolveLazy(casted_lhs);
14863 const maybe_rhs_val = try sema.resolveValueResolveLazy(casted_rhs);
14294 const maybe_lhs_val = sema.resolveValue(casted_lhs);
14295 const maybe_rhs_val = sema.resolveValue(casted_rhs);
1486414296
1486514297 if ((lhs_ty.zigTypeTag(zcu) == .comptime_float and rhs_ty.zigTypeTag(zcu) == .comptime_int) or
1486614298 (lhs_ty.zigTypeTag(zcu) == .comptime_int and rhs_ty.zigTypeTag(zcu) == .comptime_float))
......@@ -14945,8 +14377,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1494514377 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);
1494614378 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);
1494714379 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
14948 const lhs = try sema.resolveInst(extra.lhs);
14949 const rhs = try sema.resolveInst(extra.rhs);
14380 const lhs = sema.resolveInst(extra.lhs);
14381 const rhs = sema.resolveInst(extra.rhs);
1495014382 const lhs_ty = sema.typeOf(lhs);
1495114383 const rhs_ty = sema.typeOf(rhs);
1495214384 const lhs_zig_ty_tag = lhs_ty.zigTypeTag(zcu);
......@@ -14968,8 +14400,8 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1496814400
1496914401 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div_exact);
1497014402
14971 const maybe_lhs_val = try sema.resolveValueResolveLazy(casted_lhs);
14972 const maybe_rhs_val = try sema.resolveValueResolveLazy(casted_rhs);
14403 const maybe_lhs_val = sema.resolveValue(casted_lhs);
14404 const maybe_rhs_val = sema.resolveValue(casted_rhs);
1497314405
1497414406 // Because `@divExact` can trigger Illegal Behavior, undefined operands trigger Illegal Behavior.
1497514407
......@@ -15041,8 +14473,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1504114473 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);
1504214474 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);
1504314475 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
15044 const lhs = try sema.resolveInst(extra.lhs);
15045 const rhs = try sema.resolveInst(extra.rhs);
14476 const lhs = sema.resolveInst(extra.lhs);
14477 const rhs = sema.resolveInst(extra.rhs);
1504614478 const lhs_ty = sema.typeOf(lhs);
1504714479 const rhs_ty = sema.typeOf(rhs);
1504814480 const lhs_zig_ty_tag = lhs_ty.zigTypeTag(zcu);
......@@ -15064,8 +14496,8 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1506414496
1506514497 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div_floor);
1506614498
15067 const maybe_lhs_val = try sema.resolveValueResolveLazy(casted_lhs);
15068 const maybe_rhs_val = try sema.resolveValueResolveLazy(casted_rhs);
14499 const maybe_lhs_val = sema.resolveValue(casted_lhs);
14500 const maybe_rhs_val = sema.resolveValue(casted_rhs);
1506914501
1507014502 const allow_div_zero = !is_int and
1507114503 resolved_type.toIntern() != .comptime_float_type and
......@@ -15106,8 +14538,8 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1510614538 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);
1510714539 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);
1510814540 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
15109 const lhs = try sema.resolveInst(extra.lhs);
15110 const rhs = try sema.resolveInst(extra.rhs);
14541 const lhs = sema.resolveInst(extra.lhs);
14542 const rhs = sema.resolveInst(extra.rhs);
1511114543 const lhs_ty = sema.typeOf(lhs);
1511214544 const rhs_ty = sema.typeOf(rhs);
1511314545 const lhs_zig_ty_tag = lhs_ty.zigTypeTag(zcu);
......@@ -15129,8 +14561,8 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1512914561
1513014562 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .div_trunc);
1513114563
15132 const maybe_lhs_val = try sema.resolveValueResolveLazy(casted_lhs);
15133 const maybe_rhs_val = try sema.resolveValueResolveLazy(casted_rhs);
14564 const maybe_lhs_val = sema.resolveValue(casted_lhs);
14565 const maybe_rhs_val = sema.resolveValue(casted_rhs);
1513414566
1513514567 const allow_div_zero = !is_int and
1513614568 resolved_type.toIntern() != .comptime_float_type and
......@@ -15317,8 +14749,8 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1531714749 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
1531814750 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
1531914751 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
15320 const lhs = try sema.resolveInst(extra.lhs);
15321 const rhs = try sema.resolveInst(extra.rhs);
14752 const lhs = sema.resolveInst(extra.lhs);
14753 const rhs = sema.resolveInst(extra.rhs);
1532214754 const lhs_ty = sema.typeOf(lhs);
1532314755 const rhs_ty = sema.typeOf(rhs);
1532414756 const lhs_zig_ty_tag = lhs_ty.zigTypeTag(zcu);
......@@ -15341,8 +14773,8 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1534114773
1534214774 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .mod_rem);
1534314775
15344 const maybe_lhs_val = try sema.resolveValueResolveLazy(casted_lhs);
15345 const maybe_rhs_val = try sema.resolveValueResolveLazy(casted_rhs);
14776 const maybe_lhs_val = sema.resolveValue(casted_lhs);
14777 const maybe_rhs_val = sema.resolveValue(casted_rhs);
1534614778
1534714779 const lhs_maybe_negative = a: {
1534814780 if (lhs_scalar_ty.isUnsignedInt(zcu)) break :a false;
......@@ -15418,8 +14850,8 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1541814850 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);
1541914851 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);
1542014852 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
15421 const lhs = try sema.resolveInst(extra.lhs);
15422 const rhs = try sema.resolveInst(extra.rhs);
14853 const lhs = sema.resolveInst(extra.lhs);
14854 const rhs = sema.resolveInst(extra.rhs);
1542314855 const lhs_ty = sema.typeOf(lhs);
1542414856 const rhs_ty = sema.typeOf(rhs);
1542514857 const lhs_zig_ty_tag = lhs_ty.zigTypeTag(zcu);
......@@ -15440,8 +14872,8 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1544014872
1544114873 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .mod);
1544214874
15443 const maybe_lhs_val = try sema.resolveValueResolveLazy(casted_lhs);
15444 const maybe_rhs_val = try sema.resolveValueResolveLazy(casted_rhs);
14875 const maybe_lhs_val = sema.resolveValue(casted_lhs);
14876 const maybe_rhs_val = sema.resolveValue(casted_rhs);
1544514877
1544614878 const allow_div_zero = !is_int and
1544714879 resolved_type.toIntern() != .comptime_float_type and
......@@ -15482,8 +14914,8 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1548214914 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);
1548314915 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);
1548414916 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
15485 const lhs = try sema.resolveInst(extra.lhs);
15486 const rhs = try sema.resolveInst(extra.rhs);
14917 const lhs = sema.resolveInst(extra.lhs);
14918 const rhs = sema.resolveInst(extra.rhs);
1548714919 const lhs_ty = sema.typeOf(lhs);
1548814920 const rhs_ty = sema.typeOf(rhs);
1548914921 const lhs_zig_ty_tag = lhs_ty.zigTypeTag(zcu);
......@@ -15504,8 +14936,8 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1550414936
1550514937 try sema.checkArithmeticOp(block, src, scalar_tag, lhs_zig_ty_tag, rhs_zig_ty_tag, .rem);
1550614938
15507 const maybe_lhs_val = try sema.resolveValueResolveLazy(casted_lhs);
15508 const maybe_rhs_val = try sema.resolveValueResolveLazy(casted_rhs);
14939 const maybe_lhs_val = sema.resolveValue(casted_lhs);
14940 const maybe_rhs_val = sema.resolveValue(casted_rhs);
1550914941
1551014942 const allow_div_zero = !is_int and
1551114943 resolved_type.toIntern() != .comptime_float_type and
......@@ -15553,8 +14985,8 @@ fn zirOverflowArithmetic(
1555314985 const lhs_src = block.builtinCallArgSrc(extra.node, 0);
1555414986 const rhs_src = block.builtinCallArgSrc(extra.node, 1);
1555514987
15556 const uncasted_lhs = try sema.resolveInst(extra.lhs);
15557 const uncasted_rhs = try sema.resolveInst(extra.rhs);
14988 const uncasted_lhs = sema.resolveInst(extra.lhs);
14989 const uncasted_rhs = sema.resolveInst(extra.rhs);
1555814990
1555914991 const lhs_ty = sema.typeOf(uncasted_lhs);
1556014992 const rhs_ty = sema.typeOf(uncasted_rhs);
......@@ -15584,8 +15016,8 @@ fn zirOverflowArithmetic(
1558415016 return sema.fail(block, src, "expected vector of integers or integer tag type, found '{f}'", .{dest_ty.fmt(pt)});
1558515017 }
1558615018
15587 const maybe_lhs_val = try sema.resolveValue(lhs);
15588 const maybe_rhs_val = try sema.resolveValue(rhs);
15019 const maybe_lhs_val = sema.resolveValue(lhs);
15020 const maybe_rhs_val = sema.resolveValue(rhs);
1558915021
1559015022 const tuple_ty = try pt.overflowArithmeticTupleType(dest_ty);
1559115023 const overflow_ty: Type = .fromInterned(ip.indexToKey(tuple_ty.toIntern()).tuple_type.types.get(ip)[1]);
......@@ -15601,12 +15033,12 @@ fn zirOverflowArithmetic(
1560115033 // to the result, even if it is undefined..
1560215034 // Otherwise, if either of the argument is undefined, undefined is returned.
1560315035 if (maybe_lhs_val) |lhs_val| {
15604 if (!lhs_val.isUndef(zcu) and (try lhs_val.compareAllWithZeroSema(.eq, pt))) {
15036 if (!lhs_val.isUndef(zcu) and lhs_val.compareAllWithZero(.eq, zcu)) {
1560515037 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = rhs };
1560615038 }
1560715039 }
1560815040 if (maybe_rhs_val) |rhs_val| {
15609 if (!rhs_val.isUndef(zcu) and (try rhs_val.compareAllWithZeroSema(.eq, pt))) {
15041 if (!rhs_val.isUndef(zcu) and rhs_val.compareAllWithZero(.eq, zcu)) {
1561015042 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs };
1561115043 }
1561215044 }
......@@ -15627,7 +15059,7 @@ fn zirOverflowArithmetic(
1562715059 if (maybe_rhs_val) |rhs_val| {
1562815060 if (rhs_val.isUndef(zcu)) {
1562915061 break :result .{ .overflow_bit = .undef, .wrapped = .undef };
15630 } else if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
15062 } else if (rhs_val.compareAllWithZero(.eq, zcu)) {
1563115063 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs };
1563215064 } else if (maybe_lhs_val) |lhs_val| {
1563315065 if (lhs_val.isUndef(zcu)) {
......@@ -15642,12 +15074,12 @@ fn zirOverflowArithmetic(
1564215074 .mul_with_overflow => {
1564315075 // If either of the arguments is zero, the result is zero and no overflow occured.
1564415076 if (maybe_lhs_val) |lhs_val| {
15645 if (!lhs_val.isUndef(zcu) and try lhs_val.compareAllWithZeroSema(.eq, pt)) {
15077 if (!lhs_val.isUndef(zcu) and lhs_val.compareAllWithZero(.eq, zcu)) {
1564615078 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs };
1564715079 }
1564815080 }
1564915081 if (maybe_rhs_val) |rhs_val| {
15650 if (!rhs_val.isUndef(zcu) and try rhs_val.compareAllWithZeroSema(.eq, pt)) {
15082 if (!rhs_val.isUndef(zcu) and rhs_val.compareAllWithZero(.eq, zcu)) {
1565115083 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = rhs };
1565215084 }
1565315085 }
......@@ -15694,10 +15126,10 @@ fn zirOverflowArithmetic(
1569415126 const bits = scalar_ty.intInfo(zcu).bits;
1569515127 switch (rhs_ty.zigTypeTag(zcu)) {
1569615128 .int, .comptime_int => {
15697 switch (try rhs_val.orderAgainstZeroSema(pt)) {
15129 switch (Value.order(rhs_val, .zero_comptime_int, zcu)) {
1569815130 .gt => {
1569915131 var rhs_space: Value.BigIntSpace = undefined;
15700 const rhs_bigint = try rhs_val.toBigIntSema(&rhs_space, pt);
15132 const rhs_bigint = rhs_val.toBigInt(&rhs_space, zcu);
1570115133 if (rhs_bigint.orderAgainstScalar(bits) != .lt) {
1570215134 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, null);
1570315135 }
......@@ -15711,10 +15143,10 @@ fn zirOverflowArithmetic(
1571115143 for (0..rhs_ty.vectorLen(zcu)) |elem_idx| {
1571215144 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
1571315145 if (rhs_elem.isUndef(zcu)) return sema.failWithUseOfUndef(block, rhs_src, elem_idx);
15714 switch (try rhs_elem.orderAgainstZeroSema(pt)) {
15146 switch (Value.order(rhs_elem, .zero_comptime_int, zcu)) {
1571515147 .gt => {
1571615148 var rhs_elem_space: Value.BigIntSpace = undefined;
15717 const rhs_elem_bigint = try rhs_elem.toBigIntSema(&rhs_elem_space, pt);
15149 const rhs_elem_bigint = rhs_elem.toBigInt(&rhs_elem_space, zcu);
1571815150 if (rhs_elem_bigint.orderAgainstScalar(bits) != .lt) {
1571915151 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_elem, rhs_src, elem_idx);
1572015152 }
......@@ -15728,7 +15160,7 @@ fn zirOverflowArithmetic(
1572815160 },
1572915161 else => unreachable,
1573015162 }
15731 if (try rhs_val.compareAllWithZeroSema(.eq, pt)) {
15163 if (rhs_val.compareAllWithZero(.eq, zcu)) {
1573215164 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs };
1573315165 }
1573415166 } else {
......@@ -15737,7 +15169,7 @@ fn zirOverflowArithmetic(
1573715169 }
1573815170 if (maybe_lhs_val) |lhs_val| {
1573915171 try sema.checkAllScalarsDefined(block, lhs_src, lhs_val);
15740 if (try lhs_val.compareAllWithZeroSema(.eq, pt)) {
15172 if (lhs_val.compareAllWithZero(.eq, zcu)) {
1574115173 break :result .{ .overflow_bit = try sema.splat(overflow_ty, .zero_u1), .inst = lhs };
1574215174 }
1574315175 }
......@@ -15767,7 +15199,7 @@ fn zirOverflowArithmetic(
1576715199 };
1576815200
1576915201 if (result.inst != .none) {
15770 if (try sema.resolveValue(result.inst)) |some| {
15202 if (sema.resolveValue(result.inst)) |some| {
1577115203 result.wrapped = some;
1577215204 result.inst = .none;
1577315205 }
......@@ -15817,22 +15249,45 @@ fn analyzeArithmetic(
1581715249 if (zir_tag != .sub) {
1581815250 return sema.failWithInvalidPtrArithmetic(block, src, "pointer-pointer", "subtraction");
1581915251 }
15820 if (!lhs_ty.elemType2(zcu).eql(rhs_ty.elemType2(zcu), zcu)) {
15252
15253 // TODO: these semantics are really weird. Pointer subtraction works in increments
15254 // of the pointer child for indexable pointers (excluding pointers to vectors),
15255 // which makes sense, but we also allow it for arbitrary single-item pointers, which
15256 // leads to the weird result that subtraction of '*T' works completely differently
15257 // depending on whether 'T' is an array. That seems dangerous and confusing, and
15258 // requires the odd logic below. This behavior originally came from a now-removed
15259 // function `Type.elemType2`, which was removed precisely *because* the thing it did
15260 // wasn't really well-defined; for that reason, these semantics were probably
15261 // largely accidental to begin with. We should change the langauge to avoid this
15262 // confusing behavior. For instance, perhaps pointer subtraction should only work on
15263 // indexable pointers.
15264 const lhs_elem_ty = ty: {
15265 const ptr_elem_ty = lhs_ty.childType(zcu);
15266 if (lhs_ty.ptrSize(zcu) == .one and ptr_elem_ty.zigTypeTag(zcu) == .array) break :ty ptr_elem_ty.childType(zcu);
15267 break :ty ptr_elem_ty;
15268 };
15269 const rhs_elem_ty = ty: {
15270 const ptr_elem_ty = rhs_ty.childType(zcu);
15271 if (rhs_ty.ptrSize(zcu) == .one and ptr_elem_ty.zigTypeTag(zcu) == .array) break :ty ptr_elem_ty.childType(zcu);
15272 break :ty ptr_elem_ty;
15273 };
15274 if (lhs_elem_ty.toIntern() != rhs_elem_ty.toIntern()) {
1582115275 return sema.fail(block, src, "incompatible pointer arithmetic operands '{f}' and '{f}'", .{
1582215276 lhs_ty.fmt(pt), rhs_ty.fmt(pt),
1582315277 });
1582415278 }
1582515279
15826 const elem_size = lhs_ty.elemType2(zcu).abiSize(zcu);
15280 try sema.ensureLayoutResolved(lhs_elem_ty, src, .ptr_offset);
15281 const elem_size = lhs_elem_ty.abiSize(zcu);
1582715282 if (elem_size == 0) {
15828 return sema.fail(block, src, "pointer arithmetic requires element type '{f}' to have runtime bits", .{
15829 lhs_ty.elemType2(zcu).fmt(pt),
15283 return sema.fail(block, src, "pointer subtraction requires element type '{f}' to have runtime bits", .{
15284 lhs_elem_ty.fmt(pt),
1583015285 });
1583115286 }
1583215287
1583315288 const runtime_src = runtime_src: {
15834 if (try sema.resolveValue(lhs)) |lhs_value| {
15835 if (try sema.resolveValue(rhs)) |rhs_value| {
15289 if (sema.resolveValue(lhs)) |lhs_value| {
15290 if (sema.resolveValue(rhs)) |rhs_value| {
1583615291 const lhs_ptr = switch (zcu.intern_pool.indexToKey(lhs_value.toIntern())) {
1583715292 .undef => return sema.failWithUseOfUndef(block, lhs_src, null),
1583815293 .ptr => |ptr| ptr,
......@@ -15875,12 +15330,8 @@ fn analyzeArithmetic(
1587515330 else => return sema.failWithInvalidPtrArithmetic(block, src, "pointer-integer", "addition and subtraction"),
1587615331 };
1587715332
15878 if (!try lhs_ty.elemType2(zcu).hasRuntimeBitsSema(pt)) {
15879 return sema.fail(block, src, "pointer arithmetic requires element type '{f}' to have runtime bits", .{
15880 lhs_ty.elemType2(zcu).fmt(pt),
15881 });
15882 }
15883 return sema.analyzePtrArithmetic(block, src, lhs, rhs, air_tag, lhs_src, rhs_src);
15333 try sema.ensureLayoutResolved(lhs_ty.childType(zcu), src, .ptr_offset);
15334 return sema.analyzePtrArithmetic(block, src, lhs, rhs, air_tag, rhs_src);
1588415335 },
1588515336 }
1588615337 }
......@@ -15915,8 +15366,8 @@ fn analyzeArithmetic(
1591515366 else => unreachable,
1591615367 };
1591715368
15918 const maybe_lhs_val = try sema.resolveValueResolveLazy(casted_lhs);
15919 const maybe_rhs_val = try sema.resolveValueResolveLazy(casted_rhs);
15369 const maybe_lhs_val = sema.resolveValue(casted_lhs);
15370 const maybe_rhs_val = sema.resolveValue(casted_rhs);
1592015371
1592115372 if (maybe_lhs_val) |lhs_val| {
1592215373 if (maybe_rhs_val) |rhs_val| {
......@@ -15972,6 +15423,7 @@ fn analyzeArithmetic(
1597215423 return block.addBinOp(air_tag, casted_lhs, casted_rhs);
1597315424}
1597415425
15426/// Asserts that the layout of the pointer child type is already resolved.
1597515427fn analyzePtrArithmetic(
1597615428 sema: *Sema,
1597715429 block: *Block,
......@@ -15979,7 +15431,6 @@ fn analyzePtrArithmetic(
1597915431 ptr: Air.Inst.Ref,
1598015432 uncasted_offset: Air.Inst.Ref,
1598115433 air_tag: Air.Inst.Tag,
15982 ptr_src: LazySrcLoc,
1598315434 offset_src: LazySrcLoc,
1598415435) CompileError!Air.Inst.Ref {
1598515436 // TODO if the operand is comptime-known to be negative, or is a negative int,
......@@ -15987,81 +15438,55 @@ fn analyzePtrArithmetic(
1598715438 const offset = try sema.coerce(block, .usize, uncasted_offset, offset_src);
1598815439 const pt = sema.pt;
1598915440 const zcu = pt.zcu;
15990 const opt_ptr_val = try sema.resolveValue(ptr);
15991 const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset);
1599215441 const ptr_ty = sema.typeOf(ptr);
1599315442 const ptr_info = ptr_ty.ptrInfo(zcu);
1599415443 assert(ptr_info.flags.size == .many or ptr_info.flags.size == .c);
1599515444
15996 if ((try sema.typeHasOnePossibleValue(.fromInterned(ptr_info.child))) != null) {
15997 // Offset will be multiplied by zero, so result is the same as the base pointer.
15998 return ptr;
15445 const maybe_index: ?u64 = if (try sema.resolveDefinedValue(block, offset_src, offset)) |val| off: {
15446 break :off val.toUnsignedInt(zcu);
15447 } else null;
15448
15449 const elem_ty: Type = .fromInterned(ptr_info.child);
15450 elem_ty.assertHasLayout(zcu);
15451
15452 switch (elem_ty.classify(zcu)) {
15453 .no_possible_value, .one_possible_value => {
15454 // Offset will be multiplied by zero, so result is the same as the base pointer.
15455 return ptr;
15456 },
15457 else => {},
1599915458 }
1600015459
16001 const new_ptr_ty = t: {
16002 // Calculate the new pointer alignment.
16003 // This code is duplicated in `Type.elemPtrType`.
16004 if (ptr_info.flags.alignment == .none) {
16005 // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness.
16006 break :t ptr_ty;
16007 }
16008 // If the addend is not a comptime-known value we can still count on
16009 // it being a multiple of the type size.
16010 const elem_size = try Type.fromInterned(ptr_info.child).abiSizeSema(pt);
16011 const addend = if (opt_off_val) |off_val| a: {
16012 const off_int = try sema.usizeCast(block, offset_src, try off_val.toUnsignedIntSema(pt));
16013 break :a elem_size * off_int;
16014 } else elem_size;
16015
16016 // The resulting pointer is aligned to the lcd between the offset (an
16017 // arbitrary number) and the alignment factor (always a power of two,
16018 // non zero).
16019 const new_align: Alignment = @enumFromInt(@min(
16020 @ctz(addend),
16021 @intFromEnum(ptr_info.flags.alignment),
16022 ));
16023 assert(new_align != .none);
16024
16025 break :t try pt.ptrTypeSema(.{
16026 .child = ptr_info.child,
16027 .sentinel = ptr_info.sentinel,
16028 .flags = .{
16029 .size = ptr_info.flags.size,
16030 .alignment = new_align,
16031 .is_const = ptr_info.flags.is_const,
16032 .is_volatile = ptr_info.flags.is_volatile,
16033 .is_allowzero = ptr_info.flags.is_allowzero,
16034 .address_space = ptr_info.flags.address_space,
16035 },
16036 });
16037 };
15460 const elem_ptr_ty = try ptr_ty.elemPtrType(maybe_index, pt);
15461 // `elem_ptr_ty` is a single-item pointer, but we want a many-item or C pointer, and to preserve
15462 // any input sentinel.
15463 const new_ptr_ty = try pt.ptrType(info: {
15464 var info = elem_ptr_ty.ptrInfo(zcu);
15465 info.flags.size = ptr_info.flags.size;
15466 info.sentinel = ptr_info.sentinel;
15467 break :info info;
15468 });
1603815469
16039 const runtime_src = rs: {
16040 if (opt_ptr_val) |ptr_val| {
16041 if (opt_off_val) |offset_val| {
16042 if (ptr_val.isUndef(zcu)) return pt.undefRef(new_ptr_ty);
16043
16044 const offset_int = try sema.usizeCast(block, offset_src, try offset_val.toUnsignedIntSema(pt));
16045 if (offset_int == 0) return ptr;
16046 if (air_tag == .ptr_sub) {
16047 const elem_size = try Type.fromInterned(ptr_info.child).abiSizeSema(pt);
16048 const new_ptr_val = try sema.ptrSubtract(block, op_src, ptr_val, offset_int * elem_size, new_ptr_ty);
16049 return Air.internedToRef(new_ptr_val.toIntern());
16050 } else {
16051 const new_ptr_val = try pt.getCoerced(try ptr_val.ptrElem(offset_int, pt), new_ptr_ty);
16052 return Air.internedToRef(new_ptr_val.toIntern());
16053 }
16054 } else break :rs offset_src;
16055 } else break :rs ptr_src;
16056 };
15470 ct: {
15471 const ptr_val = sema.resolveValue(ptr) orelse break :ct;
15472 if (ptr_val.isUndef(zcu)) return pt.undefRef(new_ptr_ty);
15473 const index = maybe_index orelse break :ct;
15474
15475 if (index == 0) return ptr;
15476 if (air_tag == .ptr_sub) {
15477 const elem_size = elem_ty.abiSize(zcu);
15478 return .fromValue(try sema.ptrSubtract(block, op_src, ptr_val, index * elem_size, new_ptr_ty));
15479 } else {
15480 return .fromValue(try pt.getCoerced(try ptr_val.ptrElem(index, pt), new_ptr_ty));
15481 }
15482 }
1605715483
16058 try sema.requireRuntimeBlock(block, op_src, runtime_src);
1605915484 try sema.checkLogicalPtrOperation(block, op_src, ptr_ty);
1606015485
1606115486 return block.addInst(.{
1606215487 .tag = air_tag,
1606315488 .data = .{ .ty_pl = .{
16064 .ty = Air.internedToRef(new_ptr_ty.toIntern()),
15489 .ty = .fromType(new_ptr_ty),
1606515490 .payload = try sema.addExtra(Air.Bin{
1606615491 .lhs = ptr,
1606715492 .rhs = offset,
......@@ -16077,7 +15502,7 @@ fn zirLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.In
1607715502 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1607815503 const src = block.nodeOffset(inst_data.src_node);
1607915504 const ptr_src = src; // TODO better source location
16080 const ptr = try sema.resolveInst(inst_data.operand);
15505 const ptr = sema.resolveInst(inst_data.operand);
1608115506 return sema.analyzeLoad(block, src, ptr, ptr_src);
1608215507}
1608315508
......@@ -16151,7 +15576,7 @@ fn zirAsm(
1615115576 const out_ty = try sema.resolveType(block, ret_ty_src, output.data.operand);
1615215577 expr_ty = Air.internedToRef(out_ty.toIntern());
1615315578 } else {
16154 const inst = try sema.resolveInst(output.data.operand);
15579 const inst = sema.resolveInst(output.data.operand);
1615515580 if (!sema.checkRuntimeValue(inst)) {
1615615581 const output_name = try ip.getOrPutString(gpa, io, pt.tid, name, .no_embedded_nulls);
1615715582 return sema.failWithContainsReferenceToComptimeVar(block, output_src, output_name, "assembly output", .fromInterned(inst.toInterned().?));
......@@ -16181,7 +15606,7 @@ fn zirAsm(
1618115606 } });
1618215607 extra_i = input.end;
1618315608
16184 const uncasted_arg = try sema.resolveInst(input.data.operand);
15609 const uncasted_arg = sema.resolveInst(input.data.operand);
1618515610 const name = sema.code.nullTerminatedString(input.data.name);
1618615611 if (!sema.checkRuntimeValue(uncasted_arg)) {
1618715612 const input_name = try ip.getOrPutString(gpa, io, pt.tid, name, .no_embedded_nulls);
......@@ -16204,7 +15629,7 @@ fn zirAsm(
1620415629 const clobbers = if (extra.data.clobbers == .none) empty: {
1620515630 const clobbers_ty = try sema.getBuiltinType(src, .@"assembly.Clobbers");
1620615631 break :empty try sema.structInitEmpty(block, clobbers_ty, src, src);
16207 } else try sema.resolveInst(extra.data.clobbers); // Already coerced by AstGen.
15632 } else sema.resolveInst(extra.data.clobbers); // Already coerced by AstGen.
1620815633 const clobbers_val = try sema.resolveConstDefinedValue(block, src, clobbers, .{ .simple = .clobber });
1620915634 needed_capacity += asm_source.len / 4 + 1;
1621015635
......@@ -16248,6 +15673,7 @@ fn zirAsm(
1624815673 buffer[input.c.len + 1 + input.n.len] = 0;
1624915674 sema.air_extra.items.len += (input.c.len + input.n.len + (2 + 3)) / 4;
1625015675 }
15676 if (try expr_ty.toType().onePossibleValue(pt)) |opv| return .fromValue(opv);
1625115677 return asm_air;
1625215678}
1625315679
......@@ -16269,8 +15695,8 @@ fn zirCmpEq(
1626915695 const src: LazySrcLoc = block.nodeOffset(inst_data.src_node);
1627015696 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
1627115697 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
16272 const lhs = try sema.resolveInst(extra.lhs);
16273 const rhs = try sema.resolveInst(extra.rhs);
15698 const lhs = sema.resolveInst(extra.lhs);
15699 const rhs = sema.resolveInst(extra.rhs);
1627415700
1627515701 const lhs_ty = sema.typeOf(lhs);
1627615702 const rhs_ty = sema.typeOf(rhs);
......@@ -16283,10 +15709,10 @@ fn zirCmpEq(
1628315709
1628415710 // comparing null with optionals
1628515711 if (lhs_ty_tag == .null and (rhs_ty_tag == .optional or rhs_ty.isCPtr(zcu))) {
16286 return sema.analyzeIsNull(block, rhs, op == .neq);
15712 return sema.analyzeIsNull(block, src, rhs, op == .neq);
1628715713 }
1628815714 if (rhs_ty_tag == .null and (lhs_ty_tag == .optional or lhs_ty.isCPtr(zcu))) {
16289 return sema.analyzeIsNull(block, lhs, op == .neq);
15715 return sema.analyzeIsNull(block, src, lhs, op == .neq);
1629015716 }
1629115717
1629215718 if (lhs_ty_tag == .null or rhs_ty_tag == .null) {
......@@ -16303,8 +15729,8 @@ fn zirCmpEq(
1630315729
1630415730 if (lhs_ty_tag == .error_set and rhs_ty_tag == .error_set) {
1630515731 const runtime_src: LazySrcLoc = src: {
16306 if (try sema.resolveValue(lhs)) |lval| {
16307 if (try sema.resolveValue(rhs)) |rval| {
15732 if (sema.resolveValue(lhs)) |lval| {
15733 if (sema.resolveValue(rhs)) |rval| {
1630815734 if (lval.isUndef(zcu) or rval.isUndef(zcu)) return .undef_bool;
1630915735 const lkey = zcu.intern_pool.indexToKey(lval.toIntern());
1631015736 const rkey = zcu.intern_pool.indexToKey(rval.toIntern());
......@@ -16323,8 +15749,8 @@ fn zirCmpEq(
1632315749 return block.addBinOp(air_tag, lhs, rhs);
1632415750 }
1632515751 if (lhs_ty_tag == .type and rhs_ty_tag == .type) {
16326 const lhs_as_type = try sema.analyzeAsType(block, lhs_src, lhs);
16327 const rhs_as_type = try sema.analyzeAsType(block, rhs_src, rhs);
15752 const lhs_as_type = try sema.analyzeAsType(block, lhs_src, .type, lhs);
15753 const rhs_as_type = try sema.analyzeAsType(block, rhs_src, .type, rhs);
1632815754 return if (lhs_as_type.eql(rhs_as_type, zcu) == (op == .eq)) .bool_true else .bool_false;
1632915755 }
1633015756 return sema.analyzeCmp(block, src, lhs, rhs, op, lhs_src, rhs_src, true);
......@@ -16343,7 +15769,6 @@ fn analyzeCmpUnionTag(
1634315769 const pt = sema.pt;
1634415770 const zcu = pt.zcu;
1634515771 const union_ty = sema.typeOf(un);
16346 try union_ty.resolveFields(pt);
1634715772 const union_tag_ty = union_ty.unionTagType(zcu) orelse {
1634815773 const msg = msg: {
1634915774 const msg = try sema.errMsg(un_src, "comparison of union and enum literal is only valid for tagged union types", .{});
......@@ -16358,10 +15783,10 @@ fn analyzeCmpUnionTag(
1635815783 const coerced_tag = try sema.coerce(block, union_tag_ty, tag, tag_src);
1635915784 const coerced_union = try sema.coerce(block, union_tag_ty, un, un_src);
1636015785
16361 if (try sema.resolveValue(coerced_tag)) |enum_val| {
15786 if (sema.resolveValue(coerced_tag)) |enum_val| {
1636215787 if (enum_val.isUndef(zcu)) return .undef_bool;
1636315788 const field_ty = union_ty.unionFieldType(enum_val, zcu).?;
16364 if (field_ty.zigTypeTag(zcu) == .noreturn) {
15789 if (field_ty.classify(zcu) == .no_possible_value) {
1636515790 return .bool_false;
1636615791 }
1636715792 }
......@@ -16384,8 +15809,8 @@ fn zirCmp(
1638415809 const src: LazySrcLoc = block.nodeOffset(inst_data.src_node);
1638515810 const lhs_src = block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
1638615811 const rhs_src = block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
16387 const lhs = try sema.resolveInst(extra.lhs);
16388 const rhs = try sema.resolveInst(extra.rhs);
15812 const lhs = sema.resolveInst(extra.lhs);
15813 const rhs = sema.resolveInst(extra.rhs);
1638915814 return sema.analyzeCmp(block, src, lhs, rhs, op, lhs_src, rhs_src, false);
1639015815}
1639115816
......@@ -16468,8 +15893,8 @@ fn cmpSelf(
1646815893 const zcu = pt.zcu;
1646915894 const resolved_type = sema.typeOf(casted_lhs);
1647015895
16471 const maybe_lhs_val = try sema.resolveValue(casted_lhs);
16472 const maybe_rhs_val = try sema.resolveValue(casted_rhs);
15896 const maybe_lhs_val = sema.resolveValue(casted_lhs);
15897 const maybe_rhs_val = sema.resolveValue(casted_rhs);
1647315898 if (maybe_lhs_val) |v| if (v.isUndef(zcu)) return .undef_bool;
1647415899 if (maybe_rhs_val) |v| if (v.isUndef(zcu)) return .undef_bool;
1647515900
......@@ -16534,42 +15959,26 @@ fn runtimeBoolCmp(
1653415959
1653515960fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1653615961 const pt = sema.pt;
15962 const zcu = pt.zcu;
1653715963 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1653815964 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
1653915965 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
16540 switch (ty.zigTypeTag(pt.zcu)) {
16541 .@"fn",
16542 .noreturn,
16543 .undefined,
16544 .null,
16545 .@"opaque",
16546 => return sema.fail(block, operand_src, "no size available for type '{f}'", .{ty.fmt(pt)}),
15966 try sema.ensureLayoutResolved(ty, operand_src, .size_of);
15967 switch (ty.classify(zcu)) {
15968 .no_possible_value,
15969 => return sema.fail(block, operand_src, "no size available for uninstantiable type '{f}'", .{ty.fmt(pt)}),
1654715970
16548 .type,
16549 .enum_literal,
16550 .comptime_float,
16551 .comptime_int,
16552 .void,
16553 => return .zero,
15971 .partially_comptime,
15972 .fully_comptime,
15973 => return sema.fail(block, operand_src, "no size available for comptime-only type '{f}'", .{ty.fmt(pt)}),
1655415974
16555 .bool,
16556 .int,
16557 .float,
16558 .pointer,
16559 .array,
16560 .@"struct",
16561 .optional,
16562 .error_union,
16563 .error_set,
16564 .@"enum",
16565 .@"union",
16566 .vector,
16567 .frame,
16568 .@"anyframe",
16569 => {},
15975 .one_possible_value => {
15976 assert(ty.abiSize(zcu) == 0);
15977 return .zero;
15978 },
15979
15980 .runtime => return .fromValue(try pt.intValue(.comptime_int, ty.abiSize(zcu))),
1657015981 }
16571 const val = try ty.abiSizeLazy(pt);
16572 return Air.internedToRef(val.toIntern());
1657315982}
1657415983
1657515984fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -16584,12 +15993,12 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1658415993 .undefined,
1658515994 .null,
1658615995 .@"opaque",
16587 => return sema.fail(block, operand_src, "no size available for type '{f}'", .{operand_ty.fmt(pt)}),
16588
1658915996 .type,
1659015997 .enum_literal,
1659115998 .comptime_float,
1659215999 .comptime_int,
16000 => return sema.fail(block, operand_src, "no size available for type '{f}'", .{operand_ty.fmt(pt)}),
16001
1659316002 .void,
1659416003 => return .zero,
1659516004
......@@ -16609,8 +16018,8 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1660916018 .@"anyframe",
1661016019 => {},
1661116020 }
16612 const bit_size = try operand_ty.bitSizeSema(pt);
16613 return pt.intRef(.comptime_int, bit_size);
16021 try sema.ensureLayoutResolved(operand_ty, operand_src, .size_of);
16022 return .fromValue(try pt.intValue(.comptime_int, operand_ty.bitSize(zcu)));
1661416023}
1661516024
1661616025fn zirThis(
......@@ -16619,34 +16028,7 @@ fn zirThis(
1661916028 extended: Zir.Inst.Extended.InstData,
1662016029) CompileError!Air.Inst.Ref {
1662116030 _ = extended;
16622 const pt = sema.pt;
16623 const zcu = pt.zcu;
16624 const namespace = pt.zcu.namespacePtr(block.namespace);
16625
16626 switch (pt.zcu.intern_pool.indexToKey(namespace.owner_type)) {
16627 .opaque_type => {
16628 // Opaque types are never outdated since they don't undergo type resolution, so nothing to do!
16629 return Air.internedToRef(namespace.owner_type);
16630 },
16631 .struct_type, .union_type => {
16632 const new_ty = try pt.ensureTypeUpToDate(namespace.owner_type);
16633 try sema.declareDependency(.{ .interned = new_ty });
16634 return Air.internedToRef(new_ty);
16635 },
16636 .enum_type => {
16637 const new_ty = try pt.ensureTypeUpToDate(namespace.owner_type);
16638 try sema.declareDependency(.{ .interned = new_ty });
16639 // Since this is an enum, it has to be resolved immediately.
16640 // `ensureTypeUpToDate` has resolved the new type if necessary.
16641 // We just need to check for resolution failures.
16642 const ty_unit: AnalUnit = .wrap(.{ .type = new_ty });
16643 if (zcu.failed_analysis.contains(ty_unit) or zcu.transitive_failed_analysis.contains(ty_unit)) {
16644 return error.AnalysisFail;
16645 }
16646 return Air.internedToRef(new_ty);
16647 },
16648 else => unreachable,
16649 }
16031 return .fromIntern(sema.pt.zcu.namespacePtr(block.namespace).owner_type);
1665016032}
1665116033
1665216034fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
......@@ -16739,7 +16121,7 @@ fn zirRetAddr(
1673916121 _ = sema;
1674016122 _ = extended;
1674116123 if (block.isComptime()) {
16742 // TODO: we could give a meaningful lazy value here. #14938
16124 // TODO: we could give a meaningful value here. #14938
1674316125 return .zero_usize;
1674416126 } else {
1674516127 return block.addNoOp(.ret_addr);
......@@ -16882,6 +16264,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1688216264 const type_info_ty = try sema.getBuiltinType(src, .Type);
1688316265 const type_info_tag_ty = type_info_ty.unionTagType(zcu).?;
1688416266
16267 try sema.ensureLayoutResolved(ty, src, .type_info);
16268
1688516269 if (ty.typeDeclInst(zcu)) |type_decl_inst| {
1688616270 try sema.declareDependency(.{ .namespace = type_decl_inst });
1688716271 }
......@@ -16896,7 +16280,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1689616280 .undefined,
1689716281 .null,
1689816282 .enum_literal,
16899 => |type_info_tag| return unionInitFromEnumTag(sema, block, src, type_info_ty, @intFromEnum(type_info_tag), .void_value),
16283 => |type_info_tag| return .fromValue(try pt.unionValue(
16284 type_info_ty,
16285 Value.uninterpret(type_info_tag, type_info_tag_ty, pt) catch |err| switch (err) {
16286 error.TypeMismatch => @panic("std.builtin is corrupt"),
16287 error.OutOfMemory => |e| return e,
16288 },
16289 .void,
16290 )),
1690016291
1690116292 .@"fn" => {
1690216293 const fn_info_ty = try sema.getBuiltinType(src, .@"Type.Fn");
......@@ -16904,19 +16295,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1690416295
1690516296 const func_ty_info = zcu.typeToFunc(ty).?;
1690616297 const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);
16907 for (param_vals, 0..) |*param_val, i| {
16908 const param_ty = func_ty_info.param_types.get(ip)[i];
16298 var func_is_generic = false;
16299
16300 for (param_vals, 0..) |*param_val, param_index| {
16301 const param_ty = func_ty_info.param_types.get(ip)[param_index];
1690916302 const is_generic = param_ty == .generic_poison_type;
16303 const is_noalias, const is_comptime = flags: {
16304 const i = std.math.cast(u5, param_index) orelse break :flags .{ false, false };
16305 break :flags .{ func_ty_info.paramIsNoalias(i), func_ty_info.paramIsComptime(i) };
16306 };
16307
16308 if (is_generic or is_comptime or Type.fromInterned(param_ty).comptimeOnly(zcu)) {
16309 func_is_generic = true;
16310 }
16311
1691016312 const param_ty_val = try pt.intern(.{ .opt = .{
1691116313 .ty = try pt.intern(.{ .opt_type = .type_type }),
1691216314 .val = if (is_generic) .none else param_ty,
1691316315 } });
1691416316
16915 const is_noalias = blk: {
16916 const index = std.math.cast(u5, i) orelse break :blk false;
16917 break :blk @as(u1, @truncate(func_ty_info.noalias_bits >> index)) != 0;
16918 };
16919
1692016317 const param_fields = .{
1692116318 // is_generic: bool,
1692216319 Value.makeBool(is_generic).toIntern(),
......@@ -16934,7 +16331,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1693416331 .child = param_info_ty.toIntern(),
1693516332 });
1693616333 const new_decl_val = (try pt.aggregateValue(new_decl_ty, param_vals)).toIntern();
16937 const slice_ty = (try pt.ptrTypeSema(.{
16334 const slice_ty = (try pt.ptrType(.{
1693816335 .child = param_info_ty.toIntern(),
1693916336 .flags = .{
1694016337 .size = .slice,
......@@ -16956,18 +16353,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1695616353 } });
1695716354 };
1695816355
16356 const ret_ty_is_generic = generic: {
16357 const ret_ty: Type = .fromInterned(func_ty_info.return_type);
16358 if (ret_ty.toIntern() == .generic_poison_type or
16359 (ret_ty.zigTypeTag(zcu) == .error_union and
16360 ret_ty.errorUnionPayload(zcu).toIntern() == .generic_poison_type))
16361 {
16362 break :generic true;
16363 }
16364 break :generic false;
16365 };
16366 if (ret_ty_is_generic or Type.fromInterned(func_ty_info.return_type).comptimeOnly(zcu)) {
16367 func_is_generic = true;
16368 }
16369
1695916370 const ret_ty_opt = try pt.intern(.{ .opt = .{
1696016371 .ty = try pt.intern(.{ .opt_type = .type_type }),
16961 .val = opt_val: {
16962 const ret_ty: Type = .fromInterned(func_ty_info.return_type);
16963 if (ret_ty.toIntern() == .generic_poison_type) break :opt_val .none;
16964 if (ret_ty.zigTypeTag(zcu) == .error_union) {
16965 if (ret_ty.errorUnionPayload(zcu).toIntern() == .generic_poison_type) {
16966 break :opt_val .none;
16967 }
16968 }
16969 break :opt_val ret_ty.toIntern();
16970 },
16372 .val = if (ret_ty_is_generic) .none else func_ty_info.return_type,
1697116373 } });
1697216374
1697316375 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
......@@ -16980,7 +16382,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1698016382 // calling_convention: CallingConvention,
1698116383 callconv_val.toIntern(),
1698216384 // is_generic: bool,
16983 Value.makeBool(func_ty_info.is_generic).toIntern(),
16385 Value.makeBool(func_is_generic).toIntern(),
1698416386 // is_var_args: bool,
1698516387 Value.makeBool(func_ty_info.is_var_args).toIntern(),
1698616388 // return_type: ?type,
......@@ -17015,7 +16417,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1701516417
1701616418 const field_vals = .{
1701716419 // bits: u16,
17018 (try pt.intValue(.u16, ty.bitSize(zcu))).toIntern(),
16420 (try pt.intValue(.u16, ty.floatBits(zcu.getTarget()))).toIntern(),
1701916421 };
1702016422 return Air.internedToRef((try pt.internUnion(.{
1702116423 .ty = type_info_ty.toIntern(),
......@@ -17025,10 +16427,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1702516427 },
1702616428 .pointer => {
1702716429 const info = ty.ptrInfo(zcu);
17028 const alignment = if (info.flags.alignment.toByteUnits()) |alignment|
17029 try pt.intValue(.comptime_int, alignment)
17030 else
17031 try Type.fromInterned(info.child).lazyAbiAlignment(pt);
16430 const alignment_ty = try pt.optionalType(.usize_type);
16431 const alignment_val: Value = val: {
16432 const bytes = info.flags.alignment.toByteUnits() orelse {
16433 break :val try pt.nullValue(alignment_ty);
16434 };
16435 const int_val = try pt.intValue(.usize, bytes);
16436 break :val .fromInterned(try pt.intern(.{ .opt = .{
16437 .ty = alignment_ty.toIntern(),
16438 .val = int_val.toIntern(),
16439 } }));
16440 };
1703216441
1703316442 const addrspace_ty = try sema.getBuiltinType(src, .AddressSpace);
1703416443 const pointer_ty = try sema.getBuiltinType(src, .@"Type.Pointer");
......@@ -17041,8 +16450,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1704116450 Value.makeBool(info.flags.is_const).toIntern(),
1704216451 // is_volatile: bool,
1704316452 Value.makeBool(info.flags.is_volatile).toIntern(),
17044 // alignment: comptime_int,
17045 alignment.toIntern(),
16453 // alignment: ?usize,
16454 alignment_val.toIntern(),
1704616455 // address_space: AddressSpace
1704716456 (try pt.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).toIntern(),
1704816457 // child: type,
......@@ -17159,7 +16568,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1715916568 };
1716016569
1716116570 // Build our ?[]const Error value
17162 const slice_errors_ty = try pt.ptrTypeSema(.{
16571 const slice_errors_ty = try pt.ptrType(.{
1716316572 .child = error_field_ty.toIntern(),
1716416573 .flags = .{
1716516574 .size = .slice,
......@@ -17215,19 +16624,19 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1721516624 })));
1721616625 },
1721716626 .@"enum" => {
17218 const is_exhaustive = Value.makeBool(ip.loadEnumType(ty.toIntern()).tag_mode != .nonexhaustive);
16627 const enum_obj = ip.loadEnumType(ty.toIntern());
16628 const is_exhaustive: Value = .makeBool(!enum_obj.nonexhaustive);
1721916629
1722016630 const enum_field_ty = try sema.getBuiltinType(src, .@"Type.EnumField");
1722116631
17222 const enum_field_vals = try sema.arena.alloc(InternPool.Index, ip.loadEnumType(ty.toIntern()).names.len);
16632 const enum_field_vals = try sema.arena.alloc(InternPool.Index, enum_obj.field_names.len);
1722316633 for (enum_field_vals, 0..) |*field_val, tag_index| {
17224 const enum_type = ip.loadEnumType(ty.toIntern());
17225 const value_val = if (enum_type.values.len > 0)
16634 const value_val = if (enum_obj.field_values.len > 0)
1722616635 try ip.getCoercedInts(
1722716636 gpa,
1722816637 io,
1722916638 pt.tid,
17230 ip.indexToKey(enum_type.values.get(ip)[tag_index]).int,
16639 ip.indexToKey(enum_obj.field_values.get(ip)[tag_index]).int,
1723116640 .comptime_int_type,
1723216641 )
1723316642 else
......@@ -17235,7 +16644,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1723516644
1723616645 // TODO: write something like getCoercedInts to avoid needing to dupe
1723716646 const name_val = v: {
17238 const tag_name = enum_type.names.get(ip)[tag_index];
16647 const tag_name = enum_obj.field_names.get(ip)[tag_index];
1723916648 const tag_name_len = tag_name.length(ip);
1724016649 const new_decl_ty = try pt.arrayType(.{
1724116650 .len = tag_name_len,
......@@ -17275,7 +16684,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1727516684 .child = enum_field_ty.toIntern(),
1727616685 });
1727716686 const new_decl_val = (try pt.aggregateValue(fields_array_ty, enum_field_vals)).toIntern();
17278 const slice_ty = (try pt.ptrTypeSema(.{
16687 const slice_ty = (try pt.ptrType(.{
1727916688 .child = enum_field_ty.toIntern(),
1728016689 .flags = .{
1728116690 .size = .slice,
......@@ -17303,7 +16712,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1730316712
1730416713 const field_values = .{
1730516714 // tag_type: type,
17306 ip.loadEnumType(ty.toIntern()).tag_ty,
16715 ip.loadEnumType(ty.toIntern()).int_tag_type,
1730716716 // fields: []const EnumField,
1730816717 fields_val,
1730916718 // decls: []const Declaration,
......@@ -17321,17 +16730,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1732116730 const type_union_ty = try sema.getBuiltinType(src, .@"Type.Union");
1732216731 const union_field_ty = try sema.getBuiltinType(src, .@"Type.UnionField");
1732316732
17324 try ty.resolveLayout(pt); // Getting alignment requires type layout
17325 const union_obj = zcu.typeToUnion(ty).?;
17326 const tag_type = union_obj.loadTagType(ip);
17327 const layout = union_obj.flagsUnordered(ip).layout;
16733 const union_obj = ip.loadUnionType(ty.toIntern());
16734 const enum_obj = ip.loadEnumType(union_obj.enum_tag_type);
16735 const layout = union_obj.layout;
1732816736
17329 const union_field_vals = try gpa.alloc(InternPool.Index, tag_type.names.len);
16737 const union_field_vals = try gpa.alloc(InternPool.Index, enum_obj.field_names.len);
1733016738 defer gpa.free(union_field_vals);
1733116739
1733216740 for (union_field_vals, 0..) |*field_val, field_index| {
1733316741 const name_val = v: {
17334 const field_name = tag_type.names.get(ip)[field_index];
16742 const field_name = enum_obj.field_names.get(ip)[field_index];
1733516743 const field_name_len = field_name.length(ip);
1733616744 const new_decl_ty = try pt.arrayType(.{
1733716745 .len = field_name_len,
......@@ -17356,19 +16764,31 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1735616764 } });
1735716765 };
1735816766
17359 const alignment = switch (layout) {
17360 .auto, .@"extern" => try ty.fieldAlignmentSema(field_index, pt),
17361 .@"packed" => .none,
16767 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);
16768
16769 const alignment_ty = try pt.optionalType(.usize_type);
16770 const alignment_val: Value = val: {
16771 const a: Alignment = switch (layout) {
16772 .auto, .@"extern" => ty.explicitFieldAlignment(field_index, zcu),
16773 .@"packed" => .none,
16774 };
16775 const bytes = a.toByteUnits() orelse {
16776 break :val try pt.nullValue(alignment_ty);
16777 };
16778 const int_val = try pt.intValue(.usize, bytes);
16779 break :val .fromInterned(try pt.intern(.{ .opt = .{
16780 .ty = alignment_ty.toIntern(),
16781 .val = int_val.toIntern(),
16782 } }));
1736216783 };
1736316784
17364 const field_ty = union_obj.field_types.get(ip)[field_index];
1736516785 const union_field_fields = .{
1736616786 // name: [:0]const u8,
1736716787 name_val,
1736816788 // type: type,
17369 field_ty,
17370 // alignment: comptime_int,
17371 (try pt.intValue(.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(),
16789 field_ty.toIntern(),
16790 // alignment: ?usize,
16791 alignment_val.toIntern(),
1737216792 };
1737316793 field_val.* = (try pt.aggregateValue(union_field_ty, &union_field_fields)).toIntern();
1737416794 }
......@@ -17379,7 +16799,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1737916799 .child = union_field_ty.toIntern(),
1738016800 });
1738116801 const new_decl_val = (try pt.aggregateValue(array_fields_ty, union_field_vals)).toIntern();
17382 const slice_ty = (try pt.ptrTypeSema(.{
16802 const slice_ty = (try pt.ptrType(.{
1738316803 .child = union_field_ty.toIntern(),
1738416804 .flags = .{
1738516805 .size = .slice,
......@@ -17431,8 +16851,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1743116851 const type_struct_ty = try sema.getBuiltinType(src, .@"Type.Struct");
1743216852 const struct_field_ty = try sema.getBuiltinType(src, .@"Type.StructField");
1743316853
17434 try ty.resolveLayout(pt); // Getting alignment requires type layout
17435
1743616854 var struct_field_vals: []InternPool.Index = &.{};
1743716855 defer gpa.free(struct_field_vals);
1743816856 fv: {
......@@ -17468,11 +16886,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1746816886 } });
1746916887 };
1747016888
17471 try Type.fromInterned(field_ty).resolveLayout(pt);
17472
1747316889 const is_comptime = field_val != .none;
1747416890 const opt_default_val = if (is_comptime) Value.fromInterned(field_val) else null;
1747516891 const default_val_ptr = try sema.optRefValue(opt_default_val);
16892
1747616893 const struct_field_fields = .{
1747716894 // name: [:0]const u8,
1747816895 name_val,
......@@ -17482,8 +16899,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1748216899 default_val_ptr.toIntern(),
1748316900 // is_comptime: bool,
1748416901 Value.makeBool(is_comptime).toIntern(),
17485 // alignment: comptime_int,
17486 (try pt.intValue(.comptime_int, Type.fromInterned(field_ty).abiAlignment(zcu).toByteUnits() orelse 0)).toIntern(),
16902 // alignment: ?usize,
16903 (try pt.nullValue(try pt.optionalType(.usize_type))).toIntern(),
1748716904 };
1748816905 struct_field_val.* = (try pt.aggregateValue(struct_field_ty, &struct_field_fields)).toIntern();
1748916906 }
......@@ -17492,16 +16909,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1749216909 .struct_type => ip.loadStructType(ty.toIntern()),
1749316910 else => unreachable,
1749416911 };
16912 try sema.ensureStructDefaultsResolved(ty, src); // can't do this sooner, since it's not allowed on tuples
1749516913 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);
1749616914
17497 try ty.resolveStructFieldInits(pt);
17498
1749916915 for (struct_field_vals, 0..) |*field_val, field_index| {
17500 const field_name = struct_type.fieldName(ip, field_index);
16916 const field_name = struct_type.field_names.get(ip)[field_index];
1750116917 const field_name_len = field_name.length(ip);
1750216918 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
17503 const field_init = struct_type.fieldInit(ip, field_index);
17504 const field_is_comptime = struct_type.fieldIsComptime(ip, field_index);
16919 const field_default: InternPool.Index = if (struct_type.field_defaults.len > 0) d: {
16920 break :d struct_type.field_defaults.get(ip)[field_index];
16921 } else .none;
16922 const field_is_comptime = struct_type.field_is_comptime_bits.get(ip, field_index);
1750516923 const name_val = v: {
1750616924 const new_decl_ty = try pt.arrayType(.{
1750716925 .len = field_name_len,
......@@ -17526,15 +16944,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1752616944 } });
1752716945 };
1752816946
17529 const opt_default_val = if (field_init == .none) null else Value.fromInterned(field_init);
16947 const opt_default_val: ?Value = if (field_default == .none) null else .fromInterned(field_default);
1753016948 const default_val_ptr = try sema.optRefValue(opt_default_val);
17531 const alignment = switch (struct_type.layout) {
17532 .@"packed" => .none,
17533 else => try field_ty.structFieldAlignmentSema(
17534 struct_type.fieldAlign(ip, field_index),
17535 struct_type.layout,
17536 pt,
17537 ),
16949
16950 const alignment_ty = try pt.optionalType(.usize_type);
16951 const alignment_val: Value = val: {
16952 const a: Alignment = switch (struct_type.layout) {
16953 .auto, .@"extern" => ty.explicitFieldAlignment(field_index, zcu),
16954 .@"packed" => .none,
16955 };
16956 const bytes = a.toByteUnits() orelse {
16957 break :val try pt.nullValue(alignment_ty);
16958 };
16959 const int_val = try pt.intValue(.usize, bytes);
16960 break :val .fromInterned(try pt.intern(.{ .opt = .{
16961 .ty = alignment_ty.toIntern(),
16962 .val = int_val.toIntern(),
16963 } }));
1753816964 };
1753916965
1754016966 const struct_field_fields = .{
......@@ -17546,8 +16972,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1754616972 default_val_ptr.toIntern(),
1754716973 // is_comptime: bool,
1754816974 Value.makeBool(field_is_comptime).toIntern(),
17549 // alignment: comptime_int,
17550 (try pt.intValue(.comptime_int, alignment.toByteUnits() orelse 0)).toIntern(),
16975 // alignment: ?usize,
16976 alignment_val.toIntern(),
1755116977 };
1755216978 field_val.* = (try pt.aggregateValue(struct_field_ty, &struct_field_fields)).toIntern();
1755316979 }
......@@ -17559,7 +16985,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1755916985 .child = struct_field_ty.toIntern(),
1756016986 });
1756116987 const new_decl_val = (try pt.aggregateValue(array_fields_ty, struct_field_vals)).toIntern();
17562 const slice_ty = (try pt.ptrTypeSema(.{
16988 const slice_ty = (try pt.ptrType(.{
1756316989 .child = struct_field_ty.toIntern(),
1756416990 .flags = .{
1756516991 .size = .slice,
......@@ -17585,9 +17011,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1758517011
1758617012 const backing_integer_val = try pt.intern(.{ .opt = .{
1758717013 .ty = (try pt.optionalType(.type_type)).toIntern(),
17588 .val = if (zcu.typeToPackedStruct(ty)) |packed_struct| val: {
17589 assert(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)).isInt(zcu));
17590 break :val packed_struct.backingIntTypeUnordered(ip);
17014 .val = if (zcu.typeToPackedStruct(ty)) |struct_obj| val: {
17015 assert(Type.fromInterned(struct_obj.packed_backing_int_type).isInt(zcu));
17016 break :val struct_obj.packed_backing_int_type;
1759117017 } else .none,
1759217018 } });
1759317019
......@@ -17616,7 +17042,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1761617042 .@"opaque" => {
1761717043 const type_opaque_ty = try sema.getBuiltinType(src, .@"Type.Opaque");
1761817044
17619 try ty.resolveFields(pt);
1762017045 const decls_val = try sema.typeInfoDecls(src, ty.getNamespace(zcu));
1762117046
1762217047 const field_values = .{
......@@ -17658,7 +17083,7 @@ fn typeInfoDecls(
1765817083 .child = declaration_ty.toIntern(),
1765917084 });
1766017085 const new_decl_val = (try pt.aggregateValue(array_decl_ty, decl_vals.items)).toIntern();
17661 const slice_ty = (try pt.ptrTypeSema(.{
17086 const slice_ty = (try pt.ptrType(.{
1766217087 .child = declaration_ty.toIntern(),
1766317088 .flags = .{
1766417089 .size = .slice,
......@@ -17740,7 +17165,7 @@ fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1774017165 _ = block;
1774117166 const zir_datas = sema.code.instructions.items(.data);
1774217167 const inst_data = zir_datas[@intFromEnum(inst)].un_node;
17743 const operand = try sema.resolveInst(inst_data.operand);
17168 const operand = sema.resolveInst(inst_data.operand);
1774417169 const operand_ty = sema.typeOf(operand);
1774517170 return Air.internedToRef(operand_ty.toIntern());
1774617171}
......@@ -17754,7 +17179,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
1775417179 .parent = block,
1775517180 .sema = sema,
1775617181 .namespace = block.namespace,
17757 .instructions = .{},
17182 .instructions = .empty,
1775817183 .inlining = block.inlining,
1775917184 .comptime_reason = null,
1776017185 .is_typeof = true,
......@@ -17772,7 +17197,7 @@ fn zirTypeofBuiltin(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
1777217197fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1777317198 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1777417199 const src = block.nodeOffset(inst_data.src_node);
17775 const operand = try sema.resolveInst(inst_data.operand);
17200 const operand = sema.resolveInst(inst_data.operand);
1777617201 const operand_ty = sema.typeOf(operand);
1777717202 const res_ty = try sema.log2IntType(block, operand_ty, src);
1777817203 return Air.internedToRef(res_ty.toIntern());
......@@ -17783,22 +17208,12 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi
1778317208 const zcu = pt.zcu;
1778417209 switch (operand.zigTypeTag(zcu)) {
1778517210 .comptime_int => return .comptime_int,
17786 .int => {
17787 const bits = operand.bitSize(zcu);
17788 const count = if (bits == 0)
17789 0
17790 else blk: {
17791 var count: u16 = 0;
17792 var s = bits - 1;
17793 while (s != 0) : (s >>= 1) {
17794 count += 1;
17795 }
17796 break :blk count;
17797 };
17798 return pt.intType(.unsigned, count);
17799 },
17211 .int => return pt.intType(.unsigned, switch (operand.intInfo(zcu).bits) {
17212 0 => 0,
17213 else => |b| std.math.log2_int_ceil(u16, b),
17214 }),
1780017215 .vector => {
17801 const elem_ty = operand.elemType2(zcu);
17216 const elem_ty = operand.childType(zcu);
1780217217 const log2_elem_ty = try sema.log2IntType(block, elem_ty, src);
1780317218 return pt.vectorType(.{
1780417219 .len = operand.vectorLen(zcu),
......@@ -17832,7 +17247,7 @@ fn zirTypeofPeer(
1783217247 .parent = block,
1783317248 .sema = sema,
1783417249 .namespace = block.namespace,
17835 .instructions = .{},
17250 .instructions = .empty,
1783617251 .inlining = block.inlining,
1783717252 .comptime_reason = null,
1783817253 .is_typeof = true,
......@@ -17852,7 +17267,7 @@ fn zirTypeofPeer(
1785217267 defer sema.gpa.free(inst_list);
1785317268
1785417269 for (args, 0..) |arg_ref, i| {
17855 inst_list[i] = try sema.resolveInst(arg_ref);
17270 inst_list[i] = sema.resolveInst(arg_ref);
1785617271 }
1785717272
1785817273 const result_type = try sema.resolvePeerTypes(block, src, inst_list, .{ .typeof_builtin_call_node_offset = extra.data.src_node });
......@@ -17865,7 +17280,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1786517280 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1786617281 const src = block.nodeOffset(inst_data.src_node);
1786717282 const operand_src = block.src(.{ .node_offset_un_op = inst_data.src_node });
17868 const uncasted_operand = try sema.resolveInst(inst_data.operand);
17283 const uncasted_operand = sema.resolveInst(inst_data.operand);
1786917284 const uncasted_ty = sema.typeOf(uncasted_operand);
1787017285 if (uncasted_ty.isVector(zcu)) {
1787117286 if (uncasted_ty.scalarType(zcu).zigTypeTag(zcu) != .bool) {
......@@ -17876,7 +17291,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1787617291 return analyzeBitNot(sema, block, uncasted_operand, src);
1787717292 }
1787817293 const operand = try sema.coerce(block, .bool, uncasted_operand, operand_src);
17879 if (try sema.resolveValue(operand)) |val| {
17294 if (sema.resolveValue(operand)) |val| {
1788017295 return if (val.isUndef(zcu)) .undef_bool else if (val.toBool()) .bool_false else .bool_true;
1788117296 }
1788217297 try sema.requireRuntimeBlock(block, src, null);
......@@ -17900,7 +17315,7 @@ fn zirBoolBr(
1790017315 const inst_data = datas[@intFromEnum(inst)].pl_node;
1790117316 const extra = sema.code.extraData(Zir.Inst.BoolBr, inst_data.payload_index);
1790217317
17903 const uncoerced_lhs = try sema.resolveInst(extra.data.lhs);
17318 const uncoerced_lhs = sema.resolveInst(extra.data.lhs);
1790417319 const body = sema.code.bodySlice(extra.end, extra.data.body_len);
1790517320 const lhs_src = parent_block.src(.{ .node_offset_bin_lhs = inst_data.src_node });
1790617321 const rhs_src = parent_block.src(.{ .node_offset_bin_rhs = inst_data.src_node });
......@@ -18063,9 +17478,9 @@ fn zirIsNonNull(
1806317478
1806417479 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1806517480 const src = block.nodeOffset(inst_data.src_node);
18066 const operand = try sema.resolveInst(inst_data.operand);
17481 const operand = sema.resolveInst(inst_data.operand);
1806717482 try sema.checkNullableType(block, src, sema.typeOf(operand));
18068 return sema.analyzeIsNull(block, operand, true);
17483 return sema.analyzeIsNull(block, src, operand, true);
1806917484}
1807017485
1807117486fn zirIsNonNullPtr(
......@@ -18080,17 +17495,23 @@ fn zirIsNonNullPtr(
1808017495 const zcu = pt.zcu;
1808117496 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1808217497 const src = block.nodeOffset(inst_data.src_node);
18083 const ptr = try sema.resolveInst(inst_data.operand);
17498 const ptr = sema.resolveInst(inst_data.operand);
1808417499 const ptr_ty = sema.typeOf(ptr);
18085 try sema.checkNullableType(block, src, sema.typeOf(ptr).elemType2(zcu));
18086 if (try sema.resolveValue(ptr)) |ptr_val| {
18087 if (try sema.pointerDeref(block, src, ptr_val, ptr_ty)) |loaded_val| {
18088 return sema.analyzeIsNull(block, Air.internedToRef(loaded_val.toIntern()), true);
18089 }
17500 assert(ptr_ty.zigTypeTag(zcu) == .pointer);
17501 const nullable_ty = ptr_ty.childType(zcu);
17502
17503 try sema.checkNullableType(block, src, nullable_ty);
17504
17505 if (try sema.resolveIsNullFromType(block, src, nullable_ty)) |is_null| {
17506 return .fromValue(.makeBool(!is_null));
1809017507 }
18091 if (ptr_ty.childType(zcu).isNullFromType(zcu)) |is_null| {
18092 return if (is_null) .bool_false else .bool_true;
17508
17509 if (sema.resolveValue(ptr)) |ptr_val| {
17510 if (try sema.pointerDeref(block, src, ptr_val, ptr_ty)) |nullable_val| {
17511 return sema.analyzeIsNull(block, src, .fromValue(nullable_val), true);
17512 }
1809317513 }
17514
1809417515 return block.addUnOp(.is_non_null_ptr, ptr);
1809517516}
1809617517
......@@ -18111,7 +17532,7 @@ fn zirIsNonErr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1811117532
1811217533 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1811317534 const src = block.nodeOffset(inst_data.src_node);
18114 const operand = try sema.resolveInst(inst_data.operand);
17535 const operand = sema.resolveInst(inst_data.operand);
1811517536 try sema.checkErrorType(block, src, sema.typeOf(operand));
1811617537 return sema.analyzeIsNonErr(block, src, operand);
1811717538}
......@@ -18124,8 +17545,11 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1812417545 const zcu = pt.zcu;
1812517546 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1812617547 const src = block.nodeOffset(inst_data.src_node);
18127 const ptr = try sema.resolveInst(inst_data.operand);
18128 try sema.checkErrorType(block, src, sema.typeOf(ptr).elemType2(zcu));
17548 const ptr = sema.resolveInst(inst_data.operand);
17549 const ptr_ty = sema.typeOf(ptr);
17550 assert(ptr_ty.zigTypeTag(zcu) == .pointer);
17551 const error_ty = ptr_ty.childType(zcu);
17552 try sema.checkErrorType(block, src, error_ty);
1812917553 const loaded = try sema.analyzeLoad(block, src, ptr, src);
1813017554 return sema.analyzeIsNonErr(block, src, loaded);
1813117555}
......@@ -18136,7 +17560,7 @@ fn zirRetIsNonErr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1813617560
1813717561 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1813817562 const src = block.nodeOffset(inst_data.src_node);
18139 const operand = try sema.resolveInst(inst_data.operand);
17563 const operand = sema.resolveInst(inst_data.operand);
1814017564 return sema.analyzeIsNonErr(block, src, operand);
1814117565}
1814217566
......@@ -18157,7 +17581,7 @@ fn zirCondbr(
1815717581 const then_body = sema.code.bodySlice(extra.end, extra.data.then_body_len);
1815817582 const else_body = sema.code.bodySlice(extra.end + then_body.len, extra.data.else_body_len);
1815917583
18160 const uncasted_cond = try sema.resolveInst(extra.data.condition);
17584 const uncasted_cond = sema.resolveInst(extra.data.condition);
1816117585 const cond = try sema.coerce(parent_block, .bool, uncasted_cond, cond_src);
1816217586
1816317587 if (try sema.resolveDefinedValue(parent_block, cond_src, cond)) |cond_val| {
......@@ -18193,7 +17617,7 @@ fn zirCondbr(
1819317617 if (sema.code.instructions.items(.tag)[@intFromEnum(index)] != .is_non_err) break :blk null;
1819417618
1819517619 const err_inst_data = sema.code.instructions.items(.data)[@intFromEnum(index)].un_node;
18196 const err_operand = try sema.resolveInst(err_inst_data.operand);
17620 const err_operand = sema.resolveInst(err_inst_data.operand);
1819717621 const operand_ty = sema.typeOf(err_operand);
1819817622 assert(operand_ty.zigTypeTag(zcu) == .error_union);
1819917623 const result_ty = operand_ty.errorUnionSet(zcu);
......@@ -18241,7 +17665,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!
1824117665 const operand_src = parent_block.src(.{ .node_offset_try_operand = inst_data.src_node });
1824217666 const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);
1824317667 const body = sema.code.bodySlice(extra.end, extra.data.body_len);
18244 const err_union = try sema.resolveInst(extra.data.operand);
17668 const err_union = sema.resolveInst(extra.data.operand);
1824517669 const err_union_ty = sema.typeOf(err_union);
1824617670 const pt = sema.pt;
1824717671 const zcu = pt.zcu;
......@@ -18294,6 +17718,11 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!
1829417718 } },
1829517719 });
1829617720 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(sub_block.instructions.items));
17721
17722 // The payload type might still be OPV, in which case `try_inst` is just there for the runtime
17723 // control flow and we should return a comptime-known result.
17724 if (try err_union_ty.errorUnionPayload(zcu).onePossibleValue(pt)) |opv| return .fromValue(opv);
17725
1829717726 return try_inst;
1829817727}
1829917728
......@@ -18303,7 +17732,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
1830317732 const operand_src = parent_block.src(.{ .node_offset_try_operand = inst_data.src_node });
1830417733 const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index);
1830517734 const body = sema.code.bodySlice(extra.end, extra.data.body_len);
18306 const operand = try sema.resolveInst(extra.data.operand);
17735 const operand = sema.resolveInst(extra.data.operand);
1830717736 const err_union = try sema.analyzeLoad(parent_block, src, operand, operand_src);
1830817737 const err_union_ty = sema.typeOf(err_union);
1830917738 const pt = sema.pt;
......@@ -18347,7 +17776,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
1834717776
1834817777 const operand_ty = sema.typeOf(operand);
1834917778 const ptr_info = operand_ty.ptrInfo(zcu);
18350 const res_ty = try pt.ptrTypeSema(.{
17779 const res_ty = try pt.ptrType(.{
1835117780 .child = err_union_ty.errorUnionPayload(zcu).toIntern(),
1835217781 .flags = .{
1835317782 .is_const = ptr_info.flags.is_const,
......@@ -18396,9 +17825,9 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label
1839617825 .label = .{
1839717826 .zir_block = dest_block,
1839817827 .merges = .{
18399 .src_locs = .{},
18400 .results = .{},
18401 .br_list = .{},
17828 .src_locs = .empty,
17829 .results = .empty,
17830 .br_list = .empty,
1840217831 .block_inst = new_block_inst,
1840317832 },
1840417833 },
......@@ -18406,7 +17835,7 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label
1840617835 .parent = block,
1840717836 .sema = sema,
1840817837 .namespace = block.namespace,
18409 .instructions = .{},
17838 .instructions = .empty,
1841017839 .label = &labeled_block.label,
1841117840 .inlining = block.inlining,
1841217841 .comptime_reason = block.comptime_reason,
......@@ -18424,7 +17853,7 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label
1842417853fn addRuntimeBreak(sema: *Sema, child_block: *Block, block_inst: Zir.Inst.Index, break_operand: Zir.Inst.Ref) !void {
1842517854 const labeled_block = try sema.ensurePostHoc(child_block, block_inst);
1842617855
18427 const operand = try sema.resolveInst(break_operand);
17856 const operand = sema.resolveInst(break_operand);
1842817857 const br_ref = try child_block.addBr(labeled_block.label.merges.block_inst, operand);
1842917858
1843017859 try labeled_block.label.merges.results.append(sema.gpa, operand);
......@@ -18510,9 +17939,9 @@ fn zirRetImplicit(
1851017939 return;
1851117940 }
1851217941
18513 const operand = try sema.resolveInst(inst_data.operand);
17942 const operand = sema.resolveInst(inst_data.operand);
1851417943 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = .zero });
18515 const base_tag = sema.fn_ret_ty.baseZigTypeTag(zcu);
17944 const base_tag = sema.fn_ret_ty.optEuBaseType(zcu).zigTypeTag(zcu);
1851617945 if (base_tag == .noreturn) {
1851717946 const msg = msg: {
1851817947 const msg = try sema.errMsg(ret_ty_src, "function declared '{f}' implicitly returns", .{
......@@ -18543,7 +17972,7 @@ fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
1854317972 defer tracy.end();
1854417973
1854517974 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
18546 const operand = try sema.resolveInst(inst_data.operand);
17975 const operand = sema.resolveInst(inst_data.operand);
1854717976 const src = block.nodeOffset(inst_data.src_node);
1854817977
1854917978 return sema.analyzeRet(block, operand, src, block.src(.{ .node_offset_return_operand = inst_data.src_node }));
......@@ -18555,7 +17984,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
1855517984
1855617985 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1855717986 const src = block.nodeOffset(inst_data.src_node);
18558 const ret_ptr = try sema.resolveInst(inst_data.operand);
17987 const ret_ptr = sema.resolveInst(inst_data.operand);
1855917988
1856017989 if (block.isComptime() or block.inlining != null or sema.func_is_naked) {
1856117990 const operand = try sema.analyzeLoad(block, src, ret_ptr, src);
......@@ -18652,7 +18081,7 @@ fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
1865218081 if (block.isComptime() or block.is_typeof) return;
1865318082
1865418083 const save_index = inst_data.operand == .none or b: {
18655 const operand = try sema.resolveInst(inst_data.operand);
18084 const operand = sema.resolveInst(inst_data.operand);
1865618085 const operand_ty = sema.typeOf(operand);
1865718086 break :b operand_ty.isError(zcu);
1865818087 };
......@@ -18701,7 +18130,7 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_
1870118130 return; // No need to restore
1870218131 };
1870318132
18704 const operand = try sema.resolveInstAllowNone(operand_zir);
18133 const operand = sema.resolveInstAllowNone(operand_zir);
1870518134
1870618135 if (start_block.isComptime() or start_block.is_typeof) {
1870718136 const is_non_error = if (operand != .none) blk: {
......@@ -18809,8 +18238,6 @@ fn analyzeRet(
1880918238 return sema.failWithOwnedErrorMsg(block, msg);
1881018239 }
1881118240
18812 try sema.fn_ret_ty.resolveLayout(pt);
18813
1881418241 try sema.validateRuntimeValue(block, operand_src, operand);
1881518242
1881618243 const air_tag: Air.Inst.Tag = if (block.wantSafety()) .ret_safe else .ret;
......@@ -18853,8 +18280,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1885318280 const hostsize_src = block.src(.{ .node_offset_ptr_hostsize = extra.data.src_node });
1885418281
1885518282 const elem_ty = blk: {
18856 const air_inst = try sema.resolveInst(extra.data.elem_type);
18857 const ty = sema.analyzeAsType(block, elem_ty_src, air_inst) catch |err| {
18283 const air_inst = sema.resolveInst(extra.data.elem_type);
18284 const ty = sema.analyzeAsType(block, elem_ty_src, .type, air_inst) catch |err| {
1885818285 if (err == error.AnalysisFail and sema.err != null and sema.typeOf(air_inst).isSinglePointer(zcu)) {
1885918286 try sema.errNote(elem_ty_src, sema.err.?, "use '.*' to dereference pointer", .{});
1886018287 }
......@@ -18874,7 +18301,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1887418301 const sentinel = if (inst_data.flags.has_sentinel) blk: {
1887518302 const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]);
1887618303 extra_i += 1;
18877 const coerced = try sema.coerce(block, elem_ty, try sema.resolveInst(ref), sentinel_src);
18304 const coerced = try sema.coerce(block, elem_ty, sema.resolveInst(ref), sentinel_src);
1887818305 const val = try sema.resolveConstDefinedValue(block, sentinel_src, coerced, .{ .simple = .pointer_sentinel });
1887918306 try checkSentinelType(sema, block, sentinel_src, elem_ty);
1888018307 if (val.canMutateComptimeVarState(zcu)) {
......@@ -18887,18 +18314,9 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1888718314 const abi_align: Alignment = if (inst_data.flags.has_align) blk: {
1888818315 const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]);
1888918316 extra_i += 1;
18890 const coerced = try sema.coerce(block, align_ty, try sema.resolveInst(ref), align_src);
18317 const coerced = try sema.coerce(block, align_ty, sema.resolveInst(ref), align_src);
1889118318 const val = try sema.resolveConstDefinedValue(block, align_src, coerced, .{ .simple = .@"align" });
18892 // Check if this happens to be the lazy alignment of our element type, in
18893 // which case we can make this 0 without resolving it.
18894 switch (zcu.intern_pool.indexToKey(val.toIntern())) {
18895 .int => |int| switch (int.storage) {
18896 .lazy_align => |lazy_ty| if (lazy_ty == elem_ty.toIntern()) break :blk .none,
18897 else => {},
18898 },
18899 else => {},
18900 }
18901 const align_bytes = (try val.getUnsignedIntSema(pt)).?;
18319 const align_bytes = val.toUnsignedInt(zcu);
1890218320 break :blk try sema.validateAlign(block, align_src, align_bytes);
1890318321 } else .none;
1890418322
......@@ -18928,7 +18346,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1892818346 elem_ty.fmt(pt), bit_offset, bit_offset - host_size * 8, host_size,
1892918347 });
1893018348 }
18931 const elem_bit_size = try elem_ty.bitSizeSema(pt);
18349 try sema.ensureLayoutResolved(elem_ty, elem_ty_src, .bit_ptr_child);
18350 const elem_bit_size = elem_ty.bitSize(zcu);
1893218351 if (elem_bit_size > host_size * 8 - bit_offset) {
1893318352 return sema.fail(block, bitoffset_src, "packed type '{f}' at bit offset {d} ends {d} bits after the end of a {d} byte host integer", .{
1893418353 elem_ty.fmt(pt), bit_offset, elem_bit_size - (host_size * 8 - bit_offset), host_size,
......@@ -18942,31 +18361,18 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1894218361 }
1894318362 } else if (inst_data.size != .one and elem_ty.zigTypeTag(zcu) == .@"opaque") {
1894418363 return sema.fail(block, elem_ty_src, "indexable pointer to opaque type '{f}' not allowed", .{elem_ty.fmt(pt)});
18945 } else if (inst_data.size == .c) {
18946 if (!try sema.validateExternType(elem_ty, .other)) {
18947 const msg = msg: {
18948 const msg = try sema.errMsg(elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{f}'", .{elem_ty.fmt(pt)});
18949 errdefer msg.destroy(sema.gpa);
18950
18951 try sema.explainWhyTypeIsNotExtern(msg, elem_ty_src, elem_ty, .other);
18952
18953 try sema.addDeclaredHereNote(msg, elem_ty);
18954 break :msg msg;
18955 };
18956 return sema.failWithOwnedErrorMsg(block, msg);
18957 }
1895818364 }
1895918365
18960 if (host_size != 0 and !try sema.validatePackedType(elem_ty)) {
18961 return sema.failWithOwnedErrorMsg(block, msg: {
18366 if (host_size != 0) {
18367 if (elem_ty.unpackable(zcu)) |reason| return sema.failWithOwnedErrorMsg(block, msg: {
1896218368 const msg = try sema.errMsg(elem_ty_src, "bit-pointer cannot refer to value of type '{f}'", .{elem_ty.fmt(pt)});
1896318369 errdefer msg.destroy(sema.gpa);
18964 try sema.explainWhyTypeIsNotPacked(msg, elem_ty_src, elem_ty);
18370 try sema.explainWhyTypeIsUnpackable(msg, elem_ty_src, reason);
1896518371 break :msg msg;
1896618372 });
1896718373 }
1896818374
18969 const ty = try pt.ptrTypeSema(.{
18375 const ty = try pt.ptrType(.{
1897018376 .child = elem_ty.toIntern(),
1897118377 .sentinel = sentinel,
1897218378 .flags = .{
......@@ -18996,6 +18402,8 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
1899618402 const pt = sema.pt;
1899718403 const zcu = pt.zcu;
1899818404
18405 try sema.ensureLayoutResolved(obj_ty, ty_src, .init);
18406
1899918407 switch (obj_ty.zigTypeTag(zcu)) {
1900018408 .@"struct" => return sema.structInitEmpty(block, obj_ty, src, src),
1900118409 .array, .vector => return sema.arrayInitEmpty(block, src, obj_ty),
......@@ -19058,6 +18466,9 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
1905818466 .child = ptr_ty.childType(zcu).toIntern(),
1905918467 });
1906018468 } else ty_operand;
18469
18470 try sema.ensureLayoutResolved(init_ty, src, .init);
18471
1906118472 const obj_ty = init_ty.optEuBaseType(zcu);
1906218473
1906318474 const empty_ref = switch (obj_ty.zigTypeTag(zcu)) {
......@@ -19069,13 +18480,13 @@ fn zirStructInitEmptyResult(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is
1906918480 const init_ref = try sema.coerce(block, init_ty, empty_ref, src);
1907018481
1907118482 if (is_byref) {
19072 const init_val = (try sema.resolveValue(init_ref)).?;
19073 return sema.uavRef(init_val.toIntern());
18483 return sema.uavRef(sema.resolveValue(init_ref).?);
1907418484 } else {
1907518485 return init_ref;
1907618486 }
1907718487}
1907818488
18489/// Asserts that the layout of `struct_ty` is already resolved.
1907918490fn structInitEmpty(
1908018491 sema: *Sema,
1908118492 block: *Block,
......@@ -19087,7 +18498,7 @@ fn structInitEmpty(
1908718498 const zcu = pt.zcu;
1908818499 const gpa = sema.gpa;
1908918500 // This logic must be synchronized with that in `zirStructInit`.
19090 try struct_ty.resolveFields(pt);
18501 struct_ty.assertHasLayout(zcu);
1909118502
1909218503 // The init values to use for the struct instance.
1909318504 const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount(zcu));
......@@ -19118,63 +18529,36 @@ fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) Com
1911818529
1911918530fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1912018531 const pt = sema.pt;
18532 const zcu = pt.zcu;
18533 const ip = &zcu.intern_pool;
1912118534 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
1912218535 const ty_src = block.builtinCallArgSrc(inst_data.src_node, 0);
1912318536 const field_src = block.builtinCallArgSrc(inst_data.src_node, 1);
19124 const init_src = block.builtinCallArgSrc(inst_data.src_node, 2);
18537 const payload_src = block.builtinCallArgSrc(inst_data.src_node, 2);
1912518538 const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;
1912618539 const union_ty = try sema.resolveType(block, ty_src, extra.union_type);
1912718540 if (union_ty.zigTypeTag(pt.zcu) != .@"union") {
1912818541 return sema.fail(block, ty_src, "expected union type, found '{f}'", .{union_ty.fmt(pt)});
1912918542 }
18543 union_ty.assertHasLayout(zcu); // from a previous `field_type_ref` instruction
1913018544 const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{ .simple = .union_field_names });
19131 const init = try sema.resolveInst(extra.init);
19132 return sema.unionInit(block, init, init_src, union_ty, ty_src, field_name, field_src);
19133}
19134
19135fn unionInit(
19136 sema: *Sema,
19137 block: *Block,
19138 uncasted_init: Air.Inst.Ref,
19139 init_src: LazySrcLoc,
19140 union_ty: Type,
19141 union_ty_src: LazySrcLoc,
19142 field_name: InternPool.NullTerminatedString,
19143 field_src: LazySrcLoc,
19144) CompileError!Air.Inst.Ref {
19145 const pt = sema.pt;
19146 const zcu = pt.zcu;
19147 const ip = &zcu.intern_pool;
1914818545 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_src);
1914918546 const field_ty: Type = .fromInterned(zcu.typeToUnion(union_ty).?.field_types.get(ip)[field_index]);
19150 const init = try sema.coerce(block, field_ty, uncasted_init, init_src);
19151 _ = union_ty_src;
19152 return unionInitFromEnumTag(sema, block, init_src, union_ty, field_index, init);
19153}
1915418547
19155fn unionInitFromEnumTag(
19156 sema: *Sema,
19157 block: *Block,
19158 init_src: LazySrcLoc,
19159 union_ty: Type,
19160 field_index: u32,
19161 init: Air.Inst.Ref,
19162) !Air.Inst.Ref {
19163 const pt = sema.pt;
19164 const zcu = pt.zcu;
18548 const payload = try sema.coerce(block, field_ty, sema.resolveInst(extra.init), payload_src);
18549
18550 if (union_ty.containerLayout(zcu) == .@"packed") {
18551 return sema.bitCast(block, union_ty, payload, block.nodeOffset(inst_data.src_node), payload_src);
18552 }
1916518553
19166 if (try sema.resolveValue(init)) |init_val| {
18554 if (sema.resolveValue(payload)) |payload_val| {
1916718555 const tag_ty = union_ty.unionTagTypeHypothetical(zcu);
1916818556 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);
19169 return Air.internedToRef((try pt.internUnion(.{
19170 .ty = union_ty.toIntern(),
19171 .tag = tag_val.toIntern(),
19172 .val = init_val.toIntern(),
19173 })));
18557 return .fromValue(try pt.unionValue(union_ty, tag_val, payload_val));
1917418558 }
1917518559
19176 try sema.requireRuntimeBlock(block, init_src, null);
19177 return block.addUnionInit(union_ty, field_index, init);
18560 try sema.requireRuntimeBlock(block, payload_src, null);
18561 return block.addUnionInit(union_ty, field_index, payload);
1917818562}
1917918563
1918018564fn zirStructInit(
......@@ -19202,8 +18586,8 @@ fn zirStructInit(
1920218586 // The type wasn't actually known, so treat this as an anon struct init.
1920318587 return sema.structInitAnon(block, src, inst, .typed_init, extra.data, extra.end, is_ref);
1920418588 };
18589 try sema.ensureLayoutResolved(result_ty, src, .init);
1920518590 const resolved_ty = result_ty.optEuBaseType(zcu);
19206 try resolved_ty.resolveLayout(pt);
1920718591
1920818592 if (resolved_ty.zigTypeTag(zcu) == .@"struct") {
1920918593 // This logic must be synchronized with that in `zirStructInitEmpty`.
......@@ -19226,7 +18610,6 @@ fn zirStructInit(
1922618610 var field_i: u32 = 0;
1922718611 var extra_index = extra.end;
1922818612
19229 const is_packed = resolved_ty.containerLayout(zcu) == .@"packed";
1923018613 while (field_i < extra.data.fields_len) : (field_i += 1) {
1923118614 const item = sema.code.extraData(Zir.Inst.StructInit.Item, extra_index);
1923218615 extra_index = item.end;
......@@ -19248,19 +18631,16 @@ fn zirStructInit(
1924818631 assert(field_inits[field_index] == .none);
1924918632 field_assign_idxs[field_index] = field_i;
1925018633 found_fields[field_index] = item.data.field_type;
19251 const uncoerced_init = try sema.resolveInst(item.data.init);
18634 const uncoerced_init = sema.resolveInst(item.data.init);
1925218635 const field_ty = resolved_ty.fieldType(field_index, zcu);
1925318636 field_inits[field_index] = try sema.coerce(block, field_ty, uncoerced_init, field_src);
19254 if (!is_packed) {
19255 try resolved_ty.resolveStructFieldInits(pt);
19256 if (try resolved_ty.structFieldValueComptime(pt, field_index)) |default_value| {
19257 const init_val = (try sema.resolveValue(field_inits[field_index])) orelse {
19258 return sema.failWithNeededComptime(block, field_src, .{ .simple = .stored_to_comptime_field });
19259 };
19260
19261 if (!init_val.eql(default_value, resolved_ty.fieldType(field_index, zcu), zcu)) {
19262 return sema.failWithInvalidComptimeFieldStore(block, field_src, resolved_ty, field_index);
19263 }
18637 if (resolved_ty.structFieldIsComptime(field_index, zcu)) {
18638 const default_value = (try resolved_ty.structFieldValueComptime(pt, field_index)).?;
18639 const init_val = sema.resolveValue(field_inits[field_index]) orelse {
18640 return sema.failWithNeededComptime(block, field_src, .{ .simple = .stored_to_comptime_field });
18641 };
18642 if (!init_val.eql(default_value, resolved_ty.fieldType(field_index, zcu), zcu)) {
18643 return sema.failWithInvalidComptimeFieldStore(block, field_src, resolved_ty, field_index);
1926418644 }
1926518645 }
1926618646 }
......@@ -19288,9 +18668,9 @@ fn zirStructInit(
1928818668 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);
1928918669 const field_ty: Type = .fromInterned(zcu.typeToUnion(resolved_ty).?.field_types.get(ip)[field_index]);
1929018670
19291 if (field_ty.zigTypeTag(zcu) == .noreturn) {
18671 if (field_ty.classify(zcu) == .no_possible_value) {
1929218672 return sema.failWithOwnedErrorMsg(block, msg: {
19293 const msg = try sema.errMsg(src, "cannot initialize 'noreturn' field of union", .{});
18673 const msg = try sema.errMsg(src, "cannot initialize union field with uninstantiable type '{f}'", .{field_ty.fmt(pt)});
1929418674 errdefer msg.destroy(sema.gpa);
1929518675
1929618676 try sema.addFieldErrNote(resolved_ty, field_index, msg, "field '{f}' declared here", .{
......@@ -19301,21 +18681,31 @@ fn zirStructInit(
1930118681 });
1930218682 }
1930318683
19304 const uncoerced_init_inst = try sema.resolveInst(item.data.init);
18684 const uncoerced_init_inst = sema.resolveInst(item.data.init);
1930518685 const init_inst = try sema.coerce(block, field_ty, uncoerced_init_inst, field_src);
1930618686
19307 if (try sema.resolveValue(init_inst)) |val| {
18687 if (resolved_ty.containerLayout(zcu) == .@"packed") {
18688 const union_val = try sema.bitCast(block, resolved_ty, init_inst, src, field_src);
18689 const result_val = try sema.coerce(block, result_ty, union_val, src);
18690 if (is_ref) {
18691 return sema.analyzeRef(block, src, result_val, .none);
18692 } else {
18693 return result_val;
18694 }
18695 }
18696
18697 if (sema.resolveValue(init_inst)) |val| {
1930818698 const struct_val = Value.fromInterned(try pt.internUnion(.{
1930918699 .ty = resolved_ty.toIntern(),
1931018700 .tag = tag_val.toIntern(),
1931118701 .val = val.toIntern(),
1931218702 }));
1931318703 const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src);
19314 const final_val = (try sema.resolveValue(final_val_inst)).?;
19315 return sema.addConstantMaybeRef(final_val.toIntern(), is_ref);
18704 const final_val = sema.resolveValue(final_val_inst).?;
18705 return sema.addConstantMaybeRef(final_val, is_ref);
1931618706 }
1931718707
19318 if (try resolved_ty.comptimeOnlySema(pt)) {
18708 if (resolved_ty.comptimeOnly(zcu)) {
1931918709 return sema.failWithNeededComptime(block, field_src, .{ .comptime_only = .{
1932018710 .ty = resolved_ty,
1932118711 .msg = .union_init,
......@@ -19326,7 +18716,7 @@ fn zirStructInit(
1932618716
1932718717 if (is_ref) {
1932818718 const target = zcu.getTarget();
19329 const alloc_ty = try pt.ptrTypeSema(.{
18719 const alloc_ty = try pt.ptrType(.{
1933018720 .child = result_ty.toIntern(),
1933118721 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1933218722 });
......@@ -19334,10 +18724,6 @@ fn zirStructInit(
1933418724 const base_ptr = try sema.optEuBasePtrInit(block, alloc, src);
1933518725 const field_ptr = try sema.unionFieldPtr(block, field_src, base_ptr, field_name, field_src, resolved_ty, true);
1933618726 try sema.storePtr(block, src, field_ptr, init_inst);
19337 if ((try sema.typeHasOnePossibleValue(tag_ty)) == null) {
19338 const new_tag = Air.internedToRef(tag_val.toIntern());
19339 _ = try block.addBinOp(.set_union_tag, base_ptr, new_tag);
19340 }
1934118727 return sema.makePtrConst(block, alloc);
1934218728 }
1934318729
......@@ -19409,20 +18795,29 @@ fn finishStructInit(
1940918795 continue;
1941018796 }
1941118797
19412 try struct_ty.resolveStructFieldInits(pt);
18798 if (struct_type.field_is_comptime_bits.get(ip, i)) {
18799 field_inits[i] = .fromIntern(struct_type.field_defaults.get(ip)[i]);
18800 continue;
18801 }
18802
18803 try sema.ensureStructDefaultsResolved(struct_ty, init_src);
1941318804
19414 const field_init = struct_type.fieldInit(ip, i);
19415 if (field_init == .none) {
19416 const field_name = struct_type.field_names.get(ip)[i];
19417 const template = "missing struct field: {f}";
19418 const args = .{field_name.fmt(ip)};
19419 if (root_msg) |msg| {
19420 try sema.errNote(init_src, msg, template, args);
19421 } else {
19422 root_msg = try sema.errMsg(init_src, template, args);
19423 }
18805 const field_default: InternPool.Index = d: {
18806 if (struct_type.field_defaults.len == 0) break :d .none;
18807 break :d struct_type.field_defaults.get(ip)[i];
18808 };
18809 if (field_default != .none) {
18810 field_inits[i] = .fromIntern(field_default);
18811 continue;
18812 }
18813
18814 const field_name = struct_type.field_names.get(ip)[i];
18815 const template = "missing struct field: {f}";
18816 const args = .{field_name.fmt(ip)};
18817 if (root_msg) |msg| {
18818 try sema.errNote(init_src, msg, template, args);
1942418819 } else {
19425 field_inits[i] = Air.internedToRef(field_init);
18820 root_msg = try sema.errMsg(init_src, template, args);
1942618821 }
1942718822 }
1942818823 },
......@@ -19442,18 +18837,38 @@ fn finishStructInit(
1944218837 }
1944318838 } else null;
1944418839
19445 const runtime_index = opt_runtime_index orelse {
19446 const elems = try sema.arena.alloc(InternPool.Index, field_inits.len);
19447 for (elems, field_inits) |*elem, field_init| {
19448 elem.* = (sema.resolveValue(field_init) catch unreachable).?.toIntern();
19449 }
19450 const struct_val = try pt.aggregateValue(struct_ty, elems);
19451 const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), init_src);
19452 const final_val = (try sema.resolveValue(final_val_inst)).?;
19453 return sema.addConstantMaybeRef(final_val.toIntern(), is_ref);
18840 const runtime_index = opt_runtime_index orelse switch (struct_ty.containerLayout(zcu)) {
18841 .auto, .@"extern" => {
18842 const elems = try sema.arena.alloc(InternPool.Index, field_inits.len);
18843 for (elems, field_inits) |*elem, field_init| {
18844 elem.* = sema.resolveValue(field_init).?.toIntern();
18845 }
18846 const struct_val = try pt.aggregateValue(struct_ty, elems);
18847 const final_val_ref = try sema.coerce(block, result_ty, .fromValue(struct_val), init_src);
18848 return sema.addConstantMaybeRef(sema.resolveValue(final_val_ref).?, is_ref);
18849 },
18850 .@"packed" => {
18851 const buf = try sema.arena.alloc(u8, @intCast((struct_ty.bitSize(zcu) + 7) / 8));
18852 var bit_offset: u16 = 0;
18853 for (field_inits) |field_init| {
18854 const field_val = sema.resolveValue(field_init).?;
18855 field_val.writeToPackedMemory(pt, buf, bit_offset) catch |err| switch (err) {
18856 error.ReinterpretDeclRef => unreachable, // bitpack fields cannot be pointers
18857 error.OutOfMemory => |e| return e,
18858 };
18859 bit_offset += @intCast(field_val.typeOf(zcu).bitSize(zcu));
18860 }
18861 assert(bit_offset == struct_ty.bitSize(zcu));
18862 const struct_val = Value.readFromPackedMemory(struct_ty, pt, buf, 0, sema.arena) catch |err| switch (err) {
18863 error.IllDefinedMemoryLayout => unreachable, // bitpacks have well-defined layout
18864 error.OutOfMemory => |e| return e,
18865 };
18866 const final_val_ref = try sema.coerce(block, result_ty, .fromValue(struct_val), init_src);
18867 return sema.addConstantMaybeRef(sema.resolveValue(final_val_ref).?, is_ref);
18868 },
1945418869 };
1945518870
19456 if (try struct_ty.comptimeOnlySema(pt)) {
18871 if (struct_ty.comptimeOnly(zcu)) {
1945718872 return sema.failWithNeededComptime(block, block.src(.{ .init_elem = .{
1945818873 .init_node_offset = init_src.offset.node_offset.x,
1945918874 .elem_index = @intCast(runtime_index),
......@@ -19468,9 +18883,8 @@ fn finishStructInit(
1946818883 }
1946918884
1947018885 if (is_ref) {
19471 try struct_ty.resolveLayout(pt);
1947218886 const target = zcu.getTarget();
19473 const alloc_ty = try pt.ptrTypeSema(.{
18887 const alloc_ty = try pt.ptrType(.{
1947418888 .child = result_ty.toIntern(),
1947518889 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1947618890 });
......@@ -19489,7 +18903,6 @@ fn finishStructInit(
1948918903 .init_node_offset = init_src.offset.node_offset.x,
1949018904 .elem_index = @intCast(runtime_index),
1949118905 } }));
19492 try struct_ty.resolveStructFieldInits(pt);
1949318906 const struct_val = try block.addAggregateInit(struct_ty, field_inits);
1949418907 return sema.coerce(block, result_ty, struct_val, init_src);
1949518908}
......@@ -19558,7 +18971,7 @@ fn structInitAnon(
1955818971
1955918972 field_name.* = try zcu.intern_pool.getOrPutString(gpa, io, pt.tid, name, .no_embedded_nulls);
1956018973
19561 const init = try sema.resolveInst(item.data.init);
18974 const init = sema.resolveInst(item.data.init);
1956218975 field_ty.* = sema.typeOf(init).toIntern();
1956318976 if (Type.fromInterned(field_ty.*).zigTypeTag(zcu) == .@"opaque") {
1956418977 const msg = msg: {
......@@ -19574,7 +18987,7 @@ fn structInitAnon(
1957418987 };
1957518988 return sema.failWithOwnedErrorMsg(block, msg);
1957618989 }
19577 if (try sema.resolveValue(init)) |init_val| {
18990 if (sema.resolveValue(init)) |init_val| {
1957818991 field_val.* = init_val.toIntern();
1957918992 any_values = true;
1958018993 } else {
......@@ -19585,12 +18998,11 @@ fn structInitAnon(
1958518998 break :rs runtime_index;
1958618999 };
1958719000
19588 // We treat anonymous struct types as reified types, because there are similarities:
19589 // * They use a form of structural equivalence, which we can easily model using a custom hash
19590 // * They do not have captures
19591 // * They immediately have their fields resolved
19592 // In general, other code should treat anon struct types and reified struct types identically,
19593 // so there's no point having a separate `InternPool.NamespaceType` field for them.
19001 // We treat anonymous struct types as reified types, because there are similarities: they have
19002 // no captures, and instead use a form of structural equivalence which we can easy represent by
19003 // hashing the field names/types/values. They also perform layout resolution immediately. These
19004 // similarities mean that other code should actually treat anon struct types and reified struct
19005 // types identically anyway, so sharing the representation makes everything simpler.
1959419006 const type_hash: u64 = hash: {
1959519007 var hasher = std.hash.Wyhash.init(0);
1959619008 hasher.update(std.mem.sliceAsBytes(types));
......@@ -19599,35 +19011,33 @@ fn structInitAnon(
1959919011 break :hash hasher.final();
1960019012 };
1960119013 const tracked_inst = try block.trackZir(inst);
19602 const struct_ty = switch (try ip.getStructType(gpa, io, pt.tid, .{
19603 .layout = .auto,
19014 const struct_ty: Type = switch (try ip.getReifiedStructType(gpa, io, pt.tid, .{
19015 .zir_index = tracked_inst,
19016 .type_hash = type_hash,
1960419017 .fields_len = extra_data.fields_len,
19605 .known_non_opv = false,
19606 .requires_comptime = .unknown,
19018 .layout = .auto,
1960719019 .any_comptime_fields = any_values,
19608 .any_default_inits = any_values,
19609 .inits_resolved = true,
19610 .any_aligned_fields = false,
19611 .key = .{ .reified = .{
19612 .zir_index = tracked_inst,
19613 .type_hash = type_hash,
19614 } },
19615 }, false)) {
19020 .any_field_defaults = any_values,
19021 .any_field_aligns = false,
19022 .packed_backing_int_type = .none,
19023 })) {
19024 .existing => |ty| .fromInterned(ty),
1961619025 .wip => |wip| ty: {
1961719026 errdefer wip.cancel(ip, pt.tid);
19618 const type_name = try sema.createTypeName(block, .anon, "struct", inst, wip.index);
19619 wip.setName(ip, type_name.name, type_name.nav);
19620
19621 const struct_type = ip.loadStructType(wip.index);
19027 try sema.setTypeName(block, &wip, .anon, "struct", inst);
1962219028
19623 for (names, values, 0..) |name, init_val, field_idx| {
19624 assert(struct_type.addFieldName(ip, name) == null);
19625 if (init_val != .none) struct_type.setFieldComptime(ip, field_idx);
19626 }
19627
19628 @memcpy(struct_type.field_types.get(ip), types);
19029 // Reified structs have field information populated immediately.
19030 @memcpy(wip.field_names.get(ip), names);
19031 @memcpy(wip.field_types.get(ip), types);
1962919032 if (any_values) {
19630 @memcpy(struct_type.field_inits.get(ip), values);
19033 @memcpy(wip.field_values.get(ip), values);
19034 @memset(wip.field_is_comptime_bits.getAll(ip), 0);
19035 for (values, 0..) |val, field_index| {
19036 if (val == .none) continue;
19037 const bit_bag_index = field_index / 32;
19038 const mask = @as(u32, 1) << @intCast(field_index % 32);
19039 wip.field_is_comptime_bits.getAll(ip)[bit_bag_index] |= mask;
19040 }
1963119041 }
1963219042
1963319043 const new_namespace_index = try pt.createNamespace(.{
......@@ -19636,30 +19046,24 @@ fn structInitAnon(
1963619046 .file_scope = block.getFileScopeIndex(zcu),
1963719047 .generation = zcu.generation,
1963819048 });
19639 try zcu.comp.queueJob(.{ .resolve_type_fully = wip.index });
19640 codegen_type: {
19641 if (zcu.comp.config.use_llvm) break :codegen_type;
19642 if (block.ownerModule().strip) break :codegen_type;
19643 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
19644 try zcu.comp.queueJob(.{ .link_type = wip.index });
19645 }
19049 errdefer pt.destroyNamespace(new_namespace_index);
1964619050 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
19647 break :ty wip.finish(ip, new_namespace_index);
19051 break :ty .fromInterned(wip.finish(ip, new_namespace_index));
1964819052 },
19649 .existing => |ty| ty,
1965019053 };
19651 try sema.declareDependency(.{ .interned = struct_ty });
1965219054 try sema.addTypeReferenceEntry(src, struct_ty);
19055 // No need for `ensureNamespaceUpToDate` because this type's namespace is always empty.
19056 try sema.ensureLayoutResolved(struct_ty, src, .init);
1965319057
1965419058 _ = opt_runtime_index orelse {
19655 const struct_val = try pt.aggregateValue(.fromInterned(struct_ty), values);
19656 return sema.addConstantMaybeRef(struct_val.toIntern(), is_ref);
19059 const struct_val = try pt.aggregateValue(struct_ty, values);
19060 return sema.addConstantMaybeRef(struct_val, is_ref);
1965719061 };
1965819062
1965919063 if (is_ref) {
1966019064 const target = zcu.getTarget();
19661 const alloc_ty = try pt.ptrTypeSema(.{
19662 .child = struct_ty,
19065 const alloc_ty = try pt.ptrType(.{
19066 .child = struct_ty.toIntern(),
1966319067 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1966419068 });
1966519069 const alloc = try block.addTy(.alloc, alloc_ty);
......@@ -19672,12 +19076,12 @@ fn structInitAnon(
1967219076 };
1967319077 extra_index = item.end;
1967419078
19675 const field_ptr_ty = try pt.ptrTypeSema(.{
19079 const field_ptr_ty = try pt.ptrType(.{
1967619080 .child = field_ty,
1967719081 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1967819082 });
1967919083 if (values[i] == .none) {
19680 const init = try sema.resolveInst(item.data.init);
19084 const init = sema.resolveInst(item.data.init);
1968119085 const field_ptr = try block.addStructFieldPtr(alloc, i, field_ptr_ty);
1968219086 _ = try block.addBinOp(.store, field_ptr, init);
1968319087 }
......@@ -19694,10 +19098,10 @@ fn structInitAnon(
1969419098 .typed_init => sema.code.extraData(Zir.Inst.StructInit.Item, extra_index),
1969519099 };
1969619100 extra_index = item.end;
19697 element_refs[i] = try sema.resolveInst(item.data.init);
19101 element_refs[i] = sema.resolveInst(item.data.init);
1969819102 }
1969919103
19700 return block.addAggregateInit(.fromInterned(struct_ty), element_refs);
19104 return block.addAggregateInit(struct_ty, element_refs);
1970119105}
1970219106
1970319107fn zirArrayInit(
......@@ -19737,17 +19141,16 @@ fn zirArrayInit(
1973719141 } });
1973819142 // Less inits than needed.
1973919143 if (i + 2 > args.len) if (is_tuple) {
19740 const default_val = array_ty.structFieldDefaultValue(i, zcu).toIntern();
19741 if (default_val == .unreachable_value) {
19144 const default_val = array_ty.structFieldDefaultValue(i, zcu) orelse {
1974219145 const template = "missing tuple field with index {d}";
1974319146 if (root_msg) |msg| {
1974419147 try sema.errNote(src, msg, template, .{i});
1974519148 } else {
1974619149 root_msg = try sema.errMsg(src, template, .{i});
1974719150 }
19748 } else {
19749 dest.* = Air.internedToRef(default_val);
19750 }
19151 continue;
19152 };
19153 dest.* = .fromValue(default_val);
1975119154 continue;
1975219155 } else {
1975319156 dest.* = Air.internedToRef(sentinel_val.?.toIntern());
......@@ -19755,15 +19158,13 @@ fn zirArrayInit(
1975519158 };
1975619159
1975719160 const arg = args[i + 1];
19758 const resolved_arg = try sema.resolveInst(arg);
19161 const resolved_arg = sema.resolveInst(arg);
1975919162 const elem_ty = if (is_tuple)
1976019163 array_ty.fieldType(i, zcu)
1976119164 else
19762 array_ty.elemType2(zcu);
19165 array_ty.childType(zcu);
1976319166 dest.* = try sema.coerce(block, elem_ty, resolved_arg, elem_src);
1976419167 if (is_tuple) {
19765 if (array_ty.structFieldIsComptime(i, zcu))
19766 try array_ty.resolveStructFieldInits(pt);
1976719168 if (try array_ty.structFieldValueComptime(pt, i)) |field_val| {
1976819169 const init_val = try sema.resolveConstValue(block, elem_src, dest.*, .{ .simple = .stored_to_comptime_field });
1976919170 if (!field_val.eql(init_val, elem_ty, zcu)) {
......@@ -19788,17 +19189,17 @@ fn zirArrayInit(
1978819189 const elem_vals = try sema.arena.alloc(InternPool.Index, resolved_args.len);
1978919190 for (elem_vals, resolved_args) |*val, arg| {
1979019191 // We checked that all args are comptime above.
19791 val.* = (sema.resolveValue(arg) catch unreachable).?.toIntern();
19192 val.* = sema.resolveValue(arg).?.toIntern();
1979219193 }
1979319194 const arr_val = try pt.aggregateValue(array_ty, elem_vals);
1979419195 const result_ref = try sema.coerce(block, result_ty, Air.internedToRef(arr_val.toIntern()), src);
19795 const result_val = (try sema.resolveValue(result_ref)).?;
19796 return sema.addConstantMaybeRef(result_val.toIntern(), is_ref);
19196 const result_val = (sema.resolveValue(result_ref)).?;
19197 return sema.addConstantMaybeRef(result_val, is_ref);
1979719198 };
1979819199
1979919200 if (is_ref) {
1980019201 const target = zcu.getTarget();
19801 const alloc_ty = try pt.ptrTypeSema(.{
19202 const alloc_ty = try pt.ptrType(.{
1980219203 .child = result_ty.toIntern(),
1980319204 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1980419205 });
......@@ -19807,7 +19208,7 @@ fn zirArrayInit(
1980719208
1980819209 if (is_tuple) {
1980919210 for (resolved_args, 0..) |arg, i| {
19810 const elem_ptr_ty = try pt.ptrTypeSema(.{
19211 const elem_ptr_ty = try pt.ptrType(.{
1981119212 .child = array_ty.fieldType(i, zcu).toIntern(),
1981219213 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1981319214 });
......@@ -19820,8 +19221,8 @@ fn zirArrayInit(
1982019221 return sema.makePtrConst(block, alloc);
1982119222 }
1982219223
19823 const elem_ptr_ty = try pt.ptrTypeSema(.{
19824 .child = array_ty.elemType2(zcu).toIntern(),
19224 const elem_ptr_ty = try pt.ptrType(.{
19225 .child = array_ty.childType(zcu).toIntern(),
1982519226 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1982619227 });
1982719228 const elem_ptr_ty_ref = Air.internedToRef(elem_ptr_ty.toIntern());
......@@ -19875,7 +19276,7 @@ fn arrayInitAnon(
1987519276 .init_node_offset = src.offset.node_offset.x,
1987619277 .elem_index = @intCast(i),
1987719278 } });
19878 const elem = try sema.resolveInst(operand);
19279 const elem = sema.resolveInst(operand);
1987919280 types[i] = sema.typeOf(elem).toIntern();
1988019281 if (Type.fromInterned(types[i]).zigTypeTag(zcu) == .@"opaque") {
1988119282 const msg = msg: {
......@@ -19887,7 +19288,7 @@ fn arrayInitAnon(
1988719288 };
1988819289 return sema.failWithOwnedErrorMsg(block, msg);
1988919290 }
19890 if (try sema.resolveValue(elem)) |val| {
19291 if (sema.resolveValue(elem)) |val| {
1989119292 values[i] = val.toIntern();
1989219293 any_comptime = true;
1989319294 } else {
......@@ -19917,7 +19318,7 @@ fn arrayInitAnon(
1991719318
1991819319 const runtime_src = opt_runtime_src orelse {
1991919320 const tuple_val = try pt.aggregateValue(tuple_ty, values);
19920 return sema.addConstantMaybeRef(tuple_val.toIntern(), is_ref);
19321 return sema.addConstantMaybeRef(tuple_val, is_ref);
1992119322 };
1992219323
1992319324 try sema.requireRuntimeBlock(block, src, runtime_src);
......@@ -19927,25 +19328,25 @@ fn arrayInitAnon(
1992719328 .init_node_offset = src.offset.node_offset.x,
1992819329 .elem_index = @intCast(i),
1992919330 } });
19930 try sema.validateRuntimeValue(block, operand_src, try sema.resolveInst(operand));
19331 try sema.validateRuntimeValue(block, operand_src, sema.resolveInst(operand));
1993119332 }
1993219333
1993319334 if (is_ref) {
1993419335 const target = sema.pt.zcu.getTarget();
19935 const alloc_ty = try pt.ptrTypeSema(.{
19336 const alloc_ty = try pt.ptrType(.{
1993619337 .child = tuple_ty.toIntern(),
1993719338 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1993819339 });
1993919340 const alloc = try block.addTy(.alloc, alloc_ty);
1994019341 for (operands, 0..) |operand, i_usize| {
1994119342 const i: u32 = @intCast(i_usize);
19942 const field_ptr_ty = try pt.ptrTypeSema(.{
19343 const field_ptr_ty = try pt.ptrType(.{
1994319344 .child = types[i],
1994419345 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
1994519346 });
1994619347 if (values[i] == .none) {
1994719348 const field_ptr = try block.addStructFieldPtr(alloc, i, field_ptr_ty);
19948 _ = try block.addBinOp(.store, field_ptr, try sema.resolveInst(operand));
19349 _ = try block.addBinOp(.store, field_ptr, sema.resolveInst(operand));
1994919350 }
1995019351 }
1995119352
......@@ -19954,14 +19355,14 @@ fn arrayInitAnon(
1995419355
1995519356 const element_refs = try sema.arena.alloc(Air.Inst.Ref, operands.len);
1995619357 for (operands, 0..) |operand, i| {
19957 element_refs[i] = try sema.resolveInst(operand);
19358 element_refs[i] = sema.resolveInst(operand);
1995819359 }
1995919360
1996019361 return block.addAggregateInit(tuple_ty, element_refs);
1996119362}
1996219363
19963fn addConstantMaybeRef(sema: *Sema, val: InternPool.Index, is_ref: bool) !Air.Inst.Ref {
19964 return if (is_ref) sema.uavRef(val) else Air.internedToRef(val);
19364fn addConstantMaybeRef(sema: *Sema, val: Value, is_ref: bool) !Air.Inst.Ref {
19365 return if (is_ref) sema.uavRef(val) else .fromValue(val);
1996519366}
1996619367
1996719368fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -19971,6 +19372,7 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
1997119372 const field_src = block.builtinCallArgSrc(inst_data.src_node, 1);
1997219373 const aggregate_ty = try sema.resolveType(block, ty_src, extra.container_type);
1997319374 const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{ .simple = .field_name });
19375 try sema.ensureLayoutResolved(aggregate_ty, ty_src, .field_queried);
1997419376 return sema.fieldType(block, aggregate_ty, field_name, field_src, ty_src);
1997519377}
1997619378
......@@ -19990,9 +19392,11 @@ fn zirStructInitFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
1999019392 const aggregate_ty = wrapped_aggregate_ty.optEuBaseType(zcu);
1999119393 const zir_field_name = sema.code.nullTerminatedString(extra.name_start);
1999219394 const field_name = try ip.getOrPutString(gpa, io, pt.tid, zir_field_name, .no_embedded_nulls);
19395 try sema.ensureLayoutResolved(aggregate_ty, ty_src, .init);
1999319396 return sema.fieldType(block, aggregate_ty, field_name, field_name_src, ty_src);
1999419397}
1999519398
19399/// Asserts that the layout of `aggregate_ty` is resolved.
1999619400fn fieldType(
1999719401 sema: *Sema,
1999819402 block: *Block,
......@@ -20004,9 +19408,9 @@ fn fieldType(
2000419408 const pt = sema.pt;
2000519409 const zcu = pt.zcu;
2000619410 const ip = &zcu.intern_pool;
19411 aggregate_ty.assertHasLayout(zcu);
2000719412 var cur_ty = aggregate_ty;
2000819413 while (true) {
20009 try cur_ty.resolveFields(pt);
2001019414 switch (cur_ty.zigTypeTag(zcu)) {
2001119415 .@"struct" => switch (ip.indexToKey(cur_ty.toIntern())) {
2001219416 .tuple_type => |tuple| {
......@@ -20024,10 +19428,11 @@ fn fieldType(
2002419428 },
2002519429 .@"union" => {
2002619430 const union_obj = zcu.typeToUnion(cur_ty).?;
20027 const field_index = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse
19431 const enum_obj = ip.loadEnumType(union_obj.enum_tag_type);
19432 const field_index = enum_obj.nameIndex(ip, field_name) orelse
2002819433 return sema.failWithBadUnionFieldAccess(block, cur_ty, union_obj, field_src, field_name);
2002919434 const field_ty = union_obj.field_types.get(ip)[field_index];
20030 return Air.internedToRef(field_ty);
19435 return .fromIntern(field_ty);
2003119436 },
2003219437 .optional => {
2003319438 // Struct/array init through optional requires the child type to not be a pointer.
......@@ -20056,7 +19461,6 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
2005619461 const zcu = pt.zcu;
2005719462 const ip = &zcu.intern_pool;
2005819463 const stack_trace_ty = try sema.getBuiltinType(block.nodeOffset(.zero), .StackTrace);
20059 try stack_trace_ty.resolveFields(pt);
2006019464 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
2006119465 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
2006219466
......@@ -20064,7 +19468,14 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
2006419468 .func => |func| if (ip.funcAnalysisUnordered(func).has_error_trace and block.ownerModule().error_tracing) {
2006519469 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
2006619470 },
20067 .@"comptime", .nav_ty, .nav_val, .type, .memoized_state => {},
19471
19472 .@"comptime",
19473 .nav_ty,
19474 .nav_val,
19475 .type_layout,
19476 .struct_defaults,
19477 .memoized_state,
19478 => {},
2006819479 }
2006919480 return Air.internedToRef(try pt.intern(.{ .opt = .{
2007019481 .ty = opt_ptr_stack_trace_ty.toIntern(),
......@@ -20083,15 +19494,16 @@ fn zirFrame(
2008319494}
2008419495
2008519496fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
20086 const zcu = sema.pt.zcu;
19497 const pt = sema.pt;
19498 const zcu = pt.zcu;
2008719499 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
2008819500 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2008919501 const ty = try sema.resolveType(block, operand_src, inst_data.operand);
19502 try sema.ensureLayoutResolved(ty, operand_src, .align_of);
2009019503 if (ty.isNoReturn(zcu)) {
20091 return sema.fail(block, operand_src, "no align available for type '{f}'", .{ty.fmt(sema.pt)});
19504 return sema.fail(block, operand_src, "no align available for uninstantiable type '{f}'", .{ty.fmt(sema.pt)});
2009219505 }
20093 const val = try ty.lazyAbiAlignment(sema.pt);
20094 return Air.internedToRef(val.toIntern());
19506 return .fromValue(try pt.intValue(.comptime_int, ty.abiAlignment(zcu).toByteUnits().?));
2009519507}
2009619508
2009719509fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -20099,7 +19511,7 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2009919511 const zcu = pt.zcu;
2010019512 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
2010119513 const src = block.nodeOffset(inst_data.src_node);
20102 const operand = try sema.resolveInst(inst_data.operand);
19514 const operand = sema.resolveInst(inst_data.operand);
2010319515 const operand_ty = sema.typeOf(operand);
2010419516 const is_vector = operand_ty.zigTypeTag(zcu) == .vector;
2010519517 const operand_scalar_ty = operand_ty.scalarType(zcu);
......@@ -20108,7 +19520,7 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2010819520 }
2010919521 const len = if (is_vector) operand_ty.vectorLen(zcu) else undefined;
2011019522 const dest_ty: Type = if (is_vector) try pt.vectorType(.{ .child = .u1_type, .len = len }) else .u1;
20111 if (try sema.resolveValue(operand)) |val| {
19523 if (sema.resolveValue(operand)) |val| {
2011219524 if (!is_vector) {
2011319525 return if (val.isUndef(zcu)) .undef_u1 else if (val.toBool()) .one_u1 else .zero_u1;
2011419526 }
......@@ -20131,7 +19543,7 @@ fn zirIntFromBool(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2013119543fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
2013219544 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
2013319545 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
20134 const uncoerced_operand = try sema.resolveInst(inst_data.operand);
19546 const uncoerced_operand = sema.resolveInst(inst_data.operand);
2013519547 const operand = try sema.coerce(block, .anyerror, uncoerced_operand, operand_src);
2013619548
2013719549 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {
......@@ -20152,7 +19564,7 @@ fn zirAbs(
2015219564 const pt = sema.pt;
2015319565 const zcu = pt.zcu;
2015419566 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
20155 const operand = try sema.resolveInst(inst_data.operand);
19567 const operand = sema.resolveInst(inst_data.operand);
2015619568 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2015719569 const operand_ty = sema.typeOf(operand);
2015819570 const scalar_ty = operand_ty.scalarType(zcu);
......@@ -20183,7 +19595,7 @@ fn maybeConstantUnaryMath(
2018319595 const pt = sema.pt;
2018419596 const zcu = pt.zcu;
2018519597 switch (result_ty.zigTypeTag(zcu)) {
20186 .vector => if (try sema.resolveValue(operand)) |val| {
19598 .vector => if (sema.resolveValue(operand)) |val| {
2018719599 const scalar_ty = result_ty.scalarType(zcu);
2018819600 const vec_len = result_ty.vectorLen(zcu);
2018919601 if (val.isUndef(zcu))
......@@ -20196,7 +19608,7 @@ fn maybeConstantUnaryMath(
2019619608 }
2019719609 return Air.internedToRef((try pt.aggregateValue(result_ty, elems)).toIntern());
2019819610 },
20199 else => if (try sema.resolveValue(operand)) |operand_val| {
19611 else => if (sema.resolveValue(operand)) |operand_val| {
2020019612 if (operand_val.isUndef(zcu))
2020119613 return try pt.undefRef(result_ty);
2020219614 const result_val = try eval(operand_val, result_ty, sema.arena, pt);
......@@ -20219,7 +19631,7 @@ fn zirUnaryMath(
2021919631 const pt = sema.pt;
2022019632 const zcu = pt.zcu;
2022119633 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
20222 const operand = try sema.resolveInst(inst_data.operand);
19634 const operand = sema.resolveInst(inst_data.operand);
2022319635 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2022419636 const operand_ty = sema.typeOf(operand);
2022519637 const scalar_ty = operand_ty.scalarType(zcu);
......@@ -20244,12 +19656,11 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2024419656 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
2024519657 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2024619658 const src = block.nodeOffset(inst_data.src_node);
20247 const operand = try sema.resolveInst(inst_data.operand);
19659 const operand = sema.resolveInst(inst_data.operand);
2024819660 const operand_ty = sema.typeOf(operand);
2024919661 const pt = sema.pt;
2025019662 const zcu = pt.zcu;
2025119663 const ip = &zcu.intern_pool;
20252 try operand_ty.resolveLayout(pt);
2025319664 const enum_ty = switch (operand_ty.zigTypeTag(zcu)) {
2025419665 .enum_literal => {
2025519666 const val = (try sema.resolveDefinedValue(block, operand_src, operand)).?;
......@@ -20332,17 +19743,17 @@ fn zirReifySliceArgTy(
2033219743 // zig fmt: on
2033319744 };
2033419745
20335 const operand_ty = try pt.ptrTypeSema(.{
19746 const operand_ty = try pt.ptrType(.{
2033619747 .child = in_scalar_ty.toIntern(),
2033719748 .flags = .{ .size = .slice, .is_const = true },
2033819749 });
2033919750
20340 const operand_uncoerced = try sema.resolveInst(extra.operand);
19751 const operand_uncoerced = sema.resolveInst(extra.operand);
2034119752 const operand_coerced = try sema.coerce(block, operand_ty, operand_uncoerced, src);
2034219753 const operand_val = try sema.resolveConstDefinedValue(block, src, operand_coerced, .{ .simple = comptime_reason });
2034319754 const len_val: Value = .fromInterned(zcu.intern_pool.indexToKey(operand_val.toIntern()).slice.len);
2034419755 if (len_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, src, null);
20345 const len = try len_val.toUnsignedIntSema(pt);
19756 const len = len_val.toUnsignedInt(zcu);
2034619757
2034719758 return .fromType(try pt.singleConstPtrType(try pt.arrayType(.{
2034819759 .len = len,
......@@ -20365,12 +19776,12 @@ fn zirReifyEnumValueSliceTy(
2036519776
2036619777 const int_tag_ty = try sema.resolveType(block, int_tag_ty_src, extra.lhs);
2036719778
20368 const operand_uncoerced = try sema.resolveInst(extra.rhs);
19779 const operand_uncoerced = sema.resolveInst(extra.rhs);
2036919780 const operand_coerced = try sema.coerce(block, .slice_const_slice_const_u8, operand_uncoerced, field_names_src);
2037019781 const operand_val = try sema.resolveConstDefinedValue(block, field_names_src, operand_coerced, .{ .simple = .enum_field_names });
2037119782 const len_val: Value = .fromInterned(zcu.intern_pool.indexToKey(operand_val.toIntern()).slice.len);
2037219783 if (len_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, field_names_src, null);
20373 const len = try len_val.toUnsignedIntSema(pt);
19784 const len = len_val.toUnsignedInt(zcu);
2037419785
2037519786 return .fromType(try pt.singleConstPtrType(try pt.arrayType(.{
2037619787 .len = len,
......@@ -20410,7 +19821,7 @@ fn zirReifyTuple(
2041019821 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
2041119822 const operand_src = block.builtinCallArgSrc(extra.node, 0);
2041219823
20413 const types_uncoerced = try sema.resolveInst(extra.operand);
19824 const types_uncoerced = sema.resolveInst(extra.operand);
2041419825 const types_coerced = try sema.coerce(block, .slice_const_type, types_uncoerced, operand_src);
2041519826 const types_slice_val = try sema.resolveConstDefinedValue(block, operand_src, types_coerced, .{ .simple = .tuple_field_types });
2041619827 const types_array_val = try sema.derefSliceAsArray(block, operand_src, types_slice_val, .{ .simple = .tuple_field_types });
......@@ -20422,6 +19833,7 @@ fn zirReifyTuple(
2042219833 if (field_ty_val.isUndef(zcu)) {
2042319834 return sema.failWithUseOfUndef(block, operand_src, null);
2042419835 }
19836 try sema.validateTupleFieldType(block, field_ty_val.toType(), operand_src);
2042519837 field_ty.* = field_ty_val.toIntern();
2042619838 }
2042719839
......@@ -20456,12 +19868,12 @@ fn zirReifyPointer(
2045619868 const size_ty = try sema.getBuiltinType(size_src, .@"Type.Pointer.Size");
2045719869 const attrs_ty = try sema.getBuiltinType(attrs_src, .@"Type.Pointer.Attributes");
2045819870
20459 const size_uncoerced = try sema.resolveInst(extra.size);
19871 const size_uncoerced = sema.resolveInst(extra.size);
2046019872 const size_coerced = try sema.coerce(block, size_ty, size_uncoerced, size_src);
2046119873 const size_val = try sema.resolveConstDefinedValue(block, size_src, size_coerced, .{ .simple = .pointer_size });
2046219874 const size = try sema.interpretBuiltinType(block, size_src, size_val, std.builtin.Type.Pointer.Size);
2046319875
20464 const attrs_uncoerced = try sema.resolveInst(extra.attrs);
19876 const attrs_uncoerced = sema.resolveInst(extra.attrs);
2046519877 const attrs_coerced = try sema.coerce(block, attrs_ty, attrs_uncoerced, attrs_src);
2046619878 const attrs_val = try sema.resolveConstDefinedValue(block, attrs_src, attrs_coerced, .{ .simple = .pointer_attrs });
2046719879 const attrs = try sema.interpretBuiltinType(block, attrs_src, attrs_val, std.builtin.Type.Pointer.Attributes);
......@@ -20489,18 +19901,8 @@ fn zirReifyPointer(
2048919901 else => {},
2049019902 }
2049119903
20492 if (size == .c and !try sema.validateExternType(elem_ty, .other)) {
20493 return sema.failWithOwnedErrorMsg(block, msg: {
20494 const msg = try sema.errMsg(src, "C pointers cannot point to non-C-ABI-compatible type '{f}'", .{elem_ty.fmt(pt)});
20495 errdefer msg.destroy(gpa);
20496 try sema.explainWhyTypeIsNotExtern(msg, elem_ty_src, elem_ty, .other);
20497 try sema.addDeclaredHereNote(msg, elem_ty);
20498 break :msg msg;
20499 });
20500 }
20501
2050219904 const sentinel_ty = try pt.optionalType(elem_ty.toIntern());
20503 const sentinel_uncoerced = try sema.resolveInst(extra.sentinel);
19905 const sentinel_uncoerced = sema.resolveInst(extra.sentinel);
2050419906 const sentinel_coerced = try sema.coerce(block, sentinel_ty, sentinel_uncoerced, sentinel_src);
2050519907 const sentinel_val = try sema.resolveConstDefinedValue(block, sentinel_src, sentinel_coerced, .{ .simple = .pointer_sentinel });
2050619908 const opt_sentinel = sentinel_val.optionalValue(zcu);
......@@ -20516,7 +19918,7 @@ fn zirReifyPointer(
2051619918 }
2051719919 }
2051819920
20519 return .fromType(try pt.ptrTypeSema(.{
19921 return .fromType(try pt.ptrType(.{
2052019922 .child = elem_ty.toIntern(),
2052119923 .sentinel = if (opt_sentinel) |s| s.toIntern() else .none,
2052219924 .flags = .{
......@@ -20554,7 +19956,7 @@ fn zirReifyFn(
2055419956 const single_param_attrs_ty = try sema.getBuiltinType(param_attrs_src, .@"Type.Fn.Param.Attributes");
2055519957 const fn_attrs_ty = try sema.getBuiltinType(fn_attrs_src, .@"Type.Fn.Attributes");
2055619958
20557 const param_types_uncoerced = try sema.resolveInst(extra.param_types);
19959 const param_types_uncoerced = sema.resolveInst(extra.param_types);
2055819960 const param_types_coerced = try sema.coerce(block, .slice_const_type, param_types_uncoerced, param_types_src);
2055919961 const param_types_slice = try sema.resolveConstDefinedValue(block, param_types_src, param_types_coerced, .{ .simple = .fn_param_types });
2056019962 const param_types_arr = try sema.derefSliceAsArray(block, param_types_src, param_types_slice, .{ .simple = .fn_param_types });
......@@ -20565,14 +19967,14 @@ fn zirReifyFn(
2056519967 .len = params_len,
2056619968 .child = single_param_attrs_ty.toIntern(),
2056719969 }));
20568 const param_attrs_uncoerced = try sema.resolveInst(extra.param_attrs);
19970 const param_attrs_uncoerced = sema.resolveInst(extra.param_attrs);
2056919971 const param_attrs_coerced = try sema.coerce(block, param_attrs_ty, param_attrs_uncoerced, param_attrs_src);
2057019972 const param_attrs_slice = try sema.resolveConstDefinedValue(block, param_attrs_src, param_attrs_coerced, .{ .simple = .fn_param_attrs });
2057119973 const param_attrs_arr = try sema.derefSliceAsArray(block, param_attrs_src, param_attrs_slice, .{ .simple = .fn_param_attrs });
2057219974
2057319975 const ret_ty = try sema.resolveType(block, ret_ty_src, extra.ret_ty);
2057419976
20575 const fn_attrs_uncoerced = try sema.resolveInst(extra.fn_attrs);
19977 const fn_attrs_uncoerced = sema.resolveInst(extra.fn_attrs);
2057619978 const fn_attrs_coerced = try sema.coerce(block, fn_attrs_ty, fn_attrs_uncoerced, fn_attrs_src);
2057719979 const fn_attrs_val = try sema.resolveConstDefinedValue(block, fn_attrs_src, fn_attrs_coerced, .{ .simple = .fn_attrs });
2057819980 const fn_attrs = try sema.interpretBuiltinType(block, fn_attrs_src, fn_attrs_val, std.builtin.Type.Fn.Attributes);
......@@ -20587,17 +19989,15 @@ fn zirReifyFn(
2058719989 try param_attrs_arr.elemValue(pt, param_idx),
2058819990 std.builtin.Type.Fn.Param.Attributes,
2058919991 );
20590 try sema.checkParamTypeCommon(
19992 try sema.checkParamType(
2059119993 block,
2059219994 @intCast(param_idx),
2059319995 param_ty,
19996 false,
2059419997 param_attrs.@"noalias",
2059519998 param_types_src,
2059619999 fn_attrs.@"callconv",
2059720000 );
20598 if (try param_ty.comptimeOnlySema(pt)) {
20599 return sema.fail(block, param_attrs_src, "cannot reify function type with comptime-only parameter type '{f}'", .{param_ty.fmt(pt)});
20600 }
2060120001 if (param_attrs.@"noalias") {
2060220002 if (param_idx > 31) {
2060320003 return sema.fail(block, param_attrs_src, "this compiler implementation only supports 'noalias' on the first 32 parameters", .{});
......@@ -20611,7 +20011,7 @@ fn zirReifyFn(
2061120011 try sema.checkCallConvSupportsVarArgs(block, fn_attrs_src, fn_attrs.@"callconv");
2061220012 }
2061320013
20614 try sema.checkReturnTypeAndCallConvCommon(
20014 try sema.checkReturnTypeAndCallConv(
2061520015 block,
2061620016 ret_ty,
2061720017 ret_ty_src,
......@@ -20621,9 +20021,6 @@ fn zirReifyFn(
2062120021 false,
2062220022 false,
2062320023 );
20624 if (try ret_ty.comptimeOnlySema(pt)) {
20625 return sema.fail(block, param_attrs_src, "cannot reify function type with comptime-only return type '{f}'", .{ret_ty.fmt(pt)});
20626 }
2062720024
2062820025 return .fromIntern(try ip.getFuncType(gpa, io, pt.tid, .{
2062920026 .param_types = param_types_ip,
......@@ -20632,7 +20029,6 @@ fn zirReifyFn(
2063220029 .return_type = ret_ty.toIntern(),
2063320030 .cc = fn_attrs.@"callconv",
2063420031 .is_var_args = fn_attrs.varargs,
20635 .is_generic = false,
2063620032 .is_noinline = false,
2063720033 }));
2063820034}
......@@ -20653,6 +20049,7 @@ fn zirReifyStruct(
2065320049 const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small);
2065420050 const extra = sema.code.extraData(Zir.Inst.ReifyStruct, extended.operand).data;
2065520051 const tracked_inst = try block.trackZir(inst);
20052
2065620053 const src: LazySrcLoc = .{
2065720054 .base_node_inst = tracked_inst,
2065820055 .offset = .nodeOffset(.zero),
......@@ -20697,16 +20094,16 @@ fn zirReifyStruct(
2069720094 const container_layout_ty = try sema.getBuiltinType(layout_src, .@"Type.ContainerLayout");
2069820095 const single_field_attrs_ty = try sema.getBuiltinType(field_attrs_src, .@"Type.StructField.Attributes");
2069920096
20700 const layout_uncoerced = try sema.resolveInst(extra.layout);
20097 const layout_uncoerced = sema.resolveInst(extra.layout);
2070120098 const layout_coerced = try sema.coerce(block, container_layout_ty, layout_uncoerced, layout_src);
2070220099 const layout_val = try sema.resolveConstDefinedValue(block, layout_src, layout_coerced, .{ .simple = .struct_layout });
2070320100 const layout = try sema.interpretBuiltinType(block, layout_src, layout_val, std.builtin.Type.ContainerLayout);
2070420101
20705 const backing_int_ty_uncoerced = try sema.resolveInst(extra.backing_ty);
20102 const backing_int_ty_uncoerced = sema.resolveInst(extra.backing_ty);
2070620103 const backing_int_ty_coerced = try sema.coerce(block, .optional_type, backing_int_ty_uncoerced, backing_ty_src);
20707 const backing_int_ty_val = try sema.resolveConstDefinedValue(block, backing_ty_src, backing_int_ty_coerced, .{ .simple = .type });
20104 const backing_int_ty_val = try sema.resolveConstDefinedValue(block, backing_ty_src, backing_int_ty_coerced, .{ .simple = .packed_struct_backing_int_type });
2070820105
20709 const field_names_uncoerced = try sema.resolveInst(extra.field_names);
20106 const field_names_uncoerced = sema.resolveInst(extra.field_names);
2071020107 const field_names_coerced = try sema.coerce(block, .slice_const_slice_const_u8, field_names_uncoerced, field_names_src);
2071120108 const field_names_slice = try sema.resolveConstDefinedValue(block, field_names_src, field_names_coerced, .{ .simple = .struct_field_names });
2071220109 const field_names_arr = try sema.derefSliceAsArray(block, field_names_src, field_names_slice, .{ .simple = .struct_field_names });
......@@ -20722,12 +20119,12 @@ fn zirReifyStruct(
2072220119 .child = single_field_attrs_ty.toIntern(),
2072320120 }));
2072420121
20725 const field_types_uncoerced = try sema.resolveInst(extra.field_types);
20122 const field_types_uncoerced = sema.resolveInst(extra.field_types);
2072620123 const field_types_coerced = try sema.coerce(block, field_types_ty, field_types_uncoerced, field_types_src);
2072720124 const field_types_slice = try sema.resolveConstDefinedValue(block, field_types_src, field_types_coerced, .{ .simple = .struct_field_types });
2072820125 const field_types_arr = try sema.derefSliceAsArray(block, field_types_src, field_types_slice, .{ .simple = .struct_field_types });
2072920126
20730 const field_attrs_uncoerced = try sema.resolveInst(extra.field_attrs);
20127 const field_attrs_uncoerced = sema.resolveInst(extra.field_attrs);
2073120128 const field_attrs_coerced = try sema.coerce(block, field_attrs_ty, field_attrs_uncoerced, field_attrs_src);
2073220129 const field_attrs_slice = try sema.resolveConstDefinedValue(block, field_attrs_src, field_attrs_coerced, .{ .simple = .struct_field_attrs });
2073320130 const field_attrs_arr = try sema.derefSliceAsArray(block, field_attrs_src, field_attrs_slice, .{ .simple = .struct_field_attrs });
......@@ -20744,19 +20141,30 @@ fn zirReifyStruct(
2074420141 return sema.failWithUseOfUndef(block, backing_ty_src, null);
2074520142 }
2074620143
20747 // The validation work here is non-trivial, and it's possible the type already exists.
20748 // So in this first pass, let's just construct a hash to optimize for this case. If the
20749 // inputs turn out to be invalid, we can cancel the WIP type later.
20144 // Most validation of this type happens during type resolution. We basically need to do the work
20145 // which AstGen would normally do. An exception is checking for duplicate field names, which is
20146 // handled by type resolution---it just simplifies some logic a little.
20147
20148 // As well as validation, we're going to gather some information about the fields, and construct
20149 // a hash representing the inputs for deduplication purposes.
2075020150
2075120151 var any_comptime_fields = false;
20752 var any_default_inits = false;
20753 var any_aligned_fields = false;
20152 var any_field_defaults = false;
20153 var any_field_aligns = false;
2075420154
20755 // For deduplication purposes, we must create a hash including all details of this type.
2075620155 // TODO: use a longer hash!
2075720156 var hasher = std.hash.Wyhash.init(0);
2075820157 std.hash.autoHash(&hasher, layout);
2075920158 std.hash.autoHash(&hasher, backing_int_ty_val);
20159
20160 const backing_int_ty: ?Type = if (backing_int_ty_val.optionalValue(zcu)) |backing| ty: {
20161 switch (layout) {
20162 .auto, .@"extern" => return sema.fail(block, backing_ty_src, "non-packed struct does not support backing integer type", .{}),
20163 .@"packed" => {},
20164 }
20165 break :ty backing.toType();
20166 } else null;
20167
2076020168 // The field *type* array has already been deduplicated for us thanks to the InternPool!
2076120169 std.hash.autoHash(&hasher, field_types_arr);
2076220170 // However, for field names and attributes, we need to actually iterate the individual fields,
......@@ -20791,207 +20199,119 @@ fn zirReifyStruct(
2079120199 field_attrs_src,
2079220200 .{ .simple = .struct_field_default_value },
2079320201 );
20794 // Resolve the value so that lazy values do not create distinct types.
20795 break :d (try sema.resolveLazyValue(deref_val)).toIntern();
20202 if (deref_val.canMutateComptimeVarState(zcu)) {
20203 return sema.failWithContainsReferenceToComptimeVar(block, field_attrs_src, field_name, "field default value", deref_val);
20204 }
20205 any_field_defaults = true;
20206 break :d deref_val.toIntern();
2079620207 };
2079720208
20209 if (field_attr_comptime.toBool()) {
20210 if (field_default == .none) {
20211 return sema.fail(block, field_attrs_src, "comptime field without default initialization value", .{});
20212 }
20213 if (layout != .auto) {
20214 return sema.fail(block, field_attrs_src, "{t} struct fields cannot be marked comptime", .{layout});
20215 }
20216 any_comptime_fields = true;
20217 }
20218
20219 if (field_attr_align.optionalValue(zcu)) |align_val| {
20220 if (layout == .@"packed") {
20221 return sema.fail(block, field_attrs_src, "packed struct fields cannot be aligned", .{});
20222 }
20223 // Trigger a compile error if the alignment is invalid.
20224 _ = try sema.validateAlign(block, field_attrs_src, align_val.toUnsignedInt(zcu));
20225 any_field_aligns = true;
20226 }
20227
2079820228 std.hash.autoHash(&hasher, .{
2079920229 field_name,
2080020230 field_attr_comptime,
2080120231 field_attr_align,
2080220232 field_default,
2080320233 });
20804
20805 if (field_attr_comptime.toBool()) any_comptime_fields = true;
20806 if (field_attr_align.optionalValue(zcu)) |_| any_aligned_fields = true;
20807 if (field_default != .none) any_default_inits = true;
20808 }
20809
20810 // Some basic validation to avoid a bogus `getStructType` call...
20811 const backing_int_ty: ?Type = if (backing_int_ty_val.optionalValue(zcu)) |backing| ty: {
20812 switch (layout) {
20813 .auto, .@"extern" => return sema.fail(block, backing_ty_src, "non-packed struct does not support backing integer type", .{}),
20814 .@"packed" => {},
20815 }
20816 break :ty backing.toType();
20817 } else null;
20818 if (any_aligned_fields and layout == .@"packed") {
20819 return sema.fail(block, field_attrs_src, "packed struct fields cannot be aligned", .{});
20820 }
20821 if (any_comptime_fields and layout != .auto) {
20822 return sema.fail(block, field_attrs_src, "{t} struct fields cannot be marked comptime", .{layout});
2082320234 }
2082420235
20825 const wip_ty = switch (try ip.getStructType(gpa, io, pt.tid, .{
20826 .layout = layout,
20236 switch (try ip.getReifiedStructType(gpa, io, pt.tid, .{
20237 .zir_index = tracked_inst,
20238 .type_hash = hasher.final(),
2082720239 .fields_len = @intCast(fields_len),
20828 .known_non_opv = false,
20829 .requires_comptime = .unknown,
20240 .layout = layout,
2083020241 .any_comptime_fields = any_comptime_fields,
20831 .any_default_inits = any_default_inits,
20832 .any_aligned_fields = any_aligned_fields,
20833 .inits_resolved = true,
20834 .key = .{ .reified = .{
20835 .zir_index = tracked_inst,
20836 .type_hash = hasher.final(),
20837 } },
20838 }, false)) {
20839 .wip => |wip| wip,
20242 .any_field_defaults = any_field_defaults,
20243 .any_field_aligns = any_field_aligns,
20244 .packed_backing_int_type = if (backing_int_ty) |ty| ty.toIntern() else .none,
20245 })) {
2084020246 .existing => |ty| {
20841 try sema.declareDependency(.{ .interned = ty });
20842 try sema.addTypeReferenceEntry(src, ty);
20843 return Air.internedToRef(ty);
20247 try sema.addTypeReferenceEntry(src, .fromInterned(ty));
20248 // No need for `ensureNamespaceUpToDate` because this type's namespace is always empty.
20249 return .fromIntern(ty);
2084420250 },
20845 };
20846 errdefer wip_ty.cancel(ip, pt.tid);
20847
20848 const type_name = try sema.createTypeName(
20849 block,
20850 name_strategy,
20851 "struct",
20852 inst,
20853 wip_ty.index,
20854 );
20855 wip_ty.setName(ip, type_name.name, type_name.nav);
20856
20857 const wip_struct_type = ip.loadStructType(wip_ty.index);
20858
20859 for (0..fields_len) |field_idx| {
20860 const field_name_val = try field_names_arr.elemValue(pt, field_idx);
20861 const field_attrs_val = try field_attrs_arr.elemValue(pt, field_idx);
20862
20863 const field_ty = (try field_types_arr.elemValue(pt, field_idx)).toType();
20864
20865 // Don't pass a reason; first loop acts as a check that this is valid.
20866 const field_name = try sema.sliceToIpString(block, field_names_src, field_name_val, undefined);
20867 if (wip_struct_type.addFieldName(ip, field_name)) |prev_index| {
20868 _ = prev_index; // TODO: better source location
20869 return sema.fail(block, field_names_src, "duplicate struct field name {f}", .{field_name.fmt(ip)});
20870 }
20871
20872 const field_attr_comptime = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex(
20873 std.builtin.Type.StructField.Attributes,
20874 "comptime",
20875 ).?);
20876 const field_attr_align = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex(
20877 std.builtin.Type.StructField.Attributes,
20878 "align",
20879 ).?);
20880 const field_attr_default_value_ptr = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex(
20881 std.builtin.Type.StructField.Attributes,
20882 "default_value_ptr",
20883 ).?);
20884
20885 if (field_attr_align.optionalValue(zcu)) |field_align_val| {
20886 assert(layout != .@"packed");
20887 const bytes = try field_align_val.toUnsignedIntSema(pt);
20888 const a = try sema.validateAlign(block, field_attrs_src, bytes);
20889 wip_struct_type.field_aligns.get(ip)[field_idx] = a;
20890 } else if (any_aligned_fields) {
20891 assert(layout != .@"packed");
20892 wip_struct_type.field_aligns.get(ip)[field_idx] = .none;
20893 }
20251 .wip => |wip| {
20252 errdefer wip.cancel(ip, pt.tid);
20253 try sema.setTypeName(block, &wip, name_strategy, "struct", inst);
20254 for (0..fields_len) |field_idx| {
20255 const field_name_val = try field_names_arr.elemValue(pt, field_idx);
20256 const field_attrs_val = try field_attrs_arr.elemValue(pt, field_idx);
20257
20258 // No source location or reason; first loop checked this is valid.
20259 const field_name = try sema.sliceToIpString(block, .unneeded, field_name_val, undefined);
20260 wip.field_names.get(ip)[field_idx] = field_name;
20261
20262 const field_ty = (try field_types_arr.elemValue(pt, field_idx)).toType();
20263 wip.field_types.get(ip)[field_idx] = field_ty.toIntern();
20264
20265 const field_attr_comptime = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex(
20266 std.builtin.Type.StructField.Attributes,
20267 "comptime",
20268 ).?);
20269 const field_attr_align = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex(
20270 std.builtin.Type.StructField.Attributes,
20271 "align",
20272 ).?);
20273 const field_attr_default_value_ptr = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex(
20274 std.builtin.Type.StructField.Attributes,
20275 "default_value_ptr",
20276 ).?);
20277
20278 if (field_attr_comptime.toBool()) {
20279 const bit_bag_index = field_idx / 32;
20280 const mask = @as(u32, 1) << @intCast(field_idx % 32);
20281 wip.field_is_comptime_bits.getAll(ip)[bit_bag_index] |= mask;
20282 }
2089420283
20895 const field_default: InternPool.Index = d: {
20896 const ptr_val = field_attr_default_value_ptr.optionalValue(zcu) orelse break :d .none;
20897 assert(any_default_inits);
20898 const ptr_ty = try pt.singleConstPtrType(field_ty);
20899 // The first loop checked that this is comptime-dereferencable.
20900 const deref_val = (try sema.pointerDeref(block, field_attrs_src, ptr_val, ptr_ty)).?;
20901 // ...but we've not checked this yet!
20902 if (deref_val.canMutateComptimeVarState(zcu)) {
20903 return sema.failWithContainsReferenceToComptimeVar(block, field_attrs_src, field_name, "field default value", deref_val);
20904 }
20905 break :d (try sema.resolveLazyValue(deref_val)).toIntern();
20906 };
20284 if (field_attr_default_value_ptr.optionalValue(zcu)) |ptr_val| {
20285 const ptr_ty = try pt.singleConstPtrType(field_ty);
20286 // No source location; first loop checked this is valid.
20287 const deref_val = (try sema.pointerDeref(block, .unneeded, ptr_val, ptr_ty)).?;
20288 wip.field_values.get(ip)[field_idx] = deref_val.toIntern();
20289 } else if (any_field_defaults) {
20290 wip.field_values.get(ip)[field_idx] = .none;
20291 }
2090720292
20908 if (field_attr_comptime.toBool()) {
20909 assert(layout == .auto);
20910 if (field_default == .none) {
20911 return sema.fail(block, field_attrs_src, "comptime field without default initialization value", .{});
20293 if (field_attr_align.optionalValue(zcu)) |field_align_val| {
20294 const bytes = field_align_val.toUnsignedInt(zcu);
20295 // No source location; first loop checked this is valid.
20296 const a = try sema.validateAlign(block, .unneeded, bytes);
20297 wip.field_aligns.get(ip)[field_idx] = a;
20298 } else if (any_field_aligns) {
20299 wip.field_aligns.get(ip)[field_idx] = .none;
20300 }
2091220301 }
20913 wip_struct_type.setFieldComptime(ip, field_idx);
20914 }
20915
20916 wip_struct_type.field_types.get(ip)[field_idx] = field_ty.toIntern();
20917 if (field_default != .none) {
20918 wip_struct_type.field_inits.get(ip)[field_idx] = field_default;
20919 }
20920
20921 switch (field_ty.zigTypeTag(zcu)) {
20922 .@"opaque" => return sema.failWithOwnedErrorMsg(block, msg: {
20923 const msg = try sema.errMsg(field_types_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
20924 errdefer msg.destroy(gpa);
20925 try sema.addDeclaredHereNote(msg, field_ty);
20926 break :msg msg;
20927 }),
20928 .noreturn => return sema.failWithOwnedErrorMsg(block, msg: {
20929 const msg = try sema.errMsg(field_types_src, "struct fields cannot be 'noreturn'", .{});
20930 errdefer msg.destroy(gpa);
20931 try sema.addDeclaredHereNote(msg, field_ty);
20932 break :msg msg;
20933 }),
20934 else => {},
20935 }
20936
20937 switch (layout) {
20938 .auto => {},
20939 .@"extern" => if (!try sema.validateExternType(field_ty, .struct_field)) {
20940 return sema.failWithOwnedErrorMsg(block, msg: {
20941 const msg = try sema.errMsg(field_types_src, "extern structs cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
20942 errdefer msg.destroy(gpa);
20943 try sema.explainWhyTypeIsNotExtern(msg, field_types_src, field_ty, .struct_field);
20944 try sema.addDeclaredHereNote(msg, field_ty);
20945 break :msg msg;
20946 });
20947 },
20948 .@"packed" => if (!try sema.validatePackedType(field_ty)) {
20949 return sema.failWithOwnedErrorMsg(block, msg: {
20950 const msg = try sema.errMsg(field_types_src, "packed structs cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
20951 errdefer msg.destroy(gpa);
20952 try sema.explainWhyTypeIsNotPacked(msg, field_types_src, field_ty);
20953 try sema.addDeclaredHereNote(msg, field_ty);
20954 break :msg msg;
20955 });
20956 },
20957 }
20958 }
20959
20960 if (layout == .@"packed") {
20961 var fields_bit_sum: u64 = 0;
20962 for (0..wip_struct_type.field_types.len) |field_idx| {
20963 const field_ty: Type = .fromInterned(wip_struct_type.field_types.get(ip)[field_idx]);
20964 try field_ty.resolveLayout(pt);
20965 fields_bit_sum += field_ty.bitSize(zcu);
20966 }
20967 if (backing_int_ty) |ty| {
20968 try sema.checkBackingIntType(block, src, ty, fields_bit_sum);
20969 wip_struct_type.setBackingIntType(ip, io, ty.toIntern());
20970 } else {
20971 const ty = try pt.intType(.unsigned, @intCast(fields_bit_sum));
20972 wip_struct_type.setBackingIntType(ip, io, ty.toIntern());
20973 }
20974 }
20975
20976 const new_namespace_index = try pt.createNamespace(.{
20977 .parent = block.namespace.toOptional(),
20978 .owner_type = wip_ty.index,
20979 .file_scope = block.getFileScopeIndex(zcu),
20980 .generation = zcu.generation,
20981 });
2098220302
20983 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
20984 codegen_type: {
20985 if (zcu.comp.config.use_llvm) break :codegen_type;
20986 if (block.ownerModule().strip) break :codegen_type;
20987 // This job depends on any resolve_type_fully jobs queued up before it.
20988 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
20989 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
20303 const new_namespace_index = try pt.createNamespace(.{
20304 .parent = block.namespace.toOptional(),
20305 .owner_type = wip.index,
20306 .file_scope = block.getFileScopeIndex(zcu),
20307 .generation = zcu.generation,
20308 });
20309 errdefer pt.destroyNamespace(new_namespace_index);
20310 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
20311 try sema.addTypeReferenceEntry(src, .fromInterned(wip.index));
20312 return .fromIntern(wip.finish(ip, new_namespace_index));
20313 },
2099020314 }
20991 try sema.declareDependency(.{ .interned = wip_ty.index });
20992 try sema.addTypeReferenceEntry(src, wip_ty.index);
20993 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
20994 return .fromIntern(wip_ty.finish(ip, new_namespace_index));
2099520315}
2099620316
2099720317fn zirReifyUnion(
......@@ -21054,16 +20374,19 @@ fn zirReifyUnion(
2105420374 const container_layout_ty = try sema.getBuiltinType(layout_src, .@"Type.ContainerLayout");
2105520375 const single_field_attrs_ty = try sema.getBuiltinType(field_attrs_src, .@"Type.UnionField.Attributes");
2105620376
21057 const layout_uncoerced = try sema.resolveInst(extra.layout);
20377 const layout_uncoerced = sema.resolveInst(extra.layout);
2105820378 const layout_coerced = try sema.coerce(block, container_layout_ty, layout_uncoerced, layout_src);
2105920379 const layout_val = try sema.resolveConstDefinedValue(block, layout_src, layout_coerced, .{ .simple = .union_layout });
2106020380 const layout = try sema.interpretBuiltinType(block, layout_src, layout_val, std.builtin.Type.ContainerLayout);
2106120381
21062 const arg_ty_uncoerced = try sema.resolveInst(extra.arg_ty);
20382 const arg_ty_uncoerced = sema.resolveInst(extra.arg_ty);
2106320383 const arg_ty_coerced = try sema.coerce(block, .optional_type, arg_ty_uncoerced, arg_ty_src);
21064 const arg_ty_val = try sema.resolveConstDefinedValue(block, arg_ty_src, arg_ty_coerced, .{ .simple = .type });
20384 const arg_ty_val = try sema.resolveConstDefinedValue(block, arg_ty_src, arg_ty_coerced, switch (layout) {
20385 .@"packed" => .{ .simple = .packed_union_backing_int_type },
20386 .auto, .@"extern" => .{ .simple = .union_enum_tag_type },
20387 });
2106520388
21066 const field_names_uncoerced = try sema.resolveInst(extra.field_names);
20389 const field_names_uncoerced = sema.resolveInst(extra.field_names);
2106720390 const field_names_coerced = try sema.coerce(block, .slice_const_slice_const_u8, field_names_uncoerced, field_names_src);
2106820391 const field_names_slice = try sema.resolveConstDefinedValue(block, field_names_src, field_names_coerced, .{ .simple = .union_field_names });
2106920392 const field_names_arr = try sema.derefSliceAsArray(block, field_names_src, field_names_slice, .{ .simple = .union_field_names });
......@@ -21079,12 +20402,12 @@ fn zirReifyUnion(
2107920402 .child = single_field_attrs_ty.toIntern(),
2108020403 }));
2108120404
21082 const field_types_uncoerced = try sema.resolveInst(extra.field_types);
20405 const field_types_uncoerced = sema.resolveInst(extra.field_types);
2108320406 const field_types_coerced = try sema.coerce(block, field_types_ty, field_types_uncoerced, field_types_src);
2108420407 const field_types_slice = try sema.resolveConstDefinedValue(block, field_types_src, field_types_coerced, .{ .simple = .union_field_types });
2108520408 const field_types_arr = try sema.derefSliceAsArray(block, field_types_src, field_types_slice, .{ .simple = .union_field_types });
2108620409
21087 const field_attrs_uncoerced = try sema.resolveInst(extra.field_attrs);
20410 const field_attrs_uncoerced = sema.resolveInst(extra.field_attrs);
2108820411 const field_attrs_coerced = try sema.coerce(block, field_attrs_ty, field_attrs_uncoerced, field_attrs_src);
2108920412 const field_attrs_slice = try sema.resolveConstDefinedValue(block, field_attrs_src, field_attrs_coerced, .{ .simple = .union_field_attrs });
2109020413 const field_attrs_arr = try sema.derefSliceAsArray(block, field_attrs_src, field_attrs_slice, .{ .simple = .union_field_attrs });
......@@ -21101,17 +20424,29 @@ fn zirReifyUnion(
2110120424 return sema.failWithUseOfUndef(block, arg_ty_src, null);
2110220425 }
2110320426
21104 // The validation work here is non-trivial, and it's possible the type already exists.
21105 // So in this first pass, let's just construct a hash to optimize for this case. If the
21106 // inputs turn out to be invalid, we can cancel the WIP type later.
20427 // Most validation of this type happens during type resolution. We basically need to do the work
20428 // which AstGen would normally do. An exception is checking for duplicate field names, which is
20429 // handled by type resolution---it just simplifies some logic a little.
20430
20431 // As well as validation, we're going to gather some information about the fields, and construct
20432 // a hash representing the inputs for deduplication purposes.
2110720433
21108 var any_aligned_fields = false;
20434 var any_field_aligns = false;
2110920435
21110 // For deduplication purposes, we must create a hash including all details of this type.
2111120436 // TODO: use a longer hash!
2111220437 var hasher = std.hash.Wyhash.init(0);
2111320438 std.hash.autoHash(&hasher, layout);
2111420439 std.hash.autoHash(&hasher, arg_ty_val);
20440
20441 const explicit_tag_ty: ?Type, const explicit_packed_backing_type: ?Type = ty: {
20442 const arg_ty = arg_ty_val.optionalValue(zcu) orelse break :ty .{ null, null };
20443 switch (layout) {
20444 .@"extern" => return sema.fail(block, arg_ty_src, "extern union does not support enum tag type", .{}),
20445 .@"packed" => break :ty .{ null, arg_ty.toType() },
20446 .auto => break :ty .{ arg_ty.toType(), null },
20447 }
20448 };
20449
2111520450 // `field_types_arr` and `field_attrs_arr` are already deduplicated by the InternPool!
2111620451 std.hash.autoHash(&hasher, field_types_arr);
2111720452 std.hash.autoHash(&hasher, field_attrs_arr);
......@@ -21128,203 +20463,76 @@ fn zirReifyUnion(
2112820463 try field_attrs_arr.elemValue(pt, field_idx),
2112920464 std.builtin.Type.UnionField.Attributes,
2113020465 );
21131 if (field_attrs.@"align" != null) {
21132 any_aligned_fields = true;
21133 }
21134 }
21135
21136 // Some basic validation to avoid a bogus `getUnionType` call...
21137 const explicit_tag_ty: ?Type = if (arg_ty_val.optionalValue(zcu)) |arg_ty| ty: {
21138 switch (layout) {
21139 .@"extern", .@"packed" => return sema.fail(block, arg_ty_src, "{t} union does not support enum tag type", .{layout}),
21140 .auto => {},
20466 if (field_attrs.@"align") |bytes| {
20467 if (layout == .@"packed") {
20468 return sema.fail(block, field_attrs_src, "packed union fields cannot be aligned", .{});
20469 }
20470 // Trigger a compile error if the alignment is invalid.
20471 _ = try sema.validateAlign(block, field_attrs_src, bytes);
20472 any_field_aligns = true;
2114120473 }
21142 break :ty arg_ty.toType();
21143 } else null;
21144 if (any_aligned_fields and layout == .@"packed") {
21145 return sema.fail(block, field_attrs_src, "packed union fields cannot be aligned", .{});
2114620474 }
2114720475
21148 const wip_ty = switch (try ip.getUnionType(gpa, io, pt.tid, .{
21149 .flags = .{
21150 .layout = layout,
21151 .status = .none,
21152 .runtime_tag = rt: {
21153 if (explicit_tag_ty != null) break :rt .tagged;
21154 if (layout == .auto and block.wantSafeTypes()) break :rt .safety;
21155 break :rt .none;
21156 },
21157 .any_aligned_fields = any_aligned_fields,
21158 .requires_comptime = .unknown,
21159 .assumed_runtime_bits = false,
21160 .assumed_pointer_aligned = false,
21161 .alignment = .none,
21162 },
20476 switch (try ip.getReifiedUnionType(gpa, io, pt.tid, .{
20477 .zir_index = tracked_inst,
20478 .type_hash = hasher.final(),
2116320479 .fields_len = @intCast(fields_len),
21164 .enum_tag_ty = .none, // set later because not yet validated
21165 .field_types = &.{}, // set later
21166 .field_aligns = &.{}, // set later
21167 .key = .{ .reified = .{
21168 .zir_index = tracked_inst,
21169 .type_hash = hasher.final(),
21170 } },
21171 }, false)) {
21172 .wip => |wip| wip,
20480 .layout = layout,
20481 .any_field_aligns = any_field_aligns,
20482 .tag_usage = tag: {
20483 if (explicit_tag_ty != null) break :tag .tagged;
20484 if (layout == .auto and block.wantSafeTypes()) break :tag .safety;
20485 break :tag .none;
20486 },
20487 .enum_tag_type = if (explicit_tag_ty) |ty| ty.toIntern() else .none,
20488 .packed_backing_int_type = if (explicit_packed_backing_type) |ty| ty.toIntern() else .none,
20489 })) {
2117320490 .existing => |ty| {
21174 try sema.declareDependency(.{ .interned = ty });
21175 try sema.addTypeReferenceEntry(src, ty);
21176 return Air.internedToRef(ty);
20491 try sema.addTypeReferenceEntry(src, .fromInterned(ty));
20492 // No need for `ensureNamespaceUpToDate` because this type's namespace is always empty.
20493 return .fromIntern(ty);
2117720494 },
21178 };
21179 errdefer wip_ty.cancel(ip, pt.tid);
21180
21181 const type_name = try sema.createTypeName(
21182 block,
21183 name_strategy,
21184 "union",
21185 inst,
21186 wip_ty.index,
21187 );
21188 wip_ty.setName(ip, type_name.name, type_name.nav);
21189
21190 const loaded_union = ip.loadUnionType(wip_ty.index);
21191
21192 const enum_tag_ty, const has_explicit_tag = if (explicit_tag_ty) |enum_tag_ty| tag: {
21193 if (enum_tag_ty.zigTypeTag(zcu) != .@"enum") {
21194 return sema.fail(block, arg_ty_src, "tag type must be an enum type", .{});
21195 }
20495 .wip => |wip| {
20496 errdefer wip.cancel(ip, pt.tid);
20497 try sema.setTypeName(block, &wip, name_strategy, "union", inst);
2119620498
21197 const tag_ty_fields_len = enum_tag_ty.enumFieldCount(zcu);
20499 for (0..fields_len) |field_idx| {
20500 const field_name_val = try field_names_arr.elemValue(pt, field_idx);
20501 // No source location or reason; first loop checked this is valid.
20502 const field_name = try sema.sliceToIpString(block, .unneeded, field_name_val, undefined);
20503 wip.field_names.get(ip)[field_idx] = field_name;
2119820504
21199 for (0..fields_len) |field_idx| {
21200 const field_name_val = try field_names_arr.elemValue(pt, field_idx);
21201 // Don't pass a reason; first loop acts as a check that this is valid.
21202 const field_name = try sema.sliceToIpString(block, field_names_src, field_name_val, undefined);
20505 const field_ty = (try field_types_arr.elemValue(pt, field_idx)).toType();
20506 wip.field_types.get(ip)[field_idx] = field_ty.toIntern();
2120320507
21204 if (field_idx >= tag_ty_fields_len) {
21205 return sema.fail(block, field_names_src, "no field named '{f}' in enum '{f}'", .{
21206 field_name.fmt(ip), enum_tag_ty.fmt(pt),
21207 });
20508 // No source location; first loop checked this is valid.
20509 const field_attrs = try sema.interpretBuiltinType(
20510 block,
20511 .unneeded,
20512 try field_attrs_arr.elemValue(pt, field_idx),
20513 std.builtin.Type.UnionField.Attributes,
20514 );
20515 if (field_attrs.@"align") |bytes| {
20516 // No source location; first loop checked this is valid.
20517 const a = try sema.validateAlign(block, .unneeded, bytes);
20518 wip.field_aligns.get(ip)[field_idx] = a;
20519 } else if (any_field_aligns) {
20520 wip.field_aligns.get(ip)[field_idx] = .none;
20521 }
2120820522 }
2120920523
21210 const enum_field_name = enum_tag_ty.enumFieldName(field_idx, zcu);
21211 if (enum_field_name != field_name) {
21212 return sema.fail(block, field_names_src, "union field name '{f}' does not match enum field name '{f}'", .{
21213 field_name.fmt(ip), enum_field_name.fmt(ip),
21214 });
21215 }
21216 }
21217 if (tag_ty_fields_len > fields_len) return sema.failWithOwnedErrorMsg(block, msg: {
21218 const msg = try sema.errMsg(field_names_src, "{d} enum fields missing in union", .{
21219 tag_ty_fields_len - fields_len,
20524 const new_namespace_index = try pt.createNamespace(.{
20525 .parent = block.namespace.toOptional(),
20526 .owner_type = wip.index,
20527 .file_scope = block.getFileScopeIndex(zcu),
20528 .generation = zcu.generation,
2122020529 });
21221 errdefer msg.destroy(gpa);
21222 for (fields_len..tag_ty_fields_len) |enum_field_idx| {
21223 try sema.addFieldErrNote(enum_tag_ty, enum_field_idx, msg, "field '{f}' missing, declared here", .{
21224 enum_tag_ty.enumFieldName(enum_field_idx, zcu).fmt(ip),
21225 });
21226 }
21227 try sema.addDeclaredHereNote(msg, enum_tag_ty);
21228 break :msg msg;
21229 });
21230 break :tag .{ enum_tag_ty.toIntern(), true };
21231 } else tag: {
21232 // We must track field names and set up the tag type ourselves.
21233 var field_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .empty;
21234 try field_names.ensureTotalCapacity(sema.arena, fields_len);
21235
21236 for (0..fields_len) |field_idx| {
21237 const field_name_val = try field_names_arr.elemValue(pt, field_idx);
21238 // Don't pass a reason; first loop acts as a check that this is valid.
21239 const field_name = try sema.sliceToIpString(block, field_names_src, field_name_val, undefined);
21240 const gop = field_names.getOrPutAssumeCapacity(field_name);
21241 if (gop.found_existing) {
21242 // TODO: better source location
21243 return sema.fail(block, field_names_src, "duplicate union field {f}", .{field_name.fmt(ip)});
21244 }
21245 }
21246 const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), wip_ty.index, type_name.name);
21247 break :tag .{ enum_tag_ty, false };
21248 };
21249 errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error
21250
21251 for (0..fields_len) |field_idx| {
21252 const field_ty = (try field_types_arr.elemValue(pt, field_idx)).toType();
21253 const field_attrs = try sema.interpretBuiltinType(
21254 block,
21255 field_attrs_src,
21256 try field_attrs_arr.elemValue(pt, field_idx),
21257 std.builtin.Type.UnionField.Attributes,
21258 );
21259
21260 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
21261 return sema.failWithOwnedErrorMsg(block, msg: {
21262 const msg = try sema.errMsg(field_types_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{});
21263 errdefer msg.destroy(gpa);
21264 try sema.addDeclaredHereNote(msg, field_ty);
21265 break :msg msg;
21266 });
21267 }
21268
21269 switch (layout) {
21270 .auto => {},
21271 .@"extern" => if (!try sema.validateExternType(field_ty, .union_field)) {
21272 return sema.failWithOwnedErrorMsg(block, msg: {
21273 const msg = try sema.errMsg(field_types_src, "extern unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
21274 errdefer msg.destroy(gpa);
21275
21276 try sema.explainWhyTypeIsNotExtern(msg, field_types_src, field_ty, .union_field);
21277
21278 try sema.addDeclaredHereNote(msg, field_ty);
21279 break :msg msg;
21280 });
21281 },
21282 .@"packed" => if (!try sema.validatePackedType(field_ty)) {
21283 return sema.failWithOwnedErrorMsg(block, msg: {
21284 const msg = try sema.errMsg(field_types_src, "packed unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
21285 errdefer msg.destroy(gpa);
21286
21287 try sema.explainWhyTypeIsNotPacked(msg, field_types_src, field_ty);
21288
21289 try sema.addDeclaredHereNote(msg, field_ty);
21290 break :msg msg;
21291 });
21292 },
21293 }
21294
21295 loaded_union.field_types.get(ip)[field_idx] = field_ty.toIntern();
21296 if (field_attrs.@"align") |bytes| {
21297 assert(layout != .@"packed");
21298 const a = try sema.validateAlign(block, field_attrs_src, bytes);
21299 loaded_union.field_aligns.get(ip)[field_idx] = a;
21300 } else if (any_aligned_fields) {
21301 assert(layout != .@"packed");
21302 loaded_union.field_aligns.get(ip)[field_idx] = .none;
21303 }
21304 }
21305
21306 loaded_union.setTagType(ip, io, enum_tag_ty);
21307 loaded_union.setStatus(ip, io, .have_field_types);
21308
21309 const new_namespace_index = try pt.createNamespace(.{
21310 .parent = block.namespace.toOptional(),
21311 .owner_type = wip_ty.index,
21312 .file_scope = block.getFileScopeIndex(zcu),
21313 .generation = zcu.generation,
21314 });
21315
21316 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
21317 codegen_type: {
21318 if (zcu.comp.config.use_llvm) break :codegen_type;
21319 if (block.ownerModule().strip) break :codegen_type;
21320 // This job depends on any resolve_type_fully jobs queued up before it.
21321 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
21322 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
20530 errdefer pt.destroyNamespace(new_namespace_index);
20531 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
20532 try sema.addTypeReferenceEntry(src, .fromInterned(wip.index));
20533 return .fromIntern(wip.finish(ip, new_namespace_index));
20534 },
2132320535 }
21324 try sema.declareDependency(.{ .interned = wip_ty.index });
21325 try sema.addTypeReferenceEntry(src, wip_ty.index);
21326 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
21327 return .fromIntern(wip_ty.finish(ip, new_namespace_index));
2132820536}
2132920537
2133020538fn zirReifyEnum(
......@@ -21379,12 +20587,12 @@ fn zirReifyEnum(
2137920587
2138020588 const enum_mode_ty = try sema.getBuiltinType(mode_src, .@"Type.Enum.Mode");
2138120589
21382 const tag_ty = try sema.resolveType(block, tag_ty_src, extra.tag_ty);
21383 if (tag_ty.zigTypeTag(zcu) != .int) {
21384 return sema.fail(block, tag_ty_src, "tag type must be an integer type", .{});
21385 }
20590 const tag_ty_uncoerced = sema.resolveInst(extra.tag_ty);
20591 const tag_ty_coerced = try sema.coerce(block, .type, tag_ty_uncoerced, tag_ty_src);
20592 const tag_ty_val = try sema.resolveConstDefinedValue(block, tag_ty_src, tag_ty_coerced, .{ .simple = .enum_int_tag_type });
20593 const tag_ty = tag_ty_val.toType();
2138620594
21387 const mode_uncoerced = try sema.resolveInst(extra.mode);
20595 const mode_uncoerced = sema.resolveInst(extra.mode);
2138820596 const mode_coerced = try sema.coerce(block, enum_mode_ty, mode_uncoerced, mode_src);
2138920597 const mode_val = try sema.resolveConstDefinedValue(block, mode_src, mode_coerced, .{ .simple = .type });
2139020598 const nonexhaustive = switch (try sema.interpretBuiltinType(block, mode_src, mode_val, std.builtin.Type.Enum.Mode)) {
......@@ -21392,7 +20600,7 @@ fn zirReifyEnum(
2139220600 .nonexhaustive => true,
2139320601 };
2139420602
21395 const field_names_uncoerced = try sema.resolveInst(extra.field_names);
20603 const field_names_uncoerced = sema.resolveInst(extra.field_names);
2139620604 const field_names_coerced = try sema.coerce(block, .slice_const_slice_const_u8, field_names_uncoerced, field_names_src);
2139720605 const field_names_slice = try sema.resolveConstDefinedValue(block, field_names_src, field_names_coerced, .{ .simple = .enum_field_names });
2139820606 const field_names_arr = try sema.derefSliceAsArray(block, field_names_src, field_names_slice, .{ .simple = .enum_field_names });
......@@ -21404,7 +20612,7 @@ fn zirReifyEnum(
2140420612 .child = tag_ty.toIntern(),
2140520613 }));
2140620614
21407 const field_values_uncoerced = try sema.resolveInst(extra.field_values);
20615 const field_values_uncoerced = sema.resolveInst(extra.field_values);
2140820616 const field_values_coerced = try sema.coerce(block, field_values_ty, field_values_uncoerced, field_values_src);
2140920617 const field_values_slice = try sema.resolveConstDefinedValue(block, field_values_src, field_values_coerced, .{ .simple = .enum_field_values });
2141020618 const field_values_arr = try sema.derefSliceAsArray(block, field_values_src, field_values_slice, .{ .simple = .enum_field_values });
......@@ -21415,11 +20623,13 @@ fn zirReifyEnum(
2141520623 }
2141620624 // We don't need to check `field_names_arr`, because `sliceToIpString` will check that for us.
2141720625
21418 // The validation work here is non-trivial, and it's possible the type already exists.
21419 // So in this first pass, let's just construct a hash to optimize for this case. If the
21420 // inputs turn out to be invalid, we can cancel the WIP type later.
20626 // Most validation of this type happens during type resolution. We basically need to do the work
20627 // which AstGen would normally do. An exception is checking for duplicate field names, which is
20628 // handled by type resolution---it just simplifies some logic a little.
20629
20630 // As well as validation, we're going to gather some information about the fields, and construct
20631 // a hash representing the inputs for deduplication purposes.
2142120632
21422 // For deduplication purposes, we must create a hash including all details of this type.
2142320633 // TODO: use a longer hash!
2142420634 var hasher = std.hash.Wyhash.init(0);
2142520635 std.hash.autoHash(&hasher, tag_ty.toIntern());
......@@ -21435,87 +20645,46 @@ fn zirReifyEnum(
2143520645 std.hash.autoHash(&hasher, field_name);
2143620646 }
2143720647
21438 const wip_ty = switch (try ip.getEnumType(gpa, io, pt.tid, .{
21439 .has_values = true,
21440 .tag_mode = if (nonexhaustive) .nonexhaustive else .explicit,
20648 switch (try ip.getReifiedEnumType(gpa, io, pt.tid, .{
20649 .zir_index = tracked_inst,
20650 .type_hash = hasher.final(),
2144120651 .fields_len = @intCast(fields_len),
21442 .key = .{ .reified = .{
21443 .zir_index = tracked_inst,
21444 .type_hash = hasher.final(),
21445 } },
21446 }, false)) {
21447 .wip => |wip| wip,
20652 .nonexhaustive = nonexhaustive,
20653 .int_tag_type = tag_ty.toIntern(),
20654 })) {
2144820655 .existing => |ty| {
21449 try sema.declareDependency(.{ .interned = ty });
21450 try sema.addTypeReferenceEntry(src, ty);
20656 try sema.addTypeReferenceEntry(src, .fromInterned(ty));
20657 // No need for `ensureNamespaceUpToDate` because this type's namespace is always empty.
2145120658 return .fromIntern(ty);
2145220659 },
21453 };
21454 var done = false;
21455 errdefer if (!done) wip_ty.cancel(ip, pt.tid);
21456
21457 const type_name = try sema.createTypeName(
21458 block,
21459 name_strategy,
21460 "enum",
21461 inst,
21462 wip_ty.index,
21463 );
21464 wip_ty.setName(ip, type_name.name, type_name.nav);
21465
21466 const new_namespace_index = try pt.createNamespace(.{
21467 .parent = block.namespace.toOptional(),
21468 .owner_type = wip_ty.index,
21469 .file_scope = block.getFileScopeIndex(zcu),
21470 .generation = zcu.generation,
21471 });
20660 .wip => |wip| {
20661 errdefer wip.cancel(ip, pt.tid);
2147220662
21473 try sema.declareDependency(.{ .interned = wip_ty.index });
21474 try sema.addTypeReferenceEntry(src, wip_ty.index);
21475 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
21476 wip_ty.prepare(ip, new_namespace_index);
21477 wip_ty.setTagTy(ip, tag_ty.toIntern());
21478 done = true;
20663 try sema.setTypeName(block, &wip, name_strategy, "enum", inst);
2147920664
21480 for (0..fields_len) |field_idx| {
21481 const field_name_val = try field_names_arr.elemValue(pt, field_idx);
21482 // Don't pass a reason; first loop acts as a check that this is valid.
21483 const field_name = try sema.sliceToIpString(block, field_names_src, field_name_val, undefined);
20665 // Populate field names and values. Duplicate checking will be handled by type resolution.
20666 for (0..fields_len) |field_index| {
20667 const field_name_val = try field_names_arr.elemValue(pt, field_index);
20668 // No source location or reason; first loop checked this is valid.
20669 const field_name = try sema.sliceToIpString(block, .unneeded, field_name_val, undefined);
20670 wip.field_names.get(ip)[field_index] = field_name;
2148420671
21485 const field_val = try field_values_arr.elemValue(pt, field_idx);
20672 const field_val = try field_values_arr.elemValue(pt, field_index);
20673 wip.field_values.get(ip)[field_index] = field_val.toIntern();
20674 }
2148620675
21487 if (wip_ty.nextField(ip, field_name, field_val.toIntern())) |conflict| {
21488 return sema.failWithOwnedErrorMsg(block, switch (conflict.kind) {
21489 .name => msg: {
21490 const msg = try sema.errMsg(field_names_src, "duplicate enum field '{f}'", .{field_name.fmt(ip)});
21491 errdefer msg.destroy(gpa);
21492 _ = conflict.prev_field_idx; // TODO: this note is incorrect
21493 try sema.errNote(field_names_src, msg, "other field here", .{});
21494 break :msg msg;
21495 },
21496 .value => msg: {
21497 const msg = try sema.errMsg(field_values_src, "enum tag value {f} already taken", .{field_val.fmtValueSema(pt, sema)});
21498 errdefer msg.destroy(gpa);
21499 _ = conflict.prev_field_idx; // TODO: this note is incorrect
21500 try sema.errNote(field_values_src, msg, "other enum tag value here", .{});
21501 break :msg msg;
21502 },
20676 const new_namespace_index = try pt.createNamespace(.{
20677 .parent = block.namespace.toOptional(),
20678 .owner_type = wip.index,
20679 .file_scope = block.getFileScopeIndex(zcu),
20680 .generation = zcu.generation,
2150320681 });
21504 }
21505 }
21506
21507 if (nonexhaustive and fields_len > 1 and std.math.log2_int(u64, fields_len) == tag_ty.bitSize(zcu)) {
21508 return sema.fail(block, src, "non-exhaustive enum specified every value", .{});
21509 }
21510
21511 codegen_type: {
21512 if (zcu.comp.config.use_llvm) break :codegen_type;
21513 if (block.ownerModule().strip) break :codegen_type;
21514 // This job depends on any resolve_type_fully jobs queued up before it.
21515 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
21516 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
20682 errdefer pt.destroyNamespace(new_namespace_index);
20683 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
20684 try sema.addTypeReferenceEntry(src, .fromInterned(wip.index));
20685 return .fromIntern(wip.finish(ip, new_namespace_index));
20686 },
2151720687 }
21518 return Air.internedToRef(wip_ty.index);
2151920688}
2152020689
2152120690fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {
......@@ -21523,7 +20692,7 @@ fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.In
2152320692 const va_list_ty = try sema.getBuiltinType(src, .VaList);
2152420693 const va_list_ptr = try pt.singleMutPtrType(va_list_ty);
2152520694
21526 const inst = try sema.resolveInst(zir_ref);
20695 const inst = sema.resolveInst(zir_ref);
2152720696 return sema.coerce(block, va_list_ptr, inst, src);
2152820697}
2152920698
......@@ -21535,8 +20704,8 @@ fn zirCVaArg(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2153520704
2153620705 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.lhs);
2153720706 const arg_ty = try sema.resolveType(block, ty_src, extra.rhs);
21538
21539 if (!try sema.validateExternType(arg_ty, .param_ty)) {
20707 try sema.ensureLayoutResolved(arg_ty, ty_src, .parameter);
20708 if (!arg_ty.validateExtern(.param_ty, sema.pt.zcu)) {
2154020709 const msg = msg: {
2154120710 const msg = try sema.errMsg(ty_src, "cannot get '{f}' from variadic argument", .{arg_ty.fmt(sema.pt)});
2154220711 errdefer msg.destroy(sema.gpa);
......@@ -21573,7 +20742,8 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2157320742 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand);
2157420743
2157520744 try sema.requireRuntimeBlock(block, src, null);
21576 return block.addUnOp(.c_va_end, va_list_ref);
20745 _ = try block.addUnOp(.c_va_end, va_list_ref);
20746 return .void_value;
2157720747}
2157820748
2157920749fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
......@@ -21618,7 +20788,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
2161820788 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2161920789 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2162020790 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@intFromFloat");
21621 const operand = try sema.resolveInst(extra.rhs);
20791 const operand = sema.resolveInst(extra.rhs);
2162220792 const operand_ty = sema.typeOf(operand);
2162320793
2162420794 try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, operand_ty, src, operand_src);
......@@ -21630,7 +20800,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
2163020800 _ = try sema.checkIntType(block, src, dest_scalar_ty);
2163120801 try sema.checkFloatType(block, operand_src, operand_scalar_ty);
2163220802
21633 if (try sema.resolveValue(operand)) |operand_val| {
20803 if (sema.resolveValue(operand)) |operand_val| {
2163420804 const result_val = try sema.intFromFloat(block, operand_src, operand_val, operand_ty, dest_ty, .truncate);
2163520805 return Air.internedToRef(result_val.toIntern());
2163620806 } else if (dest_scalar_ty.zigTypeTag(zcu) == .comptime_int) {
......@@ -21671,7 +20841,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
2167120841 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2167220842 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2167320843 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@floatFromInt");
21674 const operand = try sema.resolveInst(extra.rhs);
20844 const operand = sema.resolveInst(extra.rhs);
2167520845 const operand_ty = sema.typeOf(operand);
2167620846
2167720847 try sema.checkVectorizableBinaryOperands(block, operand_src, dest_ty, operand_ty, src, operand_src);
......@@ -21682,9 +20852,21 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
2168220852 try sema.checkFloatType(block, src, dest_scalar_ty);
2168320853 _ = try sema.checkIntType(block, operand_src, operand_scalar_ty);
2168420854
21685 if (try sema.resolveValue(operand)) |operand_val| {
21686 const result_val = try operand_val.floatFromIntAdvanced(sema.arena, operand_ty, dest_ty, pt, .sema);
21687 return Air.internedToRef(result_val.toIntern());
20855 if (sema.resolveValue(operand)) |operand_val| {
20856 if (operand_val.isUndef(zcu)) return .fromValue(try pt.undefValue(dest_ty));
20857 if (dest_ty.zigTypeTag(zcu) != .vector) {
20858 return .fromValue(try pt.floatValue(dest_ty, operand_val.toFloat(f128, zcu)));
20859 }
20860 const dest_elems = try sema.arena.alloc(InternPool.Index, dest_ty.vectorLen(zcu));
20861 for (dest_elems, 0..) |*out_elem, elem_idx| {
20862 const orig_elem = try operand_val.elemValue(pt, elem_idx);
20863 const casted_elem = if (orig_elem.isUndef(zcu))
20864 try pt.undefValue(dest_scalar_ty)
20865 else
20866 try pt.floatValue(dest_scalar_ty, orig_elem.toFloat(f128, zcu));
20867 out_elem.* = casted_elem.toIntern();
20868 }
20869 return .fromValue(try pt.aggregateValue(dest_ty, dest_elems));
2168820870 } else if (dest_scalar_ty.zigTypeTag(zcu) == .comptime_float) {
2168920871 return sema.failWithNeededComptime(block, operand_src, .{ .simple = .casted_to_comptime_float });
2169020872 }
......@@ -21702,7 +20884,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2170220884 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2170320885
2170420886 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
21705 const operand_res = try sema.resolveInst(extra.rhs);
20887 const operand_res = sema.resolveInst(extra.rhs);
2170620888
2170720889 const uncoerced_operand_ty = sema.typeOf(operand_res);
2170820890 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu, "@ptrFromInt");
......@@ -21719,8 +20901,10 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2171920901 const ptr_ty = dest_ty.scalarType(zcu);
2172020902 try sema.checkPtrType(block, src, ptr_ty, true);
2172120903
21722 const elem_ty = ptr_ty.elemType2(zcu);
21723 const ptr_align = try ptr_ty.ptrAlignmentSema(pt);
20904 const elem_ty = ptr_ty.nullablePtrElem(zcu);
20905
20906 try sema.ensureLayoutResolved(elem_ty, src, .align_check);
20907 const ptr_align = ptr_ty.ptrAlignment(zcu);
2172420908
2172520909 if (ptr_ty.isSlice(zcu)) {
2172620910 const msg = msg: {
......@@ -21746,18 +20930,9 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2174620930 }
2174720931 return Air.internedToRef((try pt.aggregateValue(dest_ty, new_elems)).toIntern());
2174820932 }
21749 if (try ptr_ty.comptimeOnlySema(pt)) {
21750 return sema.failWithOwnedErrorMsg(block, msg: {
21751 const msg = try sema.errMsg(src, "pointer to comptime-only type '{f}' must be comptime-known, but operand is runtime-known", .{ptr_ty.fmt(pt)});
21752 errdefer msg.destroy(sema.gpa);
21753
21754 try sema.explainWhyTypeIsComptime(msg, src, ptr_ty);
21755 break :msg msg;
21756 });
21757 }
2175820933 try sema.requireRuntimeBlock(block, src, operand_src);
2175920934 try sema.checkLogicalPtrOperation(block, src, ptr_ty);
21760 if (block.wantSafety() and (try elem_ty.hasRuntimeBitsSema(pt) or elem_ty.zigTypeTag(zcu) == .@"fn")) {
20935 if (block.wantSafety()) {
2176120936 if (!ptr_ty.isAllowzeroPtr(zcu)) {
2176220937 const is_non_zero = if (is_vector) all_non_zero: {
2176320938 const zero_usize = Air.internedToRef((try sema.splat(operand_ty, .zero_usize)).toIntern());
......@@ -21804,7 +20979,7 @@ fn ptrFromIntVal(
2180420979 }
2180520980 return sema.failWithUseOfUndef(block, operand_src, vec_idx);
2180620981 }
21807 const addr = try operand_val.toUnsignedIntSema(pt);
20982 const addr = operand_val.toUnsignedInt(zcu);
2180820983 if (!ptr_ty.isAllowzeroPtr(zcu) and addr == 0)
2180920984 return sema.fail(block, operand_src, "pointer type '{f}' does not allow address zero", .{ptr_ty.fmt(pt)});
2181020985 if (addr != 0 and ptr_align != .none) {
......@@ -21836,7 +21011,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
2183621011 const src = block.nodeOffset(extra.node);
2183721012 const operand_src = block.builtinCallArgSrc(extra.node, 0);
2183821013 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_opt, "@errorCast");
21839 const operand = try sema.resolveInst(extra.rhs);
21014 const operand = sema.resolveInst(extra.rhs);
2184021015 const operand_ty = sema.typeOf(operand);
2184121016
2184221017 const dest_tag = dest_ty.zigTypeTag(zcu);
......@@ -21877,34 +21052,62 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
2187721052 else => unreachable,
2187821053 };
2187921054
21880 const disjoint = disjoint: {
21881 // Try avoiding resolving inferred error sets if we can
21882 if (!dest_err_ty.isAnyError(zcu) and dest_err_ty.errorSetIsEmpty(zcu)) break :disjoint true;
21883 if (!operand_err_ty.isAnyError(zcu) and operand_err_ty.errorSetIsEmpty(zcu)) break :disjoint true;
21884 if (dest_err_ty.isAnyError(zcu)) break :disjoint false;
21885 if (operand_err_ty.isAnyError(zcu)) break :disjoint false;
21886 const dest_err_names = dest_err_ty.errorSetNames(zcu);
21887 for (0..dest_err_names.len) |dest_err_index| {
21888 if (Type.errorSetHasFieldIp(ip, operand_err_ty.toIntern(), dest_err_names.get(ip)[dest_err_index]))
21889 break :disjoint false;
21890 }
21891
21892 if (!ip.isInferredErrorSetType(dest_err_ty.toIntern()) and
21893 !ip.isInferredErrorSetType(operand_err_ty.toIntern()))
21894 {
21895 break :disjoint true;
21896 }
21897
21898 _ = try sema.resolveInferredErrorSetTy(block, src, dest_err_ty.toIntern());
21899 _ = try sema.resolveInferredErrorSetTy(block, operand_src, operand_err_ty.toIntern());
21900 for (0..dest_err_names.len) |dest_err_index| {
21901 if (Type.errorSetHasFieldIp(ip, operand_err_ty.toIntern(), dest_err_names.get(ip)[dest_err_index]))
21902 break :disjoint false;
21903 }
21055 switch (ip.indexToKey(operand_err_ty.toIntern())) {
21056 .inferred_error_set_type => |func| try sema.ensureFuncIesResolved(block, src, func),
21057 else => {},
21058 }
2190421059
21905 break :disjoint true;
21060 const result: enum {
21061 /// The operand and destination error sets are disjoint, i.e. have no errors in common.
21062 disjoint,
21063 /// The destination error set is a superset of the operand error set, so the operation is
21064 /// effectively equivalent to a coercion.
21065 superset,
21066 /// The operand and destination error sets have *some* errors in common, but the destination
21067 /// is not a superset of the operand, so a safety check may be needed.
21068 overlap,
21069 } = if (operand_err_ty.errorSetIsEmpty(zcu)) res: {
21070 break :res .disjoint;
21071 } else check: switch (dest_err_ty.toIntern()) {
21072 .anyerror_type => .superset,
21073 .adhoc_inferred_error_set_type => {
21074 // `@errorCast` to this function's own error set.
21075 try sema.fn_ret_ty_ies.?.addErrorSet(operand_err_ty, ip, sema.arena);
21076 break :check .superset;
21077 },
21078 else => |err_set_ty| switch (ip.indexToKey(err_set_ty)) {
21079 .inferred_error_set_type => |func_index| {
21080 if (sema.fn_ret_ty_ies) |dst_ies| {
21081 if (dst_ies.func == func_index) {
21082 // `@errorCast` to this function's own error set.
21083 try sema.fn_ret_ty_ies.?.addErrorSet(operand_err_ty, ip, sema.arena);
21084 break :check .superset;
21085 }
21086 }
21087 try sema.ensureFuncIesResolved(block, src, func_index);
21088 continue :check ip.funcIesResolvedUnordered(func_index);
21089 },
21090 .error_set_type => |dest| {
21091 if (dest.names.len == 0) break :check .disjoint; // dest is 'error{}'
21092 if (operand_err_ty.isAnyError(zcu)) break :check .overlap; // anyerror -> error{...} (non-empty)
21093 var dest_has_all = true;
21094 var dest_has_any = false;
21095 for (operand_err_ty.errorSetNames(zcu).get(ip)) |operand_err_name| {
21096 if (dest.nameIndex(ip, operand_err_name) != null) {
21097 dest_has_any = true;
21098 } else {
21099 dest_has_all = false;
21100 }
21101 }
21102 if (!dest_has_any) break :check .disjoint;
21103 if (dest_has_all) break :check .superset;
21104 break :check .overlap;
21105 },
21106 else => unreachable,
21107 },
2190621108 };
21907 if (disjoint and !(operand_tag == .error_union and dest_tag == .error_union)) {
21109
21110 if (result == .disjoint and !(operand_tag == .error_union and dest_tag == .error_union)) {
2190821111 return sema.fail(block, src, "error sets '{f}' and '{f}' have no common errors", .{
2190921112 operand_err_ty.fmt(pt), dest_err_ty.fmt(pt),
2191021113 });
......@@ -21912,25 +21115,30 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
2191221115
2191321116 // operand must be defined since it can be an invalid error value
2191421117 if (try sema.resolveDefinedValue(block, operand_src, operand)) |operand_val| {
21915 const err_name: InternPool.NullTerminatedString = switch (operand_tag) {
21916 .error_set => ip.indexToKey(operand_val.toIntern()).err.name,
21917 .error_union => switch (ip.indexToKey(operand_val.toIntern()).error_union.val) {
21118 const err_name: InternPool.NullTerminatedString = switch (ip.indexToKey(operand_val.toIntern())) {
21119 .err => |err| err.name,
21120 .error_union => |eu| switch (eu.val) {
2191821121 .err_name => |name| name,
2191921122 .payload => |payload_val| {
2192021123 assert(dest_tag == .error_union); // should be guaranteed from the type checks above
21921 return sema.coerce(block, dest_ty, Air.internedToRef(payload_val), operand_src);
21124 const dest_payload_ty = dest_ty.errorUnionPayload(zcu);
21125 const coerced_payload = try sema.coerce(block, dest_payload_ty, .fromIntern(payload_val), operand_src);
21126 return sema.wrapErrorUnionPayload(block, dest_ty, coerced_payload, operand_src) catch |err| switch (err) {
21127 error.NotCoercible => unreachable,
21128 else => |e| return e,
21129 };
2192221130 },
2192321131 },
2192421132 else => unreachable,
2192521133 };
2192621134
21927 if (!dest_err_ty.isAnyError(zcu) and !Type.errorSetHasFieldIp(ip, dest_err_ty.toIntern(), err_name)) {
21135 if (result != .superset and !dest_err_ty.errorSetHasField(err_name, zcu)) {
2192821136 return sema.fail(block, src, "'error.{f}' not a member of error set '{f}'", .{
2192921137 err_name.fmt(ip), dest_err_ty.fmt(pt),
2193021138 });
2193121139 }
2193221140
21933 return Air.internedToRef(try pt.intern(switch (dest_tag) {
21141 return .fromIntern(try pt.intern(switch (dest_tag) {
2193421142 .error_set => .{ .err = .{
2193521143 .ty = dest_ty.toIntern(),
2193621144 .name = err_name,
......@@ -21944,21 +21152,17 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
2194421152 }
2194521153
2194621154 const err_int_ty = try pt.errorIntType();
21947 if (block.wantSafety() and !dest_err_ty.isAnyError(zcu) and
21948 dest_err_ty.toIntern() != .adhoc_inferred_error_set_type and
21949 zcu.backendSupportsFeature(.error_set_has_value))
21950 {
21155 if (block.wantSafety() and result != .superset and zcu.backendSupportsFeature(.error_set_has_value)) {
2195121156 const err_code_inst = switch (operand_tag) {
2195221157 .error_set => operand,
2195321158 .error_union => try block.addTyOp(.unwrap_errunion_err, operand_err_ty, operand),
2195421159 else => unreachable,
2195521160 };
2195621161 const err_int_inst = try block.addBitCast(err_int_ty, err_code_inst);
21957
2195821162 if (dest_tag == .error_union) {
2195921163 const zero_err = try pt.intRef(err_int_ty, 0);
2196021164 const is_zero = try block.addBinOp(.cmp_eq, err_int_inst, zero_err);
21961 if (disjoint) {
21165 if (result == .disjoint) {
2196221166 // Error must be zero.
2196321167 try sema.addSafetyCheck(block, src, is_zero, .invalid_error_code);
2196421168 } else {
......@@ -21987,7 +21191,7 @@ fn zirPtrCastFull(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDa
2198721191 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
2198821192 const src = block.nodeOffset(extra.node);
2198921193 const operand_src = block.src(.{ .node_offset_ptrcast_operand = extra.node });
21990 const operand = try sema.resolveInst(extra.rhs);
21194 const operand = sema.resolveInst(extra.rhs);
2199121195 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu, flags.needResultTypeBuiltinName());
2199221196 return sema.ptrCastFull(
2199321197 block,
......@@ -22006,7 +21210,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2200621210 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2200721211 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2200821212 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu, "@ptrCast");
22009 const operand = try sema.resolveInst(extra.rhs);
21213 const operand = sema.resolveInst(extra.rhs);
2201021214
2201121215 return sema.ptrCastFull(
2201221216 block,
......@@ -22043,8 +21247,8 @@ fn ptrCastFull(
2204321247 const src_info = operand_ty.ptrInfo(zcu);
2204421248 const dest_info = dest_ty.ptrInfo(zcu);
2204521249
22046 try Type.fromInterned(src_info.child).resolveLayout(pt);
22047 try Type.fromInterned(dest_info.child).resolveLayout(pt);
21250 try sema.ensureLayoutResolved(.fromInterned(src_info.child), operand_src, .align_check);
21251 try sema.ensureLayoutResolved(.fromInterned(dest_info.child), src, .align_check);
2204821252
2204921253 const DestSliceLen = union(enum) {
2205021254 undef,
......@@ -22072,16 +21276,16 @@ fn ptrCastFull(
2207221276 };
2207321277 },
2207421278 .slice => src: {
22075 const operand_val = try sema.resolveValue(operand) orelse break :src .{ .fromInterned(src_info.child), null };
21279 const operand_val = sema.resolveValue(operand) orelse break :src .{ .fromInterned(src_info.child), null };
2207621280 if (operand_val.isUndef(zcu)) break :len .undef;
2207721281 const slice_val = switch (operand_ty.zigTypeTag(zcu)) {
2207821282 .optional => operand_val.optionalValue(zcu) orelse break :len .undef,
2207921283 .pointer => operand_val,
2208021284 else => unreachable,
2208121285 };
22082 const slice_len_resolved = try sema.resolveLazyValue(.fromInterned(zcu.intern_pool.sliceLen(slice_val.toIntern())));
22083 if (slice_len_resolved.isUndef(zcu)) break :len .undef;
22084 break :src .{ .fromInterned(src_info.child), slice_len_resolved.toUnsignedInt(zcu) };
21286 const slice_len: Value = .fromInterned(zcu.intern_pool.sliceLen(slice_val.toIntern()));
21287 if (slice_len.isUndef(zcu)) break :len .undef;
21288 break :src .{ .fromInterned(src_info.child), slice_len.toUnsignedInt(zcu) };
2208521289 },
2208621290 .many, .c => {
2208721291 return sema.fail(block, src, "cannot infer length of slice from {s}", .{pointerSizeString(src_info.flags.size)});
......@@ -22369,7 +21573,7 @@ fn ptrCastFull(
2236921573
2237021574 ct: {
2237121575 if (flags.addrspace_cast) break :ct; // cannot `@addrSpaceCast` at comptime
22372 const operand_val = try sema.resolveValue(operand) orelse break :ct;
21576 const operand_val = sema.resolveValue(operand) orelse break :ct;
2237321577
2237421578 if (operand_val.isUndef(zcu)) {
2237521579 if (!dest_ty.ptrAllowsZero(zcu)) {
......@@ -22395,7 +21599,7 @@ fn ptrCastFull(
2239521599 };
2239621600
2239721601 if (dest_align.compare(.gt, src_align)) {
22398 if (try ptr_val.getUnsignedIntSema(pt)) |addr| {
21602 if (ptr_val.getUnsignedInt(zcu)) |addr| {
2239921603 const masked_addr = if (Type.fromInterned(dest_info.child).fnPtrMaskOrNull(zcu)) |mask|
2240021604 addr & mask
2240121605 else
......@@ -22464,7 +21668,7 @@ fn ptrCastFull(
2246421668 // Now, do an addrspace cast if necessary!
2246521669 if (!flags.addrspace_cast) break :ptr pre_addrspace_cast;
2246621670
22467 const intermediate_ptr_ty = try pt.ptrTypeSema(info: {
21671 const intermediate_ptr_ty = try pt.ptrType(info: {
2246821672 var info = src_info;
2246921673 info.flags.address_space = dest_info.flags.address_space;
2247021674 break :info info;
......@@ -22629,7 +21833,7 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
2262921833 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
2263021834 const src = block.nodeOffset(extra.node);
2263121835 const operand_src = block.src(.{ .node_offset_ptrcast_operand = extra.node });
22632 const operand = try sema.resolveInst(extra.operand);
21836 const operand = sema.resolveInst(extra.operand);
2263321837 const operand_ty = sema.typeOf(operand);
2263421838 try sema.checkPtrOperand(block, operand_src, operand_ty);
2263521839
......@@ -22638,14 +21842,14 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
2263821842 if (flags.volatile_cast) ptr_info.flags.is_volatile = false;
2263921843
2264021844 const dest_ty = blk: {
22641 const dest_ty = try pt.ptrTypeSema(ptr_info);
21845 const dest_ty = try pt.ptrType(ptr_info);
2264221846 if (operand_ty.zigTypeTag(zcu) == .optional) {
2264321847 break :blk try pt.optionalType(dest_ty.toIntern());
2264421848 }
2264521849 break :blk dest_ty;
2264621850 };
2264721851
22648 if (try sema.resolveValue(operand)) |operand_val| {
21852 if (sema.resolveValue(operand)) |operand_val| {
2264921853 return Air.internedToRef((try pt.getCoerced(operand_val, dest_ty)).toIntern());
2265021854 }
2265121855
......@@ -22664,7 +21868,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2266421868 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2266521869 const dest_ty = try sema.resolveDestType(block, src, extra.lhs, .remove_eu_opt, "@truncate");
2266621870 const dest_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, dest_ty, src);
22667 const operand = try sema.resolveInst(extra.rhs);
21871 const operand = sema.resolveInst(extra.rhs);
2266821872 const operand_ty = sema.typeOf(operand);
2266921873 const operand_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, operand_ty, operand_src);
2267021874
......@@ -22678,48 +21882,24 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2267821882 return sema.coerce(block, dest_ty, operand, operand_src);
2267921883 }
2268021884
22681 const dest_info = dest_scalar_ty.intInfo(zcu);
21885 if (try dest_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
2268221886
22683 if (try sema.typeHasOnePossibleValue(dest_ty)) |val| {
22684 return Air.internedToRef(val.toIntern());
22685 }
21887 const dest_info = dest_scalar_ty.intInfo(zcu);
2268621888
2268721889 if (operand_scalar_ty.zigTypeTag(zcu) != .comptime_int) {
2268821890 const operand_info = operand_ty.intInfo(zcu);
22689 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {
22690 return Air.internedToRef(val.toIntern());
22691 }
2269221891
2269321892 if (operand_info.signedness != dest_info.signedness) {
2269421893 return sema.fail(block, operand_src, "expected {s} integer type, found '{f}'", .{
2269521894 @tagName(dest_info.signedness), operand_ty.fmt(pt),
2269621895 });
2269721896 }
22698 switch (std.math.order(dest_info.bits, operand_info.bits)) {
22699 .gt => {
22700 const msg = msg: {
22701 const msg = try sema.errMsg(
22702 src,
22703 "destination type '{f}' has more bits than source type '{f}'",
22704 .{ dest_ty.fmt(pt), operand_ty.fmt(pt) },
22705 );
22706 errdefer msg.destroy(sema.gpa);
22707 try sema.errNote(src, msg, "destination type has {d} bits", .{
22708 dest_info.bits,
22709 });
22710 try sema.errNote(operand_src, msg, "operand type has {d} bits", .{
22711 operand_info.bits,
22712 });
22713 break :msg msg;
22714 };
22715 return sema.failWithOwnedErrorMsg(block, msg);
22716 },
22717 .eq => return operand,
22718 .lt => {},
21897 if (dest_info.bits >= operand_info.bits) {
21898 return sema.coerce(block, dest_ty, operand, operand_src);
2271921899 }
2272021900 }
2272121901
22722 if (try sema.resolveValueResolveLazy(operand)) |val| {
21902 if (sema.resolveValue(operand)) |val| {
2272321903 const result_val = try arith.truncate(sema, val, operand_ty, dest_ty, dest_info.signedness, dest_info.bits);
2272421904 return Air.internedToRef(result_val.toIntern());
2272521905 }
......@@ -22740,15 +21920,11 @@ fn zirBitCount(
2274021920 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
2274121921 const src = block.nodeOffset(inst_data.src_node);
2274221922 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
22743 const operand = try sema.resolveInst(inst_data.operand);
21923 const operand = sema.resolveInst(inst_data.operand);
2274421924 const operand_ty = sema.typeOf(operand);
2274521925 _ = try sema.checkIntOrVector(block, operand, operand_src);
2274621926 const bits = operand_ty.intInfo(zcu).bits;
2274721927
22748 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {
22749 return Air.internedToRef(val.toIntern());
22750 }
22751
2275221928 const result_scalar_ty = try pt.smallestUnsignedInt(bits);
2275321929 switch (operand_ty.zigTypeTag(zcu)) {
2275421930 .vector => {
......@@ -22757,7 +21933,7 @@ fn zirBitCount(
2275721933 .len = vec_len,
2275821934 .child = result_scalar_ty.toIntern(),
2275921935 });
22760 if (try sema.resolveValue(operand)) |val| {
21936 if (sema.resolveValue(operand)) |val| {
2276121937 if (val.isUndef(zcu)) return pt.undefRef(result_ty);
2276221938
2276321939 const elems = try sema.arena.alloc(InternPool.Index, vec_len);
......@@ -22774,7 +21950,7 @@ fn zirBitCount(
2277421950 }
2277521951 },
2277621952 .int => {
22777 if (try sema.resolveValueResolveLazy(operand)) |val| {
21953 if (sema.resolveValue(operand)) |val| {
2277821954 if (val.isUndef(zcu)) return pt.undefRef(result_scalar_ty);
2277921955 return pt.intRef(result_scalar_ty, comptimeOp(val, operand_ty, zcu));
2278021956 } else {
......@@ -22791,7 +21967,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2279121967 const zcu = pt.zcu;
2279221968 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
2279321969 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
22794 const operand = try sema.resolveInst(inst_data.operand);
21970 const operand = sema.resolveInst(inst_data.operand);
2279521971 const operand_ty = sema.typeOf(operand);
2279621972 const scalar_ty = try sema.checkIntOrVector(block, operand, operand_src);
2279721973 const bits = scalar_ty.intInfo(zcu).bits;
......@@ -22803,10 +21979,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2280321979 .{ scalar_ty.fmt(pt), bits },
2280421980 );
2280521981 }
22806 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {
22807 return .fromValue(val);
22808 }
22809 if (try sema.resolveValue(operand)) |operand_val| {
21982 if (sema.resolveValue(operand)) |operand_val| {
2281021983 return .fromValue(try arith.byteSwap(sema, operand_val, operand_ty));
2281121984 }
2281221985 return block.addTyOp(.byte_swap, operand_ty, operand);
......@@ -22815,14 +21988,11 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2281521988fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
2281621989 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
2281721990 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
22818 const operand = try sema.resolveInst(inst_data.operand);
21991 const operand = sema.resolveInst(inst_data.operand);
2281921992 const operand_ty = sema.typeOf(operand);
2282021993 _ = try sema.checkIntOrVector(block, operand, operand_src);
2282121994
22822 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {
22823 return .fromValue(val);
22824 }
22825 if (try sema.resolveValue(operand)) |operand_val| {
21995 if (sema.resolveValue(operand)) |operand_val| {
2282621996 return .fromValue(try arith.bitReverse(sema, operand_val, operand_ty));
2282721997 }
2282821998 return block.addTyOp(.bit_reverse, operand_ty, operand);
......@@ -22849,10 +22019,11 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
2284922019 const ty = try sema.resolveType(block, ty_src, extra.lhs);
2285022020 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.rhs, .{ .simple = .field_name });
2285122021
22022 try sema.ensureLayoutResolved(ty, ty_src, .field_queried);
22023
2285222024 const pt = sema.pt;
2285322025 const zcu = pt.zcu;
2285422026 const ip = &zcu.intern_pool;
22855 try ty.resolveLayout(pt);
2285622027 switch (ty.zigTypeTag(zcu)) {
2285722028 .@"struct" => {},
2285822029 else => return sema.fail(block, ty_src, "expected struct type, found '{f}'", .{ty.fmt(pt)}),
......@@ -23090,7 +22261,7 @@ fn checkAtomicPtrOperand(
2309022261) CompileError!Air.Inst.Ref {
2309122262 const pt = sema.pt;
2309222263 const zcu = pt.zcu;
23093 try elem_ty.resolveLayout(pt);
22264 try sema.ensureLayoutResolved(elem_ty, elem_ty_src, .ptr_access);
2309422265 var diag: Zcu.AtomicPtrAlignmentDiagnostics = .{};
2309522266 const alignment = zcu.atomicPtrAlignment(elem_ty, &diag) catch |err| switch (err) {
2309622267 error.OutOfMemory => return error.OutOfMemory,
......@@ -23126,7 +22297,7 @@ fn checkAtomicPtrOperand(
2312622297 const ptr_data = switch (ptr_ty.zigTypeTag(zcu)) {
2312722298 .pointer => ptr_ty.ptrInfo(zcu),
2312822299 else => {
23129 const wanted_ptr_ty = try pt.ptrTypeSema(wanted_ptr_data);
22300 const wanted_ptr_ty = try pt.ptrType(wanted_ptr_data);
2313022301 _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
2313122302 unreachable;
2313222303 },
......@@ -23136,7 +22307,7 @@ fn checkAtomicPtrOperand(
2313622307 wanted_ptr_data.flags.is_allowzero = ptr_data.flags.is_allowzero;
2313722308 wanted_ptr_data.flags.is_volatile = ptr_data.flags.is_volatile;
2313822309
23139 const wanted_ptr_ty = try pt.ptrTypeSema(wanted_ptr_data);
22310 const wanted_ptr_ty = try pt.ptrType(wanted_ptr_data);
2314022311 const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
2314122312
2314222313 return casted_ptr;
......@@ -23245,8 +22416,8 @@ fn checkSimdBinOp(
2324522416 .len = vec_len,
2324622417 .lhs = lhs,
2324722418 .rhs = rhs,
23248 .lhs_val = try sema.resolveValue(lhs),
23249 .rhs_val = try sema.resolveValue(rhs),
22419 .lhs_val = sema.resolveValue(lhs),
22420 .rhs_val = sema.resolveValue(rhs),
2325022421 .result_ty = result_ty,
2325122422 .scalar_ty = result_ty.scalarType(zcu),
2325222423 };
......@@ -23338,7 +22509,7 @@ fn resolveExportOptions(
2333822509 const ip = &zcu.intern_pool;
2333922510
2334022511 const export_options_ty = try sema.getBuiltinType(src, .ExportOptions);
23341 const air_ref = try sema.resolveInst(zir_ref);
22512 const air_ref = sema.resolveInst(zir_ref);
2334222513 const options = try sema.coerce(block, export_options_ty, air_ref, src);
2334322514
2334422515 const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });
......@@ -23391,7 +22562,7 @@ fn resolveBuiltinEnum(
2339122562 reason: ComptimeReason,
2339222563) CompileError!@field(std.builtin, @tagName(name)) {
2339322564 const ty = try sema.getBuiltinType(src, name);
23394 const air_ref = try sema.resolveInst(zir_ref);
22565 const air_ref = sema.resolveInst(zir_ref);
2339522566 const coerced = try sema.coerce(block, ty, air_ref, src);
2339622567 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);
2339722568 return sema.interpretBuiltinType(block, src, val, @field(std.builtin, @tagName(name)));
......@@ -23438,7 +22609,7 @@ fn zirCmpxchg(
2343822609 const success_order_src = block.builtinCallArgSrc(extra.node, 4);
2343922610 const failure_order_src = block.builtinCallArgSrc(extra.node, 5);
2344022611 // zig fmt: on
23441 const expected_value = try sema.resolveInst(extra.expected_value);
22612 const expected_value = sema.resolveInst(extra.expected_value);
2344222613 const elem_ty = sema.typeOf(expected_value);
2344322614 if (elem_ty.zigTypeTag(zcu) == .float) {
2344422615 return sema.fail(
......@@ -23448,9 +22619,9 @@ fn zirCmpxchg(
2344822619 .{elem_ty.fmt(pt)},
2344922620 );
2345022621 }
23451 const uncasted_ptr = try sema.resolveInst(extra.ptr);
22622 const uncasted_ptr = sema.resolveInst(extra.ptr);
2345222623 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false);
23453 const new_value = try sema.coerce(block, elem_ty, try sema.resolveInst(extra.new_value), new_value_src);
22624 const new_value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.new_value), new_value_src);
2345422625 const success_order = try sema.resolveAtomicOrder(block, success_order_src, extra.success_order, .{ .simple = .atomic_order });
2345522626 const failure_order = try sema.resolveAtomicOrder(block, failure_order_src, extra.failure_order, .{ .simple = .atomic_order });
2345622627
......@@ -23470,16 +22641,13 @@ fn zirCmpxchg(
2347022641 const result_ty = try pt.optionalType(elem_ty.toIntern());
2347122642
2347222643 // special case zero bit types
23473 if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) {
23474 return Air.internedToRef((try pt.intern(.{ .opt = .{
23475 .ty = result_ty.toIntern(),
23476 .val = .none,
23477 } })));
22644 if (elem_ty.classify(zcu) == .one_possible_value) {
22645 return .fromValue(try pt.nullValue(result_ty));
2347822646 }
2347922647
2348022648 const runtime_src = if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| rs: {
23481 if (try sema.resolveValue(expected_value)) |expected_val| {
23482 if (try sema.resolveValue(new_value)) |new_val| {
22649 if (sema.resolveValue(expected_value)) |expected_val| {
22650 if (sema.resolveValue(new_value)) |new_val| {
2348322651 if (expected_val.isUndef(zcu) or new_val.isUndef(zcu)) {
2348422652 // TODO: this should probably cause the memory stored at the pointer
2348522653 // to become undef as well
......@@ -23531,22 +22699,18 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
2353122699 else => return sema.fail(block, src, "expected array or vector type, found '{f}'", .{dest_ty.fmt(pt)}),
2353222700 }
2353322701
23534 const operand = try sema.resolveInst(extra.rhs);
22702 const operand = sema.resolveInst(extra.rhs);
2353522703 const scalar_ty = dest_ty.childType(zcu);
2353622704 const scalar = try sema.coerce(block, scalar_ty, operand, scalar_src);
2353722705
2353822706 const len = try sema.usizeCast(block, src, dest_ty.arrayLen(zcu));
2353922707
23540 if (try sema.typeHasOnePossibleValue(dest_ty)) |val| {
23541 return Air.internedToRef(val.toIntern());
23542 }
23543
23544 // We also need this case because `[0:s]T` is not OPV.
22708 // If the length is 0, the result is comptime-known even if the operand isn't.
2354522709 if (len == 0) return .fromValue(try pt.aggregateValue(dest_ty, &.{}));
2354622710
2354722711 const maybe_sentinel = dest_ty.sentinel(zcu);
2354822712
23549 if (try sema.resolveValue(scalar)) |scalar_val| {
22713 if (sema.resolveValue(scalar)) |scalar_val| {
2355022714 full: {
2355122715 if (dest_ty.zigTypeTag(zcu) == .vector) break :full;
2355222716 const sentinel = maybe_sentinel orelse break :full;
......@@ -23581,7 +22745,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2358122745 const op_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2358222746 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 1);
2358322747 const operation = try sema.resolveBuiltinEnum(block, op_src, extra.lhs, .ReduceOp, .{ .simple = .operand_reduce_operation });
23584 const operand = try sema.resolveInst(extra.rhs);
22748 const operand = sema.resolveInst(extra.rhs);
2358522749 const operand_ty = sema.typeOf(operand);
2358622750 const pt = sema.pt;
2358722751 const zcu = pt.zcu;
......@@ -23615,7 +22779,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2361522779 return sema.fail(block, operand_src, "@reduce operation requires a vector with nonzero length", .{});
2361622780 }
2361722781
23618 if (try sema.resolveValue(operand)) |operand_val| {
22782 if (sema.resolveValue(operand)) |operand_val| {
2361922783 if (operand_val.isUndef(zcu)) return pt.undefRef(scalar_ty);
2362022784
2362122785 var accum: Value = try operand_val.elemValue(pt, 0);
......@@ -23651,9 +22815,9 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2365122815
2365222816 const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type);
2365322817 try sema.checkVectorElemType(block, elem_ty_src, elem_ty);
23654 const a = try sema.resolveInst(extra.a);
23655 const b = try sema.resolveInst(extra.b);
23656 var mask = try sema.resolveInst(extra.mask);
22818 const a = sema.resolveInst(extra.a);
22819 const b = sema.resolveInst(extra.b);
22820 var mask = sema.resolveInst(extra.mask);
2365722821 var mask_ty = sema.typeOf(mask);
2365822822
2365922823 const mask_len = switch (sema.typeOf(mask).zigTypeTag(zcu)) {
......@@ -23733,7 +22897,7 @@ fn analyzeShuffle(
2373322897 continue;
2373422898 }
2373522899 // Safe because mask elements are `i32` and we already checked for undef:
23736 const raw = (try sema.resolveLazyValue(mask_val)).toSignedInt(zcu);
22900 const raw = mask_val.toSignedInt(zcu);
2373722901 if (raw >= 0) {
2373822902 const idx: u32 = @intCast(raw);
2373922903 a_used = true;
......@@ -23760,8 +22924,8 @@ fn analyzeShuffle(
2376022924 }
2376122925 }
2376222926
23763 const maybe_a_val = try sema.resolveValue(a_coerced);
23764 const maybe_b_val = try sema.resolveValue(b_coerced);
22927 const maybe_a_val = sema.resolveValue(a_coerced);
22928 const maybe_b_val = sema.resolveValue(b_coerced);
2376522929
2376622930 const a_rt = a_used and maybe_a_val == null;
2376722931 const b_rt = b_used and maybe_b_val == null;
......@@ -23849,7 +23013,7 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2384923013
2385023014 const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type);
2385123015 try sema.checkVectorElemType(block, elem_ty_src, elem_ty);
23852 const pred_uncoerced = try sema.resolveInst(extra.pred);
23016 const pred_uncoerced = sema.resolveInst(extra.pred);
2385323017 const pred_ty = sema.typeOf(pred_uncoerced);
2385423018
2385523019 const vec_len_u64 = switch (pred_ty.zigTypeTag(zcu)) {
......@@ -23868,12 +23032,12 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
2386823032 .len = vec_len,
2386923033 .child = elem_ty.toIntern(),
2387023034 });
23871 const a = try sema.coerce(block, vec_ty, try sema.resolveInst(extra.a), a_src);
23872 const b = try sema.coerce(block, vec_ty, try sema.resolveInst(extra.b), b_src);
23035 const a = try sema.coerce(block, vec_ty, sema.resolveInst(extra.a), a_src);
23036 const b = try sema.coerce(block, vec_ty, sema.resolveInst(extra.b), b_src);
2387323037
23874 const maybe_pred = try sema.resolveValue(pred);
23875 const maybe_a = try sema.resolveValue(a);
23876 const maybe_b = try sema.resolveValue(b);
23038 const maybe_pred = sema.resolveValue(pred);
23039 const maybe_a = sema.resolveValue(a);
23040 const maybe_b = sema.resolveValue(b);
2387723041
2387823042 const runtime_src = if (maybe_pred) |pred_val| rs: {
2387923043 if (pred_val.isUndef(zcu)) return pt.undefRef(vec_ty);
......@@ -23934,10 +23098,12 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2393423098 const order_src = block.builtinCallArgSrc(inst_data.src_node, 2);
2393523099 // zig fmt: on
2393623100 const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type);
23937 const uncasted_ptr = try sema.resolveInst(extra.ptr);
23101 const uncasted_ptr = sema.resolveInst(extra.ptr);
2393823102 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, true);
2393923103 const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering, .{ .simple = .atomic_order });
2394023104
23105 try sema.ensureLayoutResolved(elem_ty, elem_ty_src, .ptr_access);
23106
2394123107 switch (order) {
2394223108 .release, .acq_rel => {
2394323109 return sema.fail(
......@@ -23950,9 +23116,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2395023116 else => {},
2395123117 }
2395223118
23953 if (try sema.typeHasOnePossibleValue(elem_ty)) |val| {
23954 return Air.internedToRef(val.toIntern());
23955 }
23119 if (try elem_ty.onePossibleValue(sema.pt)) |opv| return .fromValue(opv);
2395623120
2395723121 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {
2395823122 if (try sema.pointerDeref(block, ptr_src, ptr_val, sema.typeOf(ptr))) |elem_val| {
......@@ -23983,9 +23147,9 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2398323147 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 3);
2398423148 const order_src = block.builtinCallArgSrc(inst_data.src_node, 4);
2398523149 // zig fmt: on
23986 const operand = try sema.resolveInst(extra.operand);
23150 const operand = sema.resolveInst(extra.operand);
2398723151 const elem_ty = sema.typeOf(operand);
23988 const uncasted_ptr = try sema.resolveInst(extra.ptr);
23152 const uncasted_ptr = sema.resolveInst(extra.ptr);
2398923153 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false);
2399023154 const op = try sema.resolveAtomicRmwOp(block, op_src, extra.operation);
2399123155
......@@ -24009,12 +23173,10 @@ fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2400923173 }
2401023174
2401123175 // special case zero bit types
24012 if (try sema.typeHasOnePossibleValue(elem_ty)) |val| {
24013 return Air.internedToRef(val.toIntern());
24014 }
23176 if (try elem_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
2401523177
2401623178 const runtime_src = if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| rs: {
24017 const maybe_operand_val = try sema.resolveValue(operand);
23179 const maybe_operand_val = sema.resolveValue(operand);
2401823180 const operand_val = maybe_operand_val orelse {
2401923181 try sema.checkPtrIsNotComptimeMutable(block, ptr_val, ptr_src, operand_src);
2402023182 break :rs operand_src;
......@@ -24065,9 +23227,9 @@ fn zirAtomicStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2406523227 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 2);
2406623228 const order_src = block.builtinCallArgSrc(inst_data.src_node, 3);
2406723229 // zig fmt: on
24068 const operand = try sema.resolveInst(extra.operand);
23230 const operand = sema.resolveInst(extra.operand);
2406923231 const elem_ty = sema.typeOf(operand);
24070 const uncasted_ptr = try sema.resolveInst(extra.ptr);
23232 const uncasted_ptr = sema.resolveInst(extra.ptr);
2407123233 const ptr = try sema.checkAtomicPtrOperand(block, elem_ty, elem_ty_src, uncasted_ptr, ptr_src, false);
2407223234 const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering, .{ .simple = .atomic_order });
2407323235
......@@ -24098,14 +23260,14 @@ fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
2409823260 const mulend2_src = block.builtinCallArgSrc(inst_data.src_node, 2);
2409923261 const addend_src = block.builtinCallArgSrc(inst_data.src_node, 3);
2410023262
24101 const addend = try sema.resolveInst(extra.addend);
23263 const addend = sema.resolveInst(extra.addend);
2410223264 const ty = sema.typeOf(addend);
24103 const mulend1 = try sema.coerce(block, ty, try sema.resolveInst(extra.mulend1), mulend1_src);
24104 const mulend2 = try sema.coerce(block, ty, try sema.resolveInst(extra.mulend2), mulend2_src);
23265 const mulend1 = try sema.coerce(block, ty, sema.resolveInst(extra.mulend1), mulend1_src);
23266 const mulend2 = try sema.coerce(block, ty, sema.resolveInst(extra.mulend2), mulend2_src);
2410523267
24106 const maybe_mulend1 = try sema.resolveValue(mulend1);
24107 const maybe_mulend2 = try sema.resolveValue(mulend2);
24108 const maybe_addend = try sema.resolveValue(addend);
23268 const maybe_mulend1 = sema.resolveValue(mulend1);
23269 const maybe_mulend2 = sema.resolveValue(mulend2);
23270 const maybe_addend = sema.resolveValue(addend);
2410923271 const pt = sema.pt;
2411023272 const zcu = pt.zcu;
2411123273
......@@ -24167,10 +23329,10 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2416723329 const call_src = block.nodeOffset(inst_data.src_node);
2416823330
2416923331 const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;
24170 const func = try sema.resolveInst(extra.callee);
23332 const func = sema.resolveInst(extra.callee);
2417123333
2417223334 const modifier_ty = try sema.getBuiltinType(call_src, .CallModifier);
24173 const air_ref = try sema.resolveInst(extra.modifier);
23335 const air_ref = sema.resolveInst(extra.modifier);
2417423336 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);
2417523337 const modifier_val = try sema.resolveConstDefinedValue(block, modifier_src, modifier_ref, .{ .simple = .call_modifier });
2417623338 var modifier = try sema.interpretBuiltinType(block, modifier_src, modifier_val, std.builtin.CallModifier);
......@@ -24208,7 +23370,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2420823370 },
2420923371 }
2421023372
24211 const args = try sema.resolveInst(extra.args);
23373 const args = sema.resolveInst(extra.args);
2421223374
2421323375 const args_ty = sema.typeOf(args);
2421423376 if (!args_ty.isTuple(zcu)) {
......@@ -24253,18 +23415,23 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
2425323415 const field_name_src = block.builtinCallArgSrc(extra.src_node, 0);
2425423416 const field_ptr_src = block.builtinCallArgSrc(extra.src_node, 1);
2425523417
24256 const parent_ptr_ty = try sema.resolveDestType(block, inst_src, extra.parent_ptr_type, .remove_eu, "@fieldParentPtr");
24257 try sema.checkPtrType(block, inst_src, parent_ptr_ty, true);
23418 const maybe_opt_parent_ptr_ty = try sema.resolveDestType(block, inst_src, extra.parent_ptr_type, .remove_eu, "@fieldParentPtr");
23419 try sema.checkPtrType(block, inst_src, maybe_opt_parent_ptr_ty, true);
23420 const parent_ptr_ty = switch (maybe_opt_parent_ptr_ty.zigTypeTag(zcu)) {
23421 .optional => maybe_opt_parent_ptr_ty.optionalChild(zcu),
23422 .pointer => maybe_opt_parent_ptr_ty,
23423 else => unreachable,
23424 };
2425823425 const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu);
2425923426 if (parent_ptr_info.flags.size != .one) {
2426023427 return sema.fail(block, inst_src, "expected single pointer type, found '{f}'", .{parent_ptr_ty.fmt(pt)});
2426123428 }
2426223429 const parent_ty: Type = .fromInterned(parent_ptr_info.child);
23430 try sema.ensureLayoutResolved(parent_ty, inst_src, .field_used);
2426323431 switch (parent_ty.zigTypeTag(zcu)) {
2426423432 .@"struct", .@"union" => {},
2426523433 else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{f}'", .{parent_ptr_ty.fmt(pt)}),
2426623434 }
24267 try parent_ty.resolveLayout(pt);
2426823435
2426923436 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{ .simple = .field_name });
2427023437 const field_index = switch (parent_ty.zigTypeTag(zcu)) {
......@@ -24285,144 +23452,77 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
2428523452 return sema.fail(block, field_name_src, "cannot get @fieldParentPtr of a comptime field", .{});
2428623453 }
2428723454
24288 const field_ptr = try sema.resolveInst(extra.field_ptr);
23455 const field_ptr = sema.resolveInst(extra.field_ptr);
2428923456 const field_ptr_ty = sema.typeOf(field_ptr);
2429023457 try sema.checkPtrOperand(block, field_ptr_src, field_ptr_ty);
24291 const field_ptr_info = field_ptr_ty.ptrInfo(zcu);
24292
24293 var actual_parent_ptr_info: InternPool.Key.PtrType = .{
24294 .child = parent_ty.toIntern(),
24295 .flags = .{
24296 .alignment = try parent_ptr_ty.ptrAlignmentSema(pt),
24297 .is_const = field_ptr_info.flags.is_const,
24298 .is_volatile = field_ptr_info.flags.is_volatile,
24299 .is_allowzero = field_ptr_info.flags.is_allowzero,
24300 .address_space = field_ptr_info.flags.address_space,
24301 },
24302 .packed_offset = parent_ptr_info.packed_offset,
24303 };
24304 const field_ty = parent_ty.fieldType(field_index, zcu);
24305 var actual_field_ptr_info: InternPool.Key.PtrType = .{
24306 .child = field_ty.toIntern(),
24307 .flags = .{
24308 .alignment = try field_ptr_ty.ptrAlignmentSema(pt),
24309 .is_const = field_ptr_info.flags.is_const,
24310 .is_volatile = field_ptr_info.flags.is_volatile,
24311 .is_allowzero = field_ptr_info.flags.is_allowzero,
24312 .address_space = field_ptr_info.flags.address_space,
24313 },
24314 .packed_offset = field_ptr_info.packed_offset,
24315 };
24316 switch (parent_ty.containerLayout(zcu)) {
24317 .auto => {
24318 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(
24319 if (zcu.typeToStruct(parent_ty)) |struct_obj|
24320 try field_ty.structFieldAlignmentSema(
24321 struct_obj.fieldAlign(ip, field_index),
24322 struct_obj.layout,
24323 pt,
24324 )
24325 else if (zcu.typeToUnion(parent_ty)) |union_obj|
24326 try field_ty.unionFieldAlignmentSema(
24327 union_obj.fieldAlign(ip, field_index),
24328 union_obj.flagsUnordered(ip).layout,
24329 pt,
24330 )
24331 else
24332 actual_field_ptr_info.flags.alignment,
24333 );
24334
24335 actual_parent_ptr_info.packed_offset = .{ .bit_offset = 0, .host_size = 0 };
24336 actual_field_ptr_info.packed_offset = .{ .bit_offset = 0, .host_size = 0 };
24337 },
24338 .@"extern" => {
24339 const field_offset = parent_ty.structFieldOffset(field_index, zcu);
24340 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(if (field_offset > 0)
24341 Alignment.fromLog2Units(@ctz(field_offset))
24342 else
24343 actual_field_ptr_info.flags.alignment);
2434423458
24345 actual_parent_ptr_info.packed_offset = .{ .bit_offset = 0, .host_size = 0 };
24346 actual_field_ptr_info.packed_offset = .{ .bit_offset = 0, .host_size = 0 };
24347 },
24348 .@"packed" => {
24349 const byte_offset = std.math.divExact(u32, @abs(@as(i32, actual_parent_ptr_info.packed_offset.bit_offset) +
24350 (if (zcu.typeToStruct(parent_ty)) |struct_obj| zcu.structPackedFieldBitOffset(struct_obj, field_index) else 0) -
24351 actual_field_ptr_info.packed_offset.bit_offset), 8) catch
24352 return sema.fail(block, inst_src, "pointer bit-offset mismatch", .{});
24353 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(if (byte_offset > 0)
24354 Alignment.fromLog2Units(@ctz(byte_offset))
24355 else
24356 actual_field_ptr_info.flags.alignment);
24357 },
24358 }
23459 const hypothetical_field_ptr_ty = try parent_ptr_ty.fieldPtrType(field_index, pt);
23460 const casted_field_ptr = try sema.ptrCastFull(
23461 block,
23462 flags,
23463 inst_src,
23464 field_ptr,
23465 field_ptr_src,
23466 hypothetical_field_ptr_ty,
23467 "@fieldParentPtr",
23468 );
2435923469
24360 const actual_field_ptr_ty = try pt.ptrTypeSema(actual_field_ptr_info);
24361 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, field_ptr_src);
24362 const actual_parent_ptr_ty = try pt.ptrTypeSema(actual_parent_ptr_info);
23470 const unaligned_parent_ptr_ty = try pt.ptrType(info: {
23471 var info = parent_ptr_info;
23472 info.flags.alignment = hypothetical_field_ptr_ty.ptrAlignment(zcu);
23473 break :info info;
23474 });
2436323475
24364 const result = if (try sema.resolveDefinedValue(block, field_ptr_src, casted_field_ptr)) |field_ptr_val| result: {
24365 switch (parent_ty.zigTypeTag(zcu)) {
24366 .@"struct" => switch (parent_ty.containerLayout(zcu)) {
24367 .auto => {},
24368 .@"extern" => {
24369 const byte_offset = parent_ty.structFieldOffset(field_index, zcu);
24370 const parent_ptr_val = try sema.ptrSubtract(block, field_ptr_src, field_ptr_val, byte_offset, actual_parent_ptr_ty);
24371 break :result Air.internedToRef(parent_ptr_val.toIntern());
24372 },
24373 .@"packed" => {
24374 // Logic lifted from type computation above - I'm just assuming it's correct.
24375 // `catch unreachable` since error case handled above.
24376 const byte_offset = std.math.divExact(u32, @abs(@as(i32, actual_parent_ptr_info.packed_offset.bit_offset) +
24377 zcu.structPackedFieldBitOffset(zcu.typeToStruct(parent_ty).?, field_index) -
24378 actual_field_ptr_info.packed_offset.bit_offset), 8) catch unreachable;
24379 const parent_ptr_val = try sema.ptrSubtract(block, field_ptr_src, field_ptr_val, byte_offset, actual_parent_ptr_ty);
24380 break :result Air.internedToRef(parent_ptr_val.toIntern());
24381 },
24382 },
24383 .@"union" => switch (parent_ty.containerLayout(zcu)) {
24384 .auto => {},
24385 .@"extern", .@"packed" => {
24386 // For an extern or packed union, just coerce the pointer.
24387 const parent_ptr_val = try pt.getCoerced(field_ptr_val, actual_parent_ptr_ty);
24388 break :result Air.internedToRef(parent_ptr_val.toIntern());
24389 },
24390 },
23476 const unaligned_parent_ptr: Air.Inst.Ref = if (try sema.resolveDefinedValue(
23477 block,
23478 field_ptr_src,
23479 casted_field_ptr,
23480 )) |field_ptr_val| switch (parent_ty.containerLayout(zcu)) {
23481 .@"packed" => .fromValue(try pt.getCoerced(field_ptr_val, unaligned_parent_ptr_ty)),
23482 .@"extern" => switch (parent_ty.zigTypeTag(zcu)) {
23483 .@"struct" => .fromValue(try sema.ptrSubtract(
23484 block,
23485 field_ptr_src,
23486 field_ptr_val,
23487 parent_ty.structFieldOffset(field_index, zcu),
23488 unaligned_parent_ptr_ty,
23489 )),
23490 .@"union" => .fromValue(try pt.getCoerced(field_ptr_val, unaligned_parent_ptr_ty)),
2439123491 else => unreachable,
24392 }
24393
24394 const opt_field: ?InternPool.Key.Ptr.BaseAddr.BaseIndex = opt_field: {
24395 const ptr = switch (ip.indexToKey(field_ptr_val.toIntern())) {
24396 .ptr => |ptr| ptr,
24397 else => break :opt_field null,
24398 };
24399 if (ptr.byte_offset != 0) break :opt_field null;
24400 break :opt_field switch (ptr.base_addr) {
24401 .field => |field| field,
24402 else => null,
23492 },
23493 .auto => result: {
23494 const opt_field: ?InternPool.Key.Ptr.BaseAddr.BaseIndex = opt_field: {
23495 const ptr = switch (ip.indexToKey(field_ptr_val.toIntern())) {
23496 .ptr => |ptr| ptr,
23497 else => break :opt_field null,
23498 };
23499 if (ptr.byte_offset != 0) break :opt_field null;
23500 break :opt_field switch (ptr.base_addr) {
23501 .field => |field| field,
23502 else => null,
23503 };
2440323504 };
24404 };
2440523505
24406 const field = opt_field orelse {
24407 return sema.fail(block, field_ptr_src, "pointer value not based on parent struct", .{});
24408 };
23506 const field = opt_field orelse {
23507 return sema.fail(block, field_ptr_src, "pointer value not based on parent struct", .{});
23508 };
2440923509
24410 if (Value.fromInterned(field.base).typeOf(zcu).childType(zcu).toIntern() != parent_ty.toIntern()) {
24411 return sema.fail(block, field_ptr_src, "pointer value not based on parent struct", .{});
24412 }
23510 if (Value.fromInterned(field.base).typeOf(zcu).childType(zcu).toIntern() != parent_ty.toIntern()) {
23511 return sema.fail(block, field_ptr_src, "pointer value not based on parent struct", .{});
23512 }
2441323513
24414 if (field.index != field_index) {
24415 return sema.fail(block, inst_src, "field '{f}' has index '{d}' but pointer value is index '{d}' of struct '{f}'", .{
24416 field_name.fmt(ip), field_index, field.index, parent_ty.fmt(pt),
24417 });
24418 }
24419 break :result try sema.coerce(block, actual_parent_ptr_ty, Air.internedToRef(field.base), inst_src);
23514 if (field.index != field_index) {
23515 return sema.fail(block, inst_src, "field '{f}' has index '{d}' but pointer value is index '{d}' of struct '{f}'", .{
23516 field_name.fmt(ip), field_index, field.index, parent_ty.fmt(pt),
23517 });
23518 }
23519 break :result .fromValue(try pt.getCoerced(.fromInterned(field.base), unaligned_parent_ptr_ty));
23520 },
2442023521 } else result: {
24421 try sema.requireRuntimeBlock(block, inst_src, field_ptr_src);
2442223522 break :result try block.addInst(.{
2442323523 .tag = .field_parent_ptr,
2442423524 .data = .{ .ty_pl = .{
24425 .ty = Air.internedToRef(actual_parent_ptr_ty.toIntern()),
23525 .ty = .fromType(unaligned_parent_ptr_ty),
2442623526 .payload = try block.sema.addExtra(Air.FieldParentPtr{
2442723527 .field_ptr = casted_field_ptr,
2442823528 .field_index = @intCast(field_index),
......@@ -24430,14 +23530,61 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
2443023530 } },
2443123531 });
2443223532 };
24433 return sema.ptrCastFull(block, flags, inst_src, result, inst_src, parent_ptr_ty, "@fieldParentPtr");
23533
23534 // There's one more error condition: if the hypothetical field pointer type has a lower
23535 // alignment than the parent pointer type, then we need an `@alignCast`. Note that the earlier
23536 // `ptrCastFull` may *also* have "used" the `@alignCast`; that would be a case where the field
23537 // is naturally less aligned than the rest of the struct, *and* the field pointer is itself
23538 // underaligned compared to the field alignment. For example, `struct { a: u32, b: u16 }` with
23539 // a field pointer of type `*align(1) u16`.
23540 switch (hypothetical_field_ptr_ty.ptrAlignment(zcu).order(parent_ptr_ty.ptrAlignment(zcu))) {
23541 .gt => unreachable, // getting a field pointer can never increase alignment
23542 .eq => return sema.coerce(block, maybe_opt_parent_ptr_ty, unaligned_parent_ptr, inst_src),
23543 .lt => if (flags.align_cast) {
23544 // Go through `ptrCastFull` for the safety check.
23545 return sema.ptrCastFull(
23546 block,
23547 flags,
23548 inst_src,
23549 unaligned_parent_ptr,
23550 inst_src,
23551 maybe_opt_parent_ptr_ty,
23552 "@fieldParentPtr",
23553 );
23554 } else return sema.failWithOwnedErrorMsg(block, msg: {
23555 const msg = try sema.errMsg(inst_src, "@fieldParentPtr increases pointer alignment", .{});
23556 errdefer msg.destroy(sema.gpa);
23557 try sema.errNote(inst_src, msg, "parent pointer type '{f}' has alignment '{d}'", .{
23558 parent_ptr_ty.fmt(pt),
23559 parent_ptr_ty.abiAlignment(zcu),
23560 });
23561 if (parent_ty.isTuple(zcu)) {
23562 try sema.errNote(field_ptr_src, msg, "tuple field '{d}' limits alignment to '{d}'", .{
23563 field_index,
23564 field_ptr_ty.ptrAlignment(zcu),
23565 });
23566 } else {
23567 try sema.errNote(parent_ty.srcLoc(zcu), msg, "{t} field '{f}' limits alignment to '{d}'", .{
23568 parent_ty.zigTypeTag(zcu),
23569 switch (parent_ty.zigTypeTag(zcu)) {
23570 .@"struct" => parent_ty.structFieldName(field_index, zcu).unwrap().?.fmt(ip),
23571 .@"union" => parent_ty.unionTagTypeHypothetical(zcu).enumFieldName(field_index, zcu).fmt(ip),
23572 else => unreachable,
23573 },
23574 field_ptr_ty.ptrAlignment(zcu),
23575 });
23576 }
23577 try sema.errNote(inst_src, msg, "use @alignCast to assert pointer alignment", .{});
23578 break :msg msg;
23579 }),
23580 }
2443423581}
2443523582
2443623583fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte_subtract: u64, new_ty: Type) !Value {
2443723584 const pt = sema.pt;
2443823585 const zcu = pt.zcu;
2443923586 if (byte_subtract == 0) return pt.getCoerced(ptr_val, new_ty);
24440 var ptr = switch (zcu.intern_pool.indexToKey(ptr_val.toIntern())) {
23587 const ptr = switch (zcu.intern_pool.indexToKey(ptr_val.toIntern())) {
2444123588 .undef => return sema.failWithUseOfUndef(block, src, null),
2444223589 .ptr => |ptr| ptr,
2444323590 else => unreachable,
......@@ -24450,9 +23597,11 @@ fn ptrSubtract(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, byte
2445023597 break :msg msg;
2445123598 });
2445223599 }
24453 ptr.byte_offset -= byte_subtract;
24454 ptr.ty = new_ty.toIntern();
24455 return Value.fromInterned(try pt.intern(.{ .ptr = ptr }));
23600 return Value.fromInterned(try pt.intern(.{ .ptr = .{
23601 .ty = new_ty.toIntern(),
23602 .base_addr = ptr.base_addr,
23603 .byte_offset = ptr.byte_offset - byte_subtract,
23604 } }));
2445623605}
2445723606
2445823607fn zirMinMax(
......@@ -24466,8 +23615,8 @@ fn zirMinMax(
2446623615 const src = block.nodeOffset(inst_data.src_node);
2446723616 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2446823617 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);
24469 const lhs = try sema.resolveInst(extra.lhs);
24470 const rhs = try sema.resolveInst(extra.rhs);
23618 const lhs = sema.resolveInst(extra.lhs);
23619 const rhs = sema.resolveInst(extra.rhs);
2447123620 return sema.analyzeMinMax(block, src, air_tag, &.{ lhs, rhs }, &.{ lhs_src, rhs_src });
2447223621}
2447323622
......@@ -24487,7 +23636,7 @@ fn zirMinMaxMulti(
2448723636
2448823637 for (operands, air_refs, operand_srcs, 0..) |zir_ref, *air_ref, *op_src, i| {
2448923638 op_src.* = block.builtinCallArgSrc(src_node, @intCast(i));
24490 air_ref.* = try sema.resolveInst(zir_ref);
23639 air_ref.* = sema.resolveInst(zir_ref);
2449123640 }
2449223641
2449323642 return sema.analyzeMinMax(block, src, air_tag, air_refs, operand_srcs);
......@@ -24590,7 +23739,7 @@ fn analyzeMinMax(
2459023739 const operand_scalar_ty = sema.typeOf(operand).scalarType(zcu);
2459123740 const want_strat: TypeStrat = switch (operand_scalar_ty.zigTypeTag(zcu)) {
2459223741 .comptime_int => s: {
24593 const val = (try sema.resolveValueResolveLazy(operand)).?;
23742 const val = sema.resolveValue(operand).?;
2459423743 if (val.isUndef(zcu)) break :s .none;
2459523744 break :s .{ .int = .{
2459623745 .all_comptime_int = true,
......@@ -24609,7 +23758,7 @@ fn analyzeMinMax(
2460923758 // (replaced with just the simple calls to `Type.minInt`/`Type.maxInt`) so that we only
2461023759 // use the input *types* to determine the result type.
2461123760 const min: Value, const max: Value = bounds: {
24612 if (try sema.resolveValueResolveLazy(operand)) |operand_val| {
23761 if (sema.resolveValue(operand)) |operand_val| {
2461323762 if (vector_len) |len| {
2461423763 var min = try operand_val.elemValue(pt, 0);
2461523764 var max = min;
......@@ -24696,6 +23845,9 @@ fn analyzeMinMax(
2469623845 .child = intermediate_scalar_ty.toIntern(),
2469723846 }) else intermediate_scalar_ty;
2469823847
23848 // We might have refined all the way down to an OPV type---check now.
23849 if (try result_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
23850
2469923851 // This value, if not `null`, will have type `intermediate_ty`.
2470023852 const comptime_part: ?Value = ct: {
2470123853 // Contains the comptime-known scalar result values.
......@@ -24712,7 +23864,7 @@ fn analyzeMinMax(
2471223864 var opt_runtime_src: ?LazySrcLoc = null;
2471323865
2471423866 for (operands, operand_srcs) |operand, operand_src| {
24715 const operand_val = try sema.resolveValueResolveLazy(operand) orelse {
23867 const operand_val = sema.resolveValue(operand) orelse {
2471623868 if (opt_runtime_src == null) opt_runtime_src = operand_src;
2471723869 continue;
2471823870 };
......@@ -24819,7 +23971,7 @@ fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !A
2481923971 // Already an array pointer.
2482023972 return ptr;
2482123973 }
24822 const new_ty = try pt.ptrTypeSema(.{
23974 const new_ty = try pt.ptrType(.{
2482323975 .child = (try pt.arrayType(.{
2482423976 .len = len,
2482523977 .sentinel = info.sentinel,
......@@ -24852,8 +24004,8 @@ fn zirMemcpy(
2485224004 const src = block.nodeOffset(inst_data.src_node);
2485324005 const dest_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2485424006 const src_src = block.builtinCallArgSrc(inst_data.src_node, 1);
24855 const dest_ptr = try sema.resolveInst(extra.lhs);
24856 const src_ptr = try sema.resolveInst(extra.rhs);
24007 const dest_ptr = sema.resolveInst(extra.lhs);
24008 const src_ptr = sema.resolveInst(extra.rhs);
2485724009 const dest_ty = sema.typeOf(dest_ptr);
2485824010 const src_ty = sema.typeOf(src_ptr);
2485924011 const dest_len = try indexablePtrLenOrNone(sema, block, dest_src, dest_ptr);
......@@ -24880,8 +24032,11 @@ fn zirMemcpy(
2488024032 return sema.failWithOwnedErrorMsg(block, msg);
2488124033 }
2488224034
24883 const dest_elem_ty = dest_ty.indexablePtrElem(zcu);
24884 const src_elem_ty = src_ty.indexablePtrElem(zcu);
24035 const dest_elem_ty = dest_ty.indexableElem(zcu);
24036 const src_elem_ty = src_ty.indexableElem(zcu);
24037
24038 try sema.ensureLayoutResolved(dest_elem_ty, dest_src, .ptr_access);
24039 try sema.ensureLayoutResolved(src_elem_ty, src_src, .ptr_access);
2488524040
2488624041 const imc = try sema.coerceInMemoryAllowed(
2488724042 block,
......@@ -24946,13 +24101,13 @@ fn zirMemcpy(
2494624101 }
2494724102
2494824103 zero_bit: {
24949 const src_comptime = try src_elem_ty.comptimeOnlySema(pt);
24950 const dest_comptime = try dest_elem_ty.comptimeOnlySema(pt);
24104 const src_comptime = src_elem_ty.comptimeOnly(zcu);
24105 const dest_comptime = dest_elem_ty.comptimeOnly(zcu);
2495124106 assert(src_comptime == dest_comptime); // IMC
2495224107 if (src_comptime) break :zero_bit;
2495324108
24954 const src_has_bits = try src_elem_ty.hasRuntimeBitsIgnoreComptimeSema(pt);
24955 const dest_has_bits = try dest_elem_ty.hasRuntimeBitsIgnoreComptimeSema(pt);
24109 const src_has_bits = src_elem_ty.hasRuntimeBits(zcu);
24110 const dest_has_bits = dest_elem_ty.hasRuntimeBits(zcu);
2495624111 assert(src_has_bits == dest_has_bits); // IMC
2495724112 if (src_has_bits) break :zero_bit;
2495824113
......@@ -24968,7 +24123,7 @@ fn zirMemcpy(
2496824123 const raw_dest_ptr = if (dest_ty.isSlice(zcu)) dest_ptr_val.slicePtr(zcu) else dest_ptr_val;
2496924124 const raw_src_ptr = if (src_ty.isSlice(zcu)) src_ptr_val.slicePtr(zcu) else src_ptr_val;
2497024125
24971 const len_u64 = try len_val.?.toUnsignedIntSema(pt);
24126 const len_u64 = len_val.?.toUnsignedInt(zcu);
2497224127
2497324128 if (check_aliasing) {
2497424129 if (Value.doPointersOverlap(
......@@ -25018,7 +24173,7 @@ fn zirMemcpy(
2501824173 var new_dest_ptr = dest_ptr;
2501924174 var new_src_ptr = src_ptr;
2502024175 if (len_val) |val| {
25021 const len = try val.toUnsignedIntSema(pt);
24176 const len = val.toUnsignedInt(zcu);
2502224177 if (len == 0) {
2502324178 // This AIR instruction guarantees length > 0 if it is comptime-known.
2502424179 return;
......@@ -25036,7 +24191,7 @@ fn zirMemcpy(
2503624191 }
2503724192 } else if (dest_len == .none and len_val == null) {
2503824193 // Change the dest to a slice, since its type must have the length.
25039 const dest_ptr_ptr = try sema.analyzeRef(block, dest_src, new_dest_ptr);
24194 const dest_ptr_ptr = try sema.analyzeRef(block, dest_src, new_dest_ptr, .none);
2504024195 new_dest_ptr = try sema.analyzeSlice(block, dest_src, dest_ptr_ptr, .zero, src_len, .none, LazySrcLoc.unneeded, dest_src, dest_src, dest_src, false);
2504124196 const new_src_ptr_ty = sema.typeOf(new_src_ptr);
2504224197 if (new_src_ptr_ty.isSlice(zcu)) {
......@@ -25067,7 +24222,7 @@ fn zirMemcpy(
2506724222 assert(dest_manyptr_ty_key.flags.size == .one);
2506824223 dest_manyptr_ty_key.child = dest_elem_ty.toIntern();
2506924224 dest_manyptr_ty_key.flags.size = .many;
25070 break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrTypeSema(dest_manyptr_ty_key), new_dest_ptr, dest_src);
24225 break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrType(dest_manyptr_ty_key), new_dest_ptr, dest_src);
2507124226 } else new_dest_ptr;
2507224227
2507324228 const new_src_ptr_ty = sema.typeOf(new_src_ptr);
......@@ -25078,13 +24233,13 @@ fn zirMemcpy(
2507824233 assert(src_manyptr_ty_key.flags.size == .one);
2507924234 src_manyptr_ty_key.child = src_elem_ty.toIntern();
2508024235 src_manyptr_ty_key.flags.size = .many;
25081 break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrTypeSema(src_manyptr_ty_key), new_src_ptr, src_src);
24236 break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrType(src_manyptr_ty_key), new_src_ptr, src_src);
2508224237 } else new_src_ptr;
2508324238
2508424239 // ok1: dest >= src + len
2508524240 // ok2: src >= dest + len
25086 const src_plus_len = try sema.analyzePtrArithmetic(block, src, raw_src_ptr, len, .ptr_add, src_src, src);
25087 const dest_plus_len = try sema.analyzePtrArithmetic(block, src, raw_dest_ptr, len, .ptr_add, dest_src, src);
24241 const src_plus_len = try sema.analyzePtrArithmetic(block, src, raw_src_ptr, len, .ptr_add, src);
24242 const dest_plus_len = try sema.analyzePtrArithmetic(block, src, raw_dest_ptr, len, .ptr_add, src);
2508824243 const ok1 = try block.addBinOp(.cmp_gte, raw_dest_ptr, src_plus_len);
2508924244 const ok2 = try block.addBinOp(.cmp_gte, new_src_ptr, dest_plus_len);
2509024245 const ok = try block.addBinOp(.bool_or, ok1, ok2);
......@@ -25113,8 +24268,8 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2511324268 const src = block.nodeOffset(inst_data.src_node);
2511424269 const dest_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2511524270 const value_src = block.builtinCallArgSrc(inst_data.src_node, 1);
25116 const dest_ptr = try sema.resolveInst(extra.lhs);
25117 const uncoerced_elem = try sema.resolveInst(extra.rhs);
24271 const dest_ptr = sema.resolveInst(extra.lhs);
24272 const uncoerced_elem = sema.resolveInst(extra.rhs);
2511824273 const dest_ptr_ty = sema.typeOf(dest_ptr);
2511924274 try checkMemOperand(sema, block, dest_src, dest_ptr_ty);
2512024275
......@@ -25145,10 +24300,17 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2514524300
2514624301 const elem = try sema.coerce(block, dest_elem_ty, uncoerced_elem, value_src);
2514724302
24303 const comptime_only_elem = switch (dest_elem_ty.classify(zcu)) {
24304 .no_possible_value => unreachable, // `elem` is a value of this type
24305 .one_possible_value => return, // no work to do
24306 .runtime => false,
24307 .partially_comptime, .fully_comptime => true,
24308 };
24309
2514824310 const runtime_src = rs: {
2514924311 const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, io, pt.tid, "len", .no_embedded_nulls), dest_src);
2515024312 const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse break :rs dest_src;
25151 const len_u64 = try len_val.toUnsignedIntSema(pt);
24313 const len_u64 = len_val.toUnsignedInt(zcu);
2515224314 const len = try sema.usizeCast(block, dest_src, len_u64);
2515324315 if (len == 0) {
2515424316 // This AIR instruction guarantees length > 0 if it is comptime-known.
......@@ -25157,7 +24319,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2515724319
2515824320 const ptr_val = try sema.resolveDefinedValue(block, dest_src, dest_ptr) orelse break :rs dest_src;
2515924321 if (!sema.isComptimeMutablePtr(ptr_val)) break :rs dest_src;
25160 const elem_val = try sema.resolveValue(elem) orelse break :rs value_src;
24322 const elem_val = sema.resolveValue(elem) orelse break :rs value_src;
2516124323 const array_ty = try pt.arrayType(.{
2516224324 .child = dest_elem_ty.toIntern(),
2516324325 .len = len_u64,
......@@ -25174,6 +24336,15 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2517424336 return sema.storePtrVal(block, src, array_ptr_val, array_val, array_ty);
2517524337 };
2517624338
24339 if (comptime_only_elem) {
24340 return sema.failWithOwnedErrorMsg(block, msg: {
24341 const msg = try sema.errMsg(src, "cannot store comptime-only element '{f}' at runtime", .{dest_elem_ty.fmt(pt)});
24342 errdefer msg.destroy(sema.gpa);
24343 try sema.errNote(dest_src, msg, "operation is runtime due to destination pointer", .{});
24344 break :msg msg;
24345 });
24346 }
24347
2517724348 try sema.requireRuntimeBlock(block, src, runtime_src);
2517824349 try sema.validateRuntimeValue(block, dest_src, dest_ptr);
2517924350 try sema.validateRuntimeValue(block, value_src, elem);
......@@ -25227,7 +24398,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2522724398 const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
2522824399 extra_index += 1;
2522924400 const cc_ty = try sema.getBuiltinType(cc_src, .CallingConvention);
25230 const uncoerced_cc = try sema.resolveInst(cc_ref);
24401 const uncoerced_cc = sema.resolveInst(cc_ref);
2523124402 const coerced_cc = try sema.coerce(block, cc_ty, uncoerced_cc, cc_src);
2523224403 const cc_val = try sema.resolveConstDefinedValue(block, cc_src, coerced_cc, .{ .simple = .@"callconv" });
2523324404 break :blk try sema.analyzeValueAsCallconv(block, cc_src, cc_val);
......@@ -25344,7 +24515,7 @@ fn zirCDefine(
2534424515 const val_src = block.builtinCallArgSrc(extra.node, 1);
2534524516
2534624517 const name = try sema.resolveConstString(block, name_src, extra.lhs, .{ .simple = .operand_cDefine_macro_name });
25347 const rhs = try sema.resolveInst(extra.rhs);
24518 const rhs = sema.resolveInst(extra.rhs);
2534824519 if (sema.typeOf(rhs).zigTypeTag(zcu) != .void) {
2534924520 const value = try sema.resolveConstString(block, val_src, extra.rhs, .{ .simple = .operand_cDefine_macro_value });
2535024521 try block.c_import_buf.?.print("#define {s} {s}\n", .{ name, value });
......@@ -25393,7 +24564,7 @@ fn zirWasmMemoryGrow(
2539324564 }
2539424565
2539524566 const index: u32 = @intCast(try sema.resolveInt(block, index_src, extra.lhs, .u32, .{ .simple = .wasm_memory_index }));
25396 const delta = try sema.coerce(block, .usize, try sema.resolveInst(extra.rhs), delta_src);
24567 const delta = try sema.coerce(block, .usize, sema.resolveInst(extra.rhs), delta_src);
2539724568
2539824569 try sema.requireRuntimeBlock(block, builtin_src, null);
2539924570 return block.addInst(.{
......@@ -25419,7 +24590,7 @@ fn resolvePrefetchOptions(
2541924590 const ip = &zcu.intern_pool;
2542024591
2542124592 const options_ty = try sema.getBuiltinType(src, .PrefetchOptions);
25422 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);
24593 const options = try sema.coerce(block, options_ty, sema.resolveInst(zir_ref), src);
2542324594
2542424595 const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node });
2542524596 const locality_src = block.src(.{ .init_field_locality = src.offset.node_offset_builtin_call_arg.builtin_call_node });
......@@ -25436,7 +24607,7 @@ fn resolvePrefetchOptions(
2543624607
2543724608 return std.builtin.PrefetchOptions{
2543824609 .rw = try sema.interpretBuiltinType(block, rw_src, rw_val, std.builtin.PrefetchOptions.Rw),
25439 .locality = @intCast(try locality_val.toUnsignedIntSema(pt)),
24610 .locality = @intCast(locality_val.toUnsignedInt(zcu)),
2544024611 .cache = try sema.interpretBuiltinType(block, cache_src, cache_val, std.builtin.PrefetchOptions.Cache),
2544124612 };
2544224613}
......@@ -25449,7 +24620,7 @@ fn zirPrefetch(
2544924620 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
2545024621 const ptr_src = block.builtinCallArgSrc(extra.node, 0);
2545124622 const opts_src = block.builtinCallArgSrc(extra.node, 1);
25452 const ptr = try sema.resolveInst(extra.lhs);
24623 const ptr = sema.resolveInst(extra.lhs);
2545324624 try sema.checkPtrOperand(block, ptr_src, sema.typeOf(ptr));
2545424625
2545524626 const options = try sema.resolvePrefetchOptions(block, opts_src, extra.rhs);
......@@ -25491,7 +24662,7 @@ fn resolveExternOptions(
2549124662 const io = comp.io;
2549224663 const ip = &zcu.intern_pool;
2549324664
25494 const options_inst = try sema.resolveInst(zir_ref);
24665 const options_inst = sema.resolveInst(zir_ref);
2549524666 const extern_options_ty = try sema.getBuiltinType(src, .ExternOptions);
2549624667 const options = try sema.coerce(block, extern_options_ty, options_inst, src);
2549724668
......@@ -25574,18 +24745,32 @@ fn zirBuiltinExtern(
2557424745 const ty_src = block.builtinCallArgSrc(extra.node, 0);
2557524746 const options_src = block.builtinCallArgSrc(extra.node, 1);
2557624747
25577 var ty = try sema.resolveType(block, ty_src, extra.lhs);
25578 if (!ty.isPtrAtRuntime(zcu)) {
24748 const ptr_ty = try sema.resolveType(block, ty_src, extra.lhs);
24749 if (!ptr_ty.isPtrAtRuntime(zcu)) {
2557924750 return sema.fail(block, ty_src, "expected (optional) pointer", .{});
2558024751 }
25581 if (!try sema.validateExternType(ty, .other)) {
25582 const msg = msg: {
25583 const msg = try sema.errMsg(ty_src, "extern symbol cannot have type '{f}'", .{ty.fmt(pt)});
24752
24753 const ptr_info = ptr_ty.ptrInfo(zcu);
24754
24755 const elem_ty: Type = .fromInterned(ptr_info.child);
24756 try sema.ensureLayoutResolved(elem_ty, src, .@"extern");
24757
24758 if (!elem_ty.validateExtern(.other, zcu)) {
24759 return sema.failWithOwnedErrorMsg(block, msg: {
24760 const msg = try sema.errMsg(ty_src, "extern symbol cannot have type '{f}'", .{ptr_ty.fmt(pt)});
2558424761 errdefer msg.destroy(sema.gpa);
25585 try sema.explainWhyTypeIsNotExtern(msg, ty_src, ty, .other);
24762 try sema.errNote(ty_src, msg, "pointer element type '{f}' is not extern compatible", .{elem_ty.fmt(pt)});
24763 try sema.explainWhyTypeIsNotExtern(msg, ty_src, elem_ty, .other);
2558624764 break :msg msg;
25587 };
25588 return sema.failWithOwnedErrorMsg(block, msg);
24765 });
24766 }
24767 if (elem_ty.zigTypeTag(zcu) == .@"fn" and !ptr_info.flags.is_const) {
24768 return sema.failWithOwnedErrorMsg(block, msg: {
24769 const msg = try sema.errMsg(ty_src, "extern symbol cannot have type '{f}'", .{ptr_ty.fmt(pt)});
24770 errdefer msg.destroy(sema.gpa);
24771 try sema.errNote(ty_src, msg, "pointer to extern function must be 'const'", .{});
24772 break :msg msg;
24773 });
2558924774 }
2559024775
2559124776 const options = try sema.resolveExternOptions(block, options_src, extra.rhs);
......@@ -25603,14 +24788,9 @@ fn zirBuiltinExtern(
2560324788
2560424789 // TODO: error for threadlocal functions, non-const functions, etc
2560524790
25606 if (options.linkage == .weak and !ty.ptrAllowsZero(zcu)) {
25607 ty = try pt.optionalType(ty.toIntern());
25608 }
25609 const ptr_info = ty.ptrInfo(zcu);
25610
2561124791 const extern_val = try pt.getExtern(.{
2561224792 .name = options.name,
25613 .ty = ptr_info.child,
24793 .ty = elem_ty.toIntern(),
2561424794 .lib_name = options.library_name,
2561524795 .linkage = options.linkage,
2561624796 .visibility = options.visibility,
......@@ -25626,7 +24806,7 @@ fn zirBuiltinExtern(
2562624806 // So, for now, just use our containing `declaration`.
2562724807 .zir_index = switch (sema.owner.unwrap()) {
2562824808 .@"comptime" => |cu| ip.getComptimeUnit(cu).zir_index,
25629 .type => |owner_ty| Type.fromInterned(owner_ty).typeDeclInst(zcu).?,
24809 .type_layout, .struct_defaults => |owner_ty| Type.fromInterned(owner_ty).typeDeclInstAllowGeneratedTag(zcu).?,
2563024810 .memoized_state => unreachable,
2563124811 .nav_ty, .nav_val => |nav| ip.getNav(nav).analysis.?.zir_index,
2563224812 .func => |func| zir_index: {
......@@ -25641,13 +24821,17 @@ fn zirBuiltinExtern(
2564124821 .source = .builtin,
2564224822 });
2564324823
24824 // For a weak symbol where the given type is not nullable, make the pointer optional.
24825 const result_ptr_ty: Type = if (options.linkage == .weak and !ptr_ty.ptrAllowsZero(zcu)) ty: {
24826 break :ty try pt.optionalType(ptr_ty.toIntern());
24827 } else ptr_ty;
24828
2564424829 const uncasted_ptr = try sema.analyzeNavRef(block, src, ip.indexToKey(extern_val).@"extern".owner_nav);
25645 // We want to cast to `ty`, but that isn't necessarily an allowed coercion.
25646 if (try sema.resolveValue(uncasted_ptr)) |uncasted_ptr_val| {
25647 const casted_ptr_val = try pt.getCoerced(uncasted_ptr_val, ty);
24830 if (sema.resolveValue(uncasted_ptr)) |uncasted_ptr_val| {
24831 const casted_ptr_val = try pt.getCoerced(uncasted_ptr_val, result_ptr_ty);
2564824832 return Air.internedToRef(casted_ptr_val.toIntern());
2564924833 } else {
25650 return block.addBitCast(ty, uncasted_ptr);
24834 return block.addBitCast(result_ptr_ty, uncasted_ptr);
2565124835 }
2565224836}
2565324837
......@@ -25732,6 +24916,7 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
2573224916 // Values are handled here.
2573324917 .calling_convention_c => {
2573424918 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
24919 // Cannot use `Value.uninterpret` because `c` is a *declaration* whose value depends on the target.
2573524920 return try sema.namespaceLookupVal(
2573624921 block,
2573724922 src,
......@@ -25740,17 +24925,15 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
2574024925 ) orelse @panic("std.builtin is corrupt");
2574124926 },
2574224927 .calling_convention_inline => {
25743 comptime assert(@typeInfo(std.builtin.CallingConvention.Tag).@"enum".tag_type == u8);
2574424928 const callconv_ty = try sema.getBuiltinType(src, .CallingConvention);
25745 const callconv_tag_ty = callconv_ty.unionTagType(zcu) orelse @panic("std.builtin is corrupt");
25746 const inline_tag_val = try pt.enumValue(
25747 callconv_tag_ty,
25748 (try pt.intValue(
25749 .u8,
25750 @intFromEnum(std.builtin.CallingConvention.@"inline"),
25751 )).toIntern(),
25752 );
25753 return sema.coerce(block, callconv_ty, Air.internedToRef(inline_tag_val.toIntern()), src);
24929 return .fromValue(Value.uninterpret(
24930 @as(std.builtin.CallingConvention, .@"inline"),
24931 callconv_ty,
24932 pt,
24933 ) catch |err| switch (err) {
24934 error.TypeMismatch => @panic("std.builtin is corrupt"),
24935 error.OutOfMemory => |e| return e,
24936 });
2575424937 },
2575524938 };
2575624939 return .fromType(try sema.getBuiltinType(src, builtin_type));
......@@ -25760,7 +24943,7 @@ fn zirInplaceArithResultTy(sema: *Sema, extended: Zir.Inst.Extended.InstData) Co
2576024943 const pt = sema.pt;
2576124944 const zcu = pt.zcu;
2576224945
25763 const lhs = try sema.resolveInst(@enumFromInt(extended.operand));
24946 const lhs = sema.resolveInst(@enumFromInt(extended.operand));
2576424947 const lhs_ty = sema.typeOf(lhs);
2576524948
2576624949 const op: Zir.Inst.InplaceOp = @enumFromInt(extended.small);
......@@ -25785,7 +24968,7 @@ fn zirInplaceArithResultTy(sema: *Sema, extended: Zir.Inst.Extended.InstData) Co
2578524968
2578624969fn zirBranchHint(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
2578724970 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
25788 const uncoerced_hint = try sema.resolveInst(extra.operand);
24971 const uncoerced_hint = sema.resolveInst(extra.operand);
2578924972 const operand_src = block.builtinCallArgSrc(extra.node, 0);
2579024973
2579124974 const hint_ty = try sema.getBuiltinType(operand_src, .BranchHint);
......@@ -25839,7 +25022,8 @@ fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc, runtime_src:
2583925022 }
2584025023}
2584125024
25842/// Emit a compile error if type cannot be used for a runtime variable.
25025/// Emit a compile error if `var_ty` cannot be used for a runtime variable.
25026/// Asserts that the layout of `var_ty` is already resolved.
2584325027pub fn validateVarType(
2584425028 sema: *Sema,
2584525029 block: *Block,
......@@ -25849,8 +25033,9 @@ pub fn validateVarType(
2584925033) CompileError!void {
2585025034 const pt = sema.pt;
2585125035 const zcu = pt.zcu;
25036 var_ty.assertHasLayout(zcu);
2585225037 if (is_extern) {
25853 if (!try sema.validateExternType(var_ty, .other)) {
25038 if (!var_ty.validateExtern(.other, zcu)) {
2585425039 const msg = msg: {
2585525040 const msg = try sema.errMsg(src, "extern variable cannot have type '{f}'", .{var_ty.fmt(pt)});
2585625041 errdefer msg.destroy(sema.gpa);
......@@ -25870,7 +25055,7 @@ pub fn validateVarType(
2587025055 }
2587125056 }
2587225057
25873 if (!try var_ty.comptimeOnlySema(pt)) return;
25058 if (!var_ty.comptimeOnly(zcu)) return;
2587425059
2587525060 const msg = msg: {
2587625061 const msg = try sema.errMsg(src, "variable of type '{f}' must be const or comptime", .{var_ty.fmt(pt)});
......@@ -25886,49 +25071,28 @@ pub fn validateVarType(
2588625071 return sema.failWithOwnedErrorMsg(block, msg);
2588725072}
2588825073
25889const TypeSet = std.AutoHashMapUnmanaged(InternPool.Index, void);
25890
2589125074fn explainWhyTypeIsComptime(
2589225075 sema: *Sema,
2589325076 msg: *Zcu.ErrorMsg,
25894 src_loc: LazySrcLoc,
25895 ty: Type,
25896) CompileError!void {
25897 var type_set = TypeSet{};
25898 defer type_set.deinit(sema.gpa);
25899
25900 try ty.resolveFully(sema.pt);
25901 return sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty, &type_set);
25902}
25903
25904fn explainWhyTypeIsComptimeInner(
25905 sema: *Sema,
25906 msg: *Zcu.ErrorMsg,
25907 src_loc: LazySrcLoc,
25077 src: LazySrcLoc,
2590825078 ty: Type,
25909 type_set: *TypeSet,
2591025079) CompileError!void {
2591125080 const pt = sema.pt;
2591225081 const zcu = pt.zcu;
2591325082 const ip = &zcu.intern_pool;
25083 assert(ty.comptimeOnly(zcu));
2591425084 switch (ty.zigTypeTag(zcu)) {
2591525085 .bool,
2591625086 .int,
2591725087 .float,
2591825088 .error_set,
25919 .@"enum",
2592025089 .frame,
2592125090 .@"anyframe",
2592225091 .void,
25923 => return,
25924
25925 .@"fn" => {
25926 try sema.errNote(src_loc, msg, "use '*const {f}' for a function pointer type", .{ty.fmt(pt)});
25927 },
25928
25929 .type => {
25930 try sema.errNote(src_loc, msg, "types are not available at runtime", .{});
25931 },
25092 .@"enum",
25093 .@"opaque",
25094 .pointer,
25095 => unreachable, // not comptime-only
2593225096
2593325097 .comptime_float,
2593425098 .comptime_int,
......@@ -25936,99 +25100,65 @@ fn explainWhyTypeIsComptimeInner(
2593625100 .noreturn,
2593725101 .undefined,
2593825102 .null,
25939 => return,
25940
25941 .@"opaque" => {
25942 try sema.errNote(src_loc, msg, "opaque type '{f}' has undefined size", .{ty.fmt(pt)});
25943 },
25944
25945 .array, .vector => {
25946 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.childType(zcu), type_set);
25947 },
25948 .pointer => {
25949 const elem_ty = ty.elemType2(zcu);
25950 if (elem_ty.zigTypeTag(zcu) == .@"fn") {
25951 const fn_info = zcu.typeToFunc(elem_ty).?;
25952 if (fn_info.is_generic) {
25953 try sema.errNote(src_loc, msg, "function is generic", .{});
25954 }
25955 switch (fn_info.cc) {
25956 .@"inline" => try sema.errNote(src_loc, msg, "function has inline calling convention", .{}),
25957 else => {},
25958 }
25959 if (Type.fromInterned(fn_info.return_type).comptimeOnly(zcu)) {
25960 try sema.errNote(src_loc, msg, "function has a comptime-only return type", .{});
25961 }
25962 return;
25963 }
25964 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.childType(zcu), type_set);
25965 },
25966
25967 .optional => {
25968 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.optionalChild(zcu), type_set);
25969 },
25970 .error_union => {
25971 try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.errorUnionPayload(zcu), type_set);
25972 },
25103 => return, // no explanation needed
2597325104
25974 .@"struct" => {
25975 if ((try type_set.getOrPut(sema.gpa, ty.toIntern())).found_existing) return;
25105 .array, .vector => try sema.explainWhyTypeIsComptime(msg, src, ty.childType(zcu)),
25106 .optional => try sema.explainWhyTypeIsComptime(msg, src, ty.optionalChild(zcu)),
25107 .error_union => try sema.explainWhyTypeIsComptime(msg, src, ty.errorUnionPayload(zcu)),
2597625108
25977 if (zcu.typeToStruct(ty)) |struct_type| {
25978 for (0..struct_type.field_types.len) |i| {
25979 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]);
25980 const field_src: LazySrcLoc = .{
25981 .base_node_inst = struct_type.zir_index,
25982 .offset = .{ .container_field_type = @intCast(i) },
25983 };
25109 .@"fn" => try sema.errNote(src, msg, "use '*const {f}' for a function pointer type", .{ty.fmt(pt)}),
25110 .type => try sema.errNote(src, msg, "types are not available at runtime", .{}),
2598425111
25985 if (try field_ty.comptimeOnlySema(pt)) {
25986 try sema.errNote(field_src, msg, "struct requires comptime because of this field", .{});
25987 try sema.explainWhyTypeIsComptimeInner(msg, field_src, field_ty, type_set);
25988 }
25989 }
25112 .@"struct" => if (zcu.typeToStruct(ty)) |struct_type| {
25113 ty.assertHasLayout(zcu);
25114 for (0..struct_type.field_types.len) |i| {
25115 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]);
25116 if (!field_ty.comptimeOnly(zcu)) continue;
25117 const field_src: LazySrcLoc = .{
25118 .base_node_inst = struct_type.zir_index,
25119 .offset = .{ .container_field_type = @intCast(i) },
25120 };
25121 try sema.errNote(field_src, msg, "struct requires comptime because of this field", .{});
25122 return sema.explainWhyTypeIsComptime(msg, field_src, field_ty);
25123 }
25124 unreachable;
25125 } else {
25126 const tuple = ip.indexToKey(ty.toIntern()).tuple_type;
25127 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty_ip, field_val_ip| {
25128 if (field_val_ip != .none) continue;
25129 const field_ty: Type = .fromInterned(field_ty_ip);
25130 if (!field_ty.comptimeOnly(zcu)) continue;
25131 try sema.errNote(src, msg, "tuple requires comptime because of field of type '{f}'", .{field_ty.fmt(pt)});
25132 return sema.explainWhyTypeIsComptime(msg, src, field_ty);
2599025133 }
25991 // TODO tuples
25134 unreachable;
2599225135 },
2599325136
2599425137 .@"union" => {
25995 if ((try type_set.getOrPut(sema.gpa, ty.toIntern())).found_existing) return;
25996
25997 if (zcu.typeToUnion(ty)) |union_obj| {
25998 for (0..union_obj.field_types.len) |i| {
25999 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[i]);
26000 const field_src: LazySrcLoc = .{
26001 .base_node_inst = union_obj.zir_index,
26002 .offset = .{ .container_field_type = @intCast(i) },
26003 };
26004
26005 if (try field_ty.comptimeOnlySema(pt)) {
26006 try sema.errNote(field_src, msg, "union requires comptime because of this field", .{});
26007 try sema.explainWhyTypeIsComptimeInner(msg, field_src, field_ty, type_set);
26008 }
26009 }
25138 const union_obj = zcu.typeToUnion(ty).?;
25139 for (0..union_obj.field_types.len) |i| {
25140 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[i]);
25141 if (!field_ty.comptimeOnly(zcu)) continue;
25142 const field_src: LazySrcLoc = .{
25143 .base_node_inst = union_obj.zir_index,
25144 .offset = .{ .container_field_type = @intCast(i) },
25145 };
25146 try sema.errNote(field_src, msg, "union requires comptime because of this field", .{});
25147 return sema.explainWhyTypeIsComptime(msg, field_src, field_ty);
2601025148 }
25149 unreachable;
2601125150 },
2601225151 }
2601325152}
2601425153
26015const ExternPosition = enum {
26016 ret_ty,
26017 param_ty,
26018 union_field,
26019 struct_field,
26020 element,
26021 other,
26022};
26023
26024/// Returns true if `ty` is allowed in extern types.
26025/// Does *NOT* require `ty` to be resolved in any way.
26026/// Calls `resolveLayout` for packed containers.
26027fn validateExternType(
25154/// Keep in sync with `Type.validateExtern`.
25155pub fn explainWhyTypeIsNotExtern(
2602825156 sema: *Sema,
25157 msg: *Zcu.ErrorMsg,
25158 src_loc: LazySrcLoc,
2602925159 ty: Type,
26030 position: ExternPosition,
26031) !bool {
25160 position: Type.ExternPosition,
25161) SemaError!void {
2603225162 const pt = sema.pt;
2603325163 const zcu = pt.zcu;
2603425164 switch (ty.zigTypeTag(zcu)) {
......@@ -26041,217 +25171,122 @@ fn validateExternType(
2604125171 .error_union,
2604225172 .error_set,
2604325173 .frame,
26044 => return false,
26045 .void => return position == .union_field or position == .ret_ty or position == .struct_field or position == .element,
26046 .noreturn => return position == .ret_ty,
26047 .@"opaque",
26048 .bool,
26049 .float,
26050 .@"anyframe",
26051 => return true,
26052 .pointer => {
26053 if (ty.childType(zcu).zigTypeTag(zcu) == .@"fn") {
26054 return ty.isConstPtr(zcu) and try sema.validateExternType(ty.childType(zcu), .other);
26055 }
26056 return !(ty.isSlice(zcu) or try ty.comptimeOnlySema(pt));
26057 },
26058 .int => switch (ty.intInfo(zcu).bits) {
26059 0, 8, 16, 32, 64, 128 => return true,
26060 else => return false,
26061 },
26062 .@"fn" => {
26063 if (position != .other) return false;
26064 // For now we want to authorize PTX kernel to use zig objects, even if we end up exposing the ABI.
26065 // The goal is to experiment with more integrated CPU/GPU code.
26066 if (ty.fnCallingConvention(zcu) == .nvptx_kernel) {
26067 return true;
26068 }
26069 return !target_util.fnCallConvAllowsZigTypes(ty.fnCallingConvention(zcu));
26070 },
26071 .@"enum" => {
26072 return sema.validateExternType(ty.intTagType(zcu), position);
26073 },
26074 .@"struct", .@"union" => switch (ty.containerLayout(zcu)) {
26075 .@"extern" => return true,
26076 .@"packed" => {
26077 const bit_size = try ty.bitSizeSema(pt);
26078 switch (bit_size) {
26079 0, 8, 16, 32, 64, 128 => return true,
26080 else => return false,
26081 }
26082 },
26083 .auto => return !(try ty.hasRuntimeBitsSema(pt)),
26084 },
26085 .array => {
26086 if (position == .ret_ty or position == .param_ty) return false;
26087 return sema.validateExternType(ty.elemType2(zcu), .element);
26088 },
26089 .vector => return sema.validateExternType(ty.elemType2(zcu), .element),
26090 .optional => return ty.isPtrLikeOptional(zcu),
26091 }
26092}
25174 => return,
25175
25176 .void => try sema.errNote(src_loc, msg, "'void' is a zero bit type", .{}),
25177 .noreturn => try sema.errNote(src_loc, msg, "'noreturn' is only allowed as a return type", .{}),
2609325178
26094fn explainWhyTypeIsNotExtern(
26095 sema: *Sema,
26096 msg: *Zcu.ErrorMsg,
26097 src_loc: LazySrcLoc,
26098 ty: Type,
26099 position: ExternPosition,
26100) CompileError!void {
26101 const pt = sema.pt;
26102 const zcu = pt.zcu;
26103 switch (ty.zigTypeTag(zcu)) {
2610425179 .@"opaque",
2610525180 .bool,
2610625181 .float,
2610725182 .@"anyframe",
26108 => return,
26109
26110 .type,
26111 .comptime_float,
26112 .comptime_int,
26113 .enum_literal,
26114 .undefined,
26115 .null,
26116 .error_union,
26117 .error_set,
26118 .frame,
26119 => return,
25183 => unreachable, // these *are* allowed
2612025184
26121 .pointer => {
26122 if (ty.isSlice(zcu)) {
26123 try sema.errNote(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
25185 .pointer => if (ty.isSlice(zcu)) {
25186 try sema.errNote(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
25187 } else {
25188 assert(ty.childType(zcu).zigTypeTag(zcu) == .@"fn");
25189 if (!ty.isConstPtr(zcu)) {
25190 try sema.errNote(src_loc, msg, "pointer to extern function must be 'const'", .{});
2612425191 } else {
26125 const pointee_ty = ty.childType(zcu);
26126 if (!ty.isConstPtr(zcu) and pointee_ty.zigTypeTag(zcu) == .@"fn") {
26127 try sema.errNote(src_loc, msg, "pointer to extern function must be 'const'", .{});
26128 } else if (try ty.comptimeOnlySema(pt)) {
26129 try sema.errNote(src_loc, msg, "pointer to comptime-only type '{f}'", .{pointee_ty.fmt(pt)});
26130 try sema.explainWhyTypeIsComptime(msg, src_loc, ty);
26131 }
26132 try sema.explainWhyTypeIsNotExtern(msg, src_loc, pointee_ty, .other);
25192 try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.childType(zcu), .other);
2613325193 }
2613425194 },
26135 .void => try sema.errNote(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}),
26136 .noreturn => try sema.errNote(src_loc, msg, "'noreturn' is only allowed as a return type", .{}),
2613725195 .int => if (!std.math.isPowerOfTwo(ty.intInfo(zcu).bits)) {
2613825196 try sema.errNote(src_loc, msg, "only integers with 0 or power of two bits are extern compatible", .{});
2613925197 } else {
2614025198 try sema.errNote(src_loc, msg, "only integers with 0, 8, 16, 32, 64 and 128 bits are extern compatible", .{});
2614125199 },
26142 .@"fn" => {
26143 if (position != .other) {
26144 try sema.errNote(src_loc, msg, "type has no guaranteed in-memory representation", .{});
26145 try sema.errNote(src_loc, msg, "use '*const ' to make a function pointer type", .{});
26146 return;
26147 }
26148 switch (ty.fnCallingConvention(zcu)) {
26149 .auto => try sema.errNote(src_loc, msg, "extern function must specify calling convention", .{}),
26150 .async => try sema.errNote(src_loc, msg, "async function cannot be extern", .{}),
26151 .@"inline" => try sema.errNote(src_loc, msg, "inline function cannot be extern", .{}),
26152 else => return,
26153 }
25200 .@"fn" => if (position != .other) {
25201 try sema.errNote(src_loc, msg, "type has no guaranteed in-memory representation", .{});
25202 try sema.errNote(src_loc, msg, "use '*const ' to make a function pointer type", .{});
25203 } else switch (ty.fnCallingConvention(zcu)) {
25204 .auto => try sema.errNote(src_loc, msg, "extern function must specify calling convention", .{}),
25205 else => |cc| try sema.errNote(src_loc, msg, "{t} function cannot be extern", .{cc}),
2615425206 },
2615525207 .@"enum" => {
26156 const tag_ty = ty.intTagType(zcu);
26157 try sema.errNote(src_loc, msg, "enum tag type '{f}' is not extern compatible", .{tag_ty.fmt(pt)});
26158 try sema.explainWhyTypeIsNotExtern(msg, src_loc, tag_ty, position);
25208 const enum_obj = zcu.intern_pool.loadEnumType(ty.toIntern());
25209 switch (enum_obj.int_tag_mode) {
25210 .auto => {
25211 try sema.errNote(ty.srcLoc(zcu), msg, "integer tag type of enum is inferred", .{});
25212 try sema.errNote(ty.srcLoc(zcu), msg, "consider explicitly specifying the integer tag type", .{});
25213 },
25214 .explicit => {
25215 const tag_ty: Type = .fromInterned(enum_obj.int_tag_type);
25216 try sema.errNote(ty.srcLoc(zcu), msg, "enum tag type '{f}' is not extern compatible", .{tag_ty.fmt(pt)});
25217 try sema.explainWhyTypeIsNotExtern(msg, ty.srcLoc(zcu), tag_ty, position);
25218 },
25219 }
2615925220 },
26160 .@"struct" => try sema.errNote(src_loc, msg, "only extern structs and ABI sized packed structs are extern compatible", .{}),
26161 .@"union" => try sema.errNote(src_loc, msg, "only extern unions and ABI sized packed unions are extern compatible", .{}),
26162 .array => {
26163 if (position == .ret_ty) {
26164 return sema.errNote(src_loc, msg, "arrays are not allowed as a return type", .{});
26165 } else if (position == .param_ty) {
26166 return sema.errNote(src_loc, msg, "arrays are not allowed as a parameter type", .{});
25221 .@"struct" => {
25222 const struct_obj = zcu.intern_pool.loadStructType(ty.toIntern());
25223 switch (struct_obj.layout) {
25224 .auto => try sema.errNote(src_loc, msg, "struct with automatic layout has no guaranteed in-memory representation", .{}),
25225 .@"extern" => unreachable,
25226 .@"packed" => switch (struct_obj.packed_backing_mode) {
25227 .auto => try sema.errNote(src_loc, msg, "inferred backing integer of packed struct has unspecified signedness", .{}),
25228 .explicit => {
25229 const backing_int_ty: Type = .fromInterned(struct_obj.packed_backing_int_type);
25230 try sema.errNote(src_loc, msg, "packed struct backing integer type '{f}' is not extern compatible", .{backing_int_ty.fmt(pt)});
25231 try sema.explainWhyTypeIsNotExtern(msg, src_loc, backing_int_ty, position);
25232 },
25233 },
2616725234 }
26168 try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(zcu), .element);
2616925235 },
26170 .vector => try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.elemType2(zcu), .element),
26171 .optional => try sema.errNote(src_loc, msg, "only pointer like optionals are extern compatible", .{}),
26172 }
26173}
26174
26175/// Returns true if `ty` is allowed in packed types.
26176/// Does not require `ty` to be resolved in any way, but may resolve whether it is comptime-only.
26177fn validatePackedType(sema: *Sema, ty: Type) !bool {
26178 const pt = sema.pt;
26179 const zcu = pt.zcu;
26180 return switch (ty.zigTypeTag(zcu)) {
26181 .type,
26182 .comptime_float,
26183 .comptime_int,
26184 .enum_literal,
26185 .undefined,
26186 .null,
26187 .error_union,
26188 .error_set,
26189 .frame,
26190 .noreturn,
26191 .@"opaque",
26192 .@"anyframe",
26193 .@"fn",
26194 .array,
26195 => false,
26196 .optional => return ty.isPtrLikeOptional(zcu),
26197 .void,
26198 .bool,
26199 .float,
26200 .int,
26201 .vector,
26202 => true,
26203 .@"enum" => switch (zcu.intern_pool.loadEnumType(ty.toIntern()).tag_mode) {
26204 .auto => false,
26205 .explicit, .nonexhaustive => true,
25236 .@"union" => {
25237 const union_obj = zcu.intern_pool.loadUnionType(ty.toIntern());
25238 switch (union_obj.layout) {
25239 .auto => try sema.errNote(src_loc, msg, "union with automatic layout has no guaranteed in-memory representation", .{}),
25240 .@"extern" => unreachable,
25241 .@"packed" => switch (union_obj.packed_backing_mode) {
25242 .auto => try sema.errNote(src_loc, msg, "inferred backing integer of packed union has unspecified signedness", .{}),
25243 .explicit => {
25244 const backing_int_ty: Type = .fromInterned(union_obj.packed_backing_int_type);
25245 try sema.errNote(src_loc, msg, "packed union backing integer type '{f}' is not extern compatible", .{backing_int_ty.fmt(pt)});
25246 try sema.explainWhyTypeIsNotExtern(msg, src_loc, backing_int_ty, position);
25247 },
25248 },
25249 }
2620625250 },
26207 .pointer => !ty.isSlice(zcu) and !try ty.comptimeOnlySema(pt),
26208 .@"struct", .@"union" => ty.containerLayout(zcu) == .@"packed",
26209 };
25251 .array => switch (position) {
25252 .ret_ty => try sema.errNote(src_loc, msg, "arrays are not allowed as a return type", .{}),
25253 .param_ty => try sema.errNote(src_loc, msg, "arrays are not allowed as a parameter type", .{}),
25254 else => try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.childType(zcu), .element),
25255 },
25256 .vector => try sema.explainWhyTypeIsNotExtern(msg, src_loc, ty.childType(zcu), .element),
25257 .optional => try sema.errNote(src_loc, msg, "non-pointer optionals have no guaranteed in-memory representation", .{}),
25258 }
2621025259}
2621125260
26212fn explainWhyTypeIsNotPacked(
25261pub fn explainWhyTypeIsUnpackable(
2621325262 sema: *Sema,
2621425263 msg: *Zcu.ErrorMsg,
26215 src_loc: LazySrcLoc,
26216 ty: Type,
25264 src: LazySrcLoc,
25265 reason: Type.UnpackableReason,
2621725266) CompileError!void {
2621825267 const pt = sema.pt;
2621925268 const zcu = pt.zcu;
26220 switch (ty.zigTypeTag(zcu)) {
26221 .void,
26222 .bool,
26223 .float,
26224 .int,
26225 .vector,
26226 .@"enum",
26227 => return,
26228 .type,
26229 .comptime_float,
26230 .comptime_int,
26231 .enum_literal,
26232 .undefined,
26233 .null,
26234 .frame,
26235 .noreturn,
26236 .@"opaque",
26237 .error_union,
26238 .error_set,
26239 .@"anyframe",
26240 .optional,
26241 .array,
26242 => try sema.errNote(src_loc, msg, "type has no guaranteed in-memory representation", .{}),
26243 .pointer => if (ty.isSlice(zcu)) {
26244 try sema.errNote(src_loc, msg, "slices have no guaranteed in-memory representation", .{});
26245 } else {
26246 try sema.errNote(src_loc, msg, "comptime-only pointer has no guaranteed in-memory representation", .{});
26247 try sema.explainWhyTypeIsComptime(msg, src_loc, ty);
25269 switch (reason) {
25270 .comptime_only => try sema.errNote(src, msg, "comptime-only types have no bit-packed representation", .{}),
25271 .pointer => {
25272 try sema.errNote(src, msg, "pointers cannot be directly bitpacked", .{});
25273 try sema.errNote(src, msg, "consider using 'usize' and '@intFromPtr'", .{});
2624825274 },
26249 .@"fn" => {
26250 try sema.errNote(src_loc, msg, "type has no guaranteed in-memory representation", .{});
26251 try sema.errNote(src_loc, msg, "use '*const ' to make a function pointer type", .{});
25275 .enum_inferred_int_tag => |enum_ty| {
25276 const enum_src = enum_ty.srcLoc(zcu);
25277 try sema.errNote(enum_src, msg, "integer tag type of enum is inferred", .{});
25278 try sema.errNote(enum_src, msg, "consider explicitly specifying the integer tag type", .{});
25279 },
25280 .non_packed_struct => |struct_ty| {
25281 try sema.errNote(src, msg, "non-packed structs do not have a bit-packed representation", .{});
25282 try sema.addDeclaredHereNote(msg, struct_ty);
25283 },
25284 .non_packed_union => |union_ty| {
25285 try sema.errNote(src, msg, "non-packed unions do not have a bit-packed representation", .{});
25286 try sema.addDeclaredHereNote(msg, union_ty);
2625225287 },
26253 .@"struct" => try sema.errNote(src_loc, msg, "only packed structs layout are allowed in packed types", .{}),
26254 .@"union" => try sema.errNote(src_loc, msg, "only packed unions layout are allowed in packed types", .{}),
25288 .slice => try sema.errNote(src, msg, "slices do not have a bit-packed representation", .{}),
25289 .other => try sema.errNote(src, msg, "type does not have a bit-packed representation", .{}),
2625525290 }
2625625291}
2625725292
......@@ -26277,7 +25312,14 @@ fn getPanicIdFunc(sema: *Sema, src: LazySrcLoc, panic_id: Zcu.SimplePanicId) !In
2627725312 try sema.ensureMemoizedStateResolved(src, .panic);
2627825313 const panic_fn_index = zcu.builtin_decl_values.get(panic_id.toBuiltin());
2627925314 switch (sema.owner.unwrap()) {
26280 .@"comptime", .nav_ty, .nav_val, .type, .memoized_state => {},
25315 .@"comptime",
25316 .nav_ty,
25317 .nav_val,
25318 .type_layout,
25319 .struct_defaults,
25320 .memoized_state,
25321 => {},
25322
2628125323 .func => |owner_func| zcu.intern_pool.funcSetHasErrorTrace(io, owner_func, true),
2628225324 }
2628325325 return panic_fn_index;
......@@ -26297,7 +25339,7 @@ fn addSafetyCheck(
2629725339 .parent = parent_block,
2629825340 .sema = sema,
2629925341 .namespace = parent_block.namespace,
26300 .instructions = .{},
25342 .instructions = .empty,
2630125343 .inlining = parent_block.inlining,
2630225344 .comptime_reason = null,
2630325345 .src_base_inst = parent_block.src_base_inst,
......@@ -26391,7 +25433,7 @@ fn addSafetyCheckUnwrapError(
2639125433 .parent = parent_block,
2639225434 .sema = sema,
2639325435 .namespace = parent_block.namespace,
26394 .instructions = .{},
25436 .instructions = .empty,
2639525437 .inlining = parent_block.inlining,
2639625438 .comptime_reason = null,
2639725439 .src_base_inst = parent_block.src_base_inst,
......@@ -26458,21 +25500,39 @@ fn addSafetyCheckSentinelMismatch(
2645825500 const expected_sentinel = Air.internedToRef(expected_sentinel_val.toIntern());
2645925501
2646025502 const ptr_ty = sema.typeOf(ptr);
26461 const actual_sentinel = if (ptr_ty.isSlice(zcu))
26462 try parent_block.addBinOp(.slice_elem_val, ptr, sentinel_index)
26463 else blk: {
26464 const elem_ptr_ty = try ptr_ty.elemPtrType(null, pt);
26465 const sentinel_ptr = try parent_block.addPtrElemPtr(ptr, sentinel_index, elem_ptr_ty);
26466 break :blk try parent_block.addTyOp(.load, sentinel_ty, sentinel_ptr);
26467 };
26468
26469 const ok = if (sentinel_ty.zigTypeTag(zcu) == .vector) ok: {
26470 const eql = try parent_block.addCmpVector(expected_sentinel, actual_sentinel, .eq);
26471 break :ok try parent_block.addReduce(eql, .And);
26472 } else ok: {
26473 assert(sentinel_ty.isSelfComparable(zcu, true));
26474 break :ok try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel);
25503 const ptr_info = ptr_ty.ptrInfo(zcu);
25504 const actual_sentinel: Air.Inst.Ref = switch (ptr_ty.ptrSize(zcu)) {
25505 .slice => try parent_block.addBinOp(.slice_elem_val, ptr, sentinel_index),
25506 .one => s: {
25507 const array_ty: Type = .fromInterned(ptr_info.child);
25508 assert(array_ty.zigTypeTag(zcu) == .array);
25509 assert(array_ty.childType(zcu).toIntern() == sentinel_ty.toIntern());
25510 const many_ptr_ty = try pt.ptrType(.{
25511 .child = sentinel_ty.toIntern(),
25512 .flags = .{
25513 .size = .many,
25514 .is_const = ptr_info.flags.is_const,
25515 .is_volatile = ptr_info.flags.is_volatile,
25516 .is_allowzero = ptr_info.flags.is_allowzero,
25517 .alignment = switch (ptr_info.flags.alignment) {
25518 .none => .none,
25519 else => |ptr_align| .minStrict(ptr_align, sentinel_ty.abiAlignment(zcu)),
25520 },
25521 .address_space = ptr_info.flags.address_space,
25522 },
25523 });
25524 const many_ptr = try parent_block.addBitCast(many_ptr_ty, ptr);
25525 break :s try parent_block.addBinOp(.ptr_elem_val, many_ptr, sentinel_index);
25526 },
25527 .many => unreachable,
25528 .c => unreachable,
2647525529 };
25530 assert(sema.typeOf(actual_sentinel).toIntern() == sentinel_ty.toIntern());
25531 assert(sentinel_ty.isSelfComparable(zcu, true));
25532 const ok: Air.Inst.Ref = if (sentinel_ty.zigTypeTag(zcu) == .vector) ok: {
25533 const elementwise = try parent_block.addCmpVector(expected_sentinel, actual_sentinel, .eq);
25534 break :ok try parent_block.addReduce(elementwise, .And);
25535 } else try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel);
2647625536
2647725537 return addSafetyCheckCall(sema, parent_block, src, ok, .@"panic.sentinelMismatch", &.{
2647825538 expected_sentinel, actual_sentinel,
......@@ -26496,7 +25556,7 @@ fn addSafetyCheckCall(
2649625556 .parent = parent_block,
2649725557 .sema = sema,
2649825558 .namespace = parent_block.namespace,
26499 .instructions = .{},
25559 .instructions = .empty,
2650025560 .inlining = parent_block.inlining,
2650125561 .comptime_reason = null,
2650225562 .src_base_inst = parent_block.src_base_inst,
......@@ -26554,8 +25614,10 @@ fn fieldPtrLoad(
2655425614 const pt = sema.pt;
2655525615 const zcu = pt.zcu;
2655625616 const object_ptr_ty = sema.typeOf(object_ptr);
25617 assert(object_ptr_ty.zigTypeTag(zcu) == .pointer);
2655725618 const pointee_ty = object_ptr_ty.childType(zcu);
26558 if (try typeHasOnePossibleValue(sema, pointee_ty)) |opv| {
25619 try sema.ensureLayoutResolved(pointee_ty, src, .ptr_access);
25620 if (try pointee_ty.onePossibleValue(pt)) |opv| {
2655925621 const object: Air.Inst.Ref = .fromValue(opv);
2656025622 return fieldVal(sema, block, src, object, field_name, field_name_src);
2656125623 }
......@@ -26603,7 +25665,7 @@ fn fieldVal(
2660325665 return Air.internedToRef((try pt.intValue(.usize, inner_ty.arrayLen(zcu))).toIntern());
2660425666 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
2660525667 const ptr_info = object_ty.ptrInfo(zcu);
26606 const result_ty = try pt.ptrTypeSema(.{
25668 const result_ty = try pt.ptrType(.{
2660725669 .child = Type.fromInterned(ptr_info.child).childType(zcu).toIntern(),
2660825670 .sentinel = if (inner_ty.sentinel(zcu)) |s| s.toIntern() else .none,
2660925671 .flags = .{
......@@ -26663,37 +25725,34 @@ fn fieldVal(
2666325725
2666425726 switch (child_type.zigTypeTag(zcu)) {
2666525727 .error_set => {
26666 switch (ip.indexToKey(child_type.toIntern())) {
26667 .error_set_type => |error_set_type| blk: {
26668 if (error_set_type.nameIndex(ip, field_name) != null) break :blk;
25728 const err_set_ty: Type = err_set: switch (ip.indexToKey(child_type.toIntern())) {
25729 .inferred_error_set_type => |func_index| {
25730 try sema.ensureFuncIesResolved(block, src, func_index);
25731 const resolved_ies = ip.funcIesResolvedUnordered(func_index);
25732 continue :err_set ip.indexToKey(resolved_ies);
25733 },
25734 .error_set_type => |err_set| if (err_set.nameIndex(ip, field_name) == null) {
2666925735 return sema.fail(block, src, "no error named '{f}' in '{f}'", .{
2667025736 field_name.fmt(ip), child_type.fmt(pt),
2667125737 });
26672 },
26673 .inferred_error_set_type => {
26674 return sema.fail(block, src, "TODO handle inferred error sets here", .{});
26675 },
25738 } else child_type,
2667625739 .simple_type => |t| {
2667725740 assert(t == .anyerror);
2667825741 _ = try pt.getErrorValue(field_name);
25742 break :err_set try pt.singleErrorSetType(field_name);
2667925743 },
2668025744 else => unreachable,
26681 }
26682
26683 const error_set_type = if (!child_type.isAnyError(zcu))
26684 child_type
26685 else
26686 try pt.singleErrorSetType(field_name);
26687 return Air.internedToRef((try pt.intern(.{ .err = .{
26688 .ty = error_set_type.toIntern(),
25745 };
25746 return .fromIntern(try pt.intern(.{ .err = .{
25747 .ty = err_set_ty.toIntern(),
2668925748 .name = field_name,
26690 } })));
25749 } }));
2669125750 },
2669225751 .@"union" => {
2669325752 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
2669425753 return inst;
2669525754 }
26696 try child_type.resolveFields(pt);
25755 try sema.ensureLayoutResolved(child_type, src, .field_used);
2669725756 if (child_type.unionTagType(zcu)) |enum_ty| {
2669825757 if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index_usize| {
2669925758 const field_index: u32 = @intCast(field_index_usize);
......@@ -26706,6 +25765,7 @@ fn fieldVal(
2670625765 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
2670725766 return inst;
2670825767 }
25768 try sema.ensureLayoutResolved(child_type, src, .field_used);
2670925769 const field_index_usize = child_type.enumFieldIndex(field_name, zcu) orelse
2671025770 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
2671125771 const field_index: u32 = @intCast(field_index_usize);
......@@ -26731,13 +25791,15 @@ fn fieldVal(
2673125791 },
2673225792 .@"struct" => if (is_pointer_to) {
2673325793 // Avoid loading the entire struct by fetching a pointer and loading that
26734 const field_ptr = try sema.structFieldPtr(block, src, object, field_name, field_name_src, inner_ty, false);
25794 try sema.ensureLayoutResolved(inner_ty, src, .ptr_access);
25795 const field_ptr = try sema.structFieldPtr(block, src, object, field_name, field_name_src, inner_ty);
2673525796 return sema.analyzeLoad(block, src, field_ptr, object_src);
2673625797 } else {
2673725798 return sema.structFieldVal(block, object, field_name, field_name_src, inner_ty);
2673825799 },
2673925800 .@"union" => if (is_pointer_to) {
2674025801 // Avoid loading the entire union by fetching a pointer and loading that
25802 try sema.ensureLayoutResolved(inner_ty, src, .ptr_access);
2674125803 const field_ptr = try sema.unionFieldPtr(block, src, object, field_name, field_name_src, inner_ty, false);
2674225804 return sema.analyzeLoad(block, src, field_ptr, object_src);
2674325805 } else {
......@@ -26784,10 +25846,10 @@ fn fieldPtr(
2678425846 .array => {
2678525847 if (field_name.eqlSlice("len", ip)) {
2678625848 const int_val = try pt.intValue(.usize, inner_ty.arrayLen(zcu));
26787 return uavRef(sema, int_val.toIntern());
25849 return uavRef(sema, int_val);
2678825850 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
2678925851 const ptr_info = object_ty.ptrInfo(zcu);
26790 const new_ptr_ty = try pt.ptrTypeSema(.{
25852 const new_ptr_ty = try pt.ptrType(.{
2679125853 .child = Type.fromInterned(ptr_info.child).childType(zcu).toIntern(),
2679225854 .sentinel = if (inner_ty.sentinel(zcu)) |s| s.toIntern() else .none,
2679325855 .flags = .{
......@@ -26802,10 +25864,11 @@ fn fieldPtr(
2680225864 .packed_offset = ptr_info.packed_offset,
2680325865 });
2680425866 const ptr_ptr_info = object_ptr_ty.ptrInfo(zcu);
26805 const result_ty = try pt.ptrTypeSema(.{
25867 const result_ty = try pt.ptrType(.{
2680625868 .child = new_ptr_ty.toIntern(),
2680725869 .sentinel = if (object_ptr_ty.sentinel(zcu)) |s| s.toIntern() else .none,
2680825870 .flags = .{
25871 .size = .one,
2680925872 .alignment = ptr_ptr_info.flags.alignment,
2681025873 .is_const = ptr_ptr_info.flags.is_const,
2681125874 .is_volatile = ptr_ptr_info.flags.is_volatile,
......@@ -26836,7 +25899,7 @@ fn fieldPtr(
2683625899 if (field_name.eqlSlice("ptr", ip)) {
2683725900 const slice_ptr_ty = inner_ty.slicePtrFieldType(zcu);
2683825901
26839 const result_ty = try pt.ptrTypeSema(.{
25902 const result_ty = try pt.ptrType(.{
2684025903 .child = slice_ptr_ty.toIntern(),
2684125904 .flags = .{
2684225905 .is_const = !attr_ptr_ty.ptrIsMutable(zcu),
......@@ -26854,7 +25917,7 @@ fn fieldPtr(
2685425917 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);
2685525918 return field_ptr;
2685625919 } else if (field_name.eqlSlice("len", ip)) {
26857 const result_ty = try pt.ptrTypeSema(.{
25920 const result_ty = try pt.ptrType(.{
2685825921 .child = .usize_type,
2685925922 .flags = .{
2686025923 .is_const = !attr_ptr_ty.ptrIsMutable(zcu),
......@@ -26881,7 +25944,6 @@ fn fieldPtr(
2688125944 }
2688225945 },
2688325946 .type => {
26884 _ = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, object_ptr, undefined);
2688525947 const result = try sema.analyzeLoad(block, src, object_ptr, object_ptr_src);
2688625948 const inner = if (is_pointer_to)
2688725949 try sema.analyzeLoad(block, src, result, object_ptr_src)
......@@ -26893,44 +25955,39 @@ fn fieldPtr(
2689325955
2689425956 switch (child_type.zigTypeTag(zcu)) {
2689525957 .error_set => {
26896 switch (ip.indexToKey(child_type.toIntern())) {
26897 .error_set_type => |error_set_type| blk: {
26898 if (error_set_type.nameIndex(ip, field_name) != null) {
26899 break :blk;
26900 }
25958 const err_set_ty: Type = err_set: switch (ip.indexToKey(child_type.toIntern())) {
25959 .inferred_error_set_type => |func_index| {
25960 try sema.ensureFuncIesResolved(block, src, func_index);
25961 const resolved_ies = ip.funcIesResolvedUnordered(func_index);
25962 continue :err_set ip.indexToKey(resolved_ies);
25963 },
25964 .error_set_type => |err_set| if (err_set.nameIndex(ip, field_name) == null) {
2690125965 return sema.fail(block, src, "no error named '{f}' in '{f}'", .{
2690225966 field_name.fmt(ip), child_type.fmt(pt),
2690325967 });
26904 },
26905 .inferred_error_set_type => {
26906 return sema.fail(block, src, "TODO handle inferred error sets here", .{});
26907 },
25968 } else child_type,
2690825969 .simple_type => |t| {
2690925970 assert(t == .anyerror);
2691025971 _ = try pt.getErrorValue(field_name);
25972 break :err_set try pt.singleErrorSetType(field_name);
2691125973 },
2691225974 else => unreachable,
26913 }
26914
26915 const error_set_type = if (!child_type.isAnyError(zcu))
26916 child_type
26917 else
26918 try pt.singleErrorSetType(field_name);
26919 return uavRef(sema, try pt.intern(.{ .err = .{
26920 .ty = error_set_type.toIntern(),
25975 };
25976 return uavRef(sema, .fromInterned(try pt.intern(.{ .err = .{
25977 .ty = err_set_ty.toIntern(),
2692125978 .name = field_name,
26922 } }));
25979 } })));
2692325980 },
2692425981 .@"union" => {
2692525982 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
2692625983 return inst;
2692725984 }
26928 try child_type.resolveFields(pt);
25985 try sema.ensureLayoutResolved(child_type, src, .field_used);
2692925986 if (child_type.unionTagType(zcu)) |enum_ty| {
2693025987 if (enum_ty.enumFieldIndex(field_name, zcu)) |field_index| {
2693125988 const field_index_u32: u32 = @intCast(field_index);
2693225989 const idx_val = try pt.enumValueFieldIndex(enum_ty, field_index_u32);
26933 return uavRef(sema, idx_val.toIntern());
25990 return uavRef(sema, idx_val);
2693425991 }
2693525992 }
2693625993 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
......@@ -26939,12 +25996,13 @@ fn fieldPtr(
2693925996 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
2694025997 return inst;
2694125998 }
25999 try sema.ensureLayoutResolved(child_type, src, .field_used);
2694226000 const field_index = child_type.enumFieldIndex(field_name, zcu) orelse {
2694326001 return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name);
2694426002 };
2694526003 const field_index_u32: u32 = @intCast(field_index);
2694626004 const idx_val = try pt.enumValueFieldIndex(child_type, field_index_u32);
26947 return uavRef(sema, idx_val.toIntern());
26005 return uavRef(sema, idx_val);
2694826006 },
2694926007 .@"struct", .@"opaque" => {
2695026008 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(zcu), field_name)) |inst| {
......@@ -26960,7 +26018,8 @@ fn fieldPtr(
2696026018 try sema.analyzeLoad(block, src, object_ptr, object_ptr_src)
2696126019 else
2696226020 object_ptr;
26963 const field_ptr = try sema.structFieldPtr(block, src, inner_ptr, field_name, field_name_src, inner_ty, initializing);
26021 try sema.ensureLayoutResolved(inner_ty, src, .ptr_access);
26022 const field_ptr = try sema.structFieldPtr(block, src, inner_ptr, field_name, field_name_src, inner_ty);
2696426023 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);
2696526024 return field_ptr;
2696626025 },
......@@ -26969,6 +26028,7 @@ fn fieldPtr(
2696926028 try sema.analyzeLoad(block, src, object_ptr, object_ptr_src)
2697026029 else
2697126030 object_ptr;
26031 try sema.ensureLayoutResolved(inner_ty, src, .ptr_access);
2697226032 const field_ptr = try sema.unionFieldPtr(block, src, inner_ptr, field_name, field_name_src, inner_ty, initializing);
2697326033 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);
2697426034 return field_ptr;
......@@ -27012,6 +26072,7 @@ fn fieldCallBind(
2701226072 // Optionally dereference a second pointer to get the concrete type.
2701326073 const is_double_ptr = inner_ty.zigTypeTag(zcu) == .pointer and inner_ty.ptrSize(zcu) == .one;
2701426074 const concrete_ty = if (is_double_ptr) inner_ty.childType(zcu) else inner_ty;
26075 try sema.ensureLayoutResolved(concrete_ty, src, .ptr_access);
2701526076 const ptr_ty = if (is_double_ptr) inner_ty else raw_ptr_ty;
2701626077 const object_ptr = if (is_double_ptr)
2701726078 try sema.analyzeLoad(block, src, raw_ptr, src)
......@@ -27021,10 +26082,8 @@ fn fieldCallBind(
2702126082 find_field: {
2702226083 switch (concrete_ty.zigTypeTag(zcu)) {
2702326084 .@"struct" => {
27024 try concrete_ty.resolveFields(pt);
2702526085 if (zcu.typeToStruct(concrete_ty)) |struct_type| {
27026 const field_index = struct_type.nameIndex(ip, field_name) orelse
27027 break :find_field;
26086 const field_index = struct_type.nameIndex(ip, field_name) orelse break :find_field;
2702826087 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
2702926088
2703026089 return sema.finishFieldCallBind(block, src, ptr_ty, field_ty, field_index, object_ptr);
......@@ -27047,9 +26106,9 @@ fn fieldCallBind(
2704726106 }
2704826107 },
2704926108 .@"union" => {
27050 try concrete_ty.resolveFields(pt);
2705126109 const union_obj = zcu.typeToUnion(concrete_ty).?;
27052 _ = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse break :find_field;
26110 const enum_obj = ip.loadEnumType(union_obj.enum_tag_type);
26111 if (enum_obj.nameIndex(ip, field_name) == null) break :find_field;
2705326112 const field_ptr = try unionFieldPtr(sema, block, src, object_ptr, field_name, field_name_src, concrete_ty, false);
2705426113 return .{ .direct = try sema.analyzeLoad(block, src, field_ptr, src) };
2705526114 },
......@@ -27163,7 +26222,7 @@ fn finishFieldCallBind(
2716326222) CompileError!ResolvedFieldCallee {
2716426223 const pt = sema.pt;
2716526224 const zcu = pt.zcu;
27166 const ptr_field_ty = try pt.ptrTypeSema(.{
26225 const ptr_field_ty = try pt.ptrType(.{
2716726226 .child = field_ty.toIntern(),
2716826227 .flags = .{
2716926228 .is_const = !ptr_ty.ptrIsMutable(zcu),
......@@ -27174,7 +26233,6 @@ fn finishFieldCallBind(
2717426233 const container_ty = ptr_ty.childType(zcu);
2717526234 if (container_ty.zigTypeTag(zcu) == .@"struct") {
2717626235 if (container_ty.structFieldIsComptime(field_index, zcu)) {
27177 try container_ty.resolveStructFieldInits(pt);
2717826236 const default_val = (try container_ty.structFieldValueComptime(pt, field_index)).?;
2717926237 return .{ .direct = Air.internedToRef(default_val.toIntern()) };
2718026238 }
......@@ -27239,6 +26297,7 @@ fn namespaceLookupVal(
2723926297 return try sema.analyzeNavVal(block, src, nav);
2724026298}
2724126299
26300/// Asserts that the layout of `struct_ty` is already resolved.
2724226301fn structFieldPtr(
2724326302 sema: *Sema,
2724426303 block: *Block,
......@@ -27247,33 +26306,33 @@ fn structFieldPtr(
2724726306 field_name: InternPool.NullTerminatedString,
2724826307 field_name_src: LazySrcLoc,
2724926308 struct_ty: Type,
27250 initializing: bool,
2725126309) CompileError!Air.Inst.Ref {
2725226310 const pt = sema.pt;
2725326311 const zcu = pt.zcu;
2725426312 const ip = &zcu.intern_pool;
27255 assert(struct_ty.zigTypeTag(zcu) == .@"struct");
2725626313
27257 try struct_ty.resolveFields(pt);
27258 try struct_ty.resolveLayout(pt);
26314 assert(struct_ty.zigTypeTag(zcu) == .@"struct");
26315 struct_ty.assertHasLayout(zcu);
2725926316
27260 if (struct_ty.isTuple(zcu)) {
26317 const field_index: u32 = if (struct_ty.isTuple(zcu)) field_index: {
2726126318 if (field_name.eqlSlice("len", ip)) {
2726226319 const len_inst = try pt.intRef(.usize, struct_ty.structFieldCount(zcu));
27263 return sema.analyzeRef(block, src, len_inst);
26320 return sema.analyzeRef(block, src, len_inst, .none);
2726426321 }
27265 const field_index = try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src);
27266 return sema.tupleFieldPtr(block, src, struct_ptr, field_name_src, field_index, initializing);
27267 }
27268
27269 const struct_type = zcu.typeToStruct(struct_ty).?;
27270
27271 const field_index = struct_type.nameIndex(ip, field_name) orelse
27272 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);
26322 break :field_index try sema.tupleFieldIndex(block, struct_ty, field_name, field_name_src);
26323 } else field_index: {
26324 const struct_type = zcu.typeToStruct(struct_ty).?;
26325 break :field_index struct_type.nameIndex(ip, field_name) orelse {
26326 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);
26327 };
26328 };
2727326329
2727426330 return sema.structFieldPtrByIndex(block, src, struct_ptr, field_index, struct_ty);
2727526331}
2727626332
26333/// Supports both structs and unions.
26334///
26335/// Asserts that the layout of `struct_ty` is already resolved.
2727726336fn structFieldPtrByIndex(
2727826337 sema: *Sema,
2727926338 block: *Block,
......@@ -27284,79 +26343,24 @@ fn structFieldPtrByIndex(
2728426343) CompileError!Air.Inst.Ref {
2728526344 const pt = sema.pt;
2728626345 const zcu = pt.zcu;
27287 const ip = &zcu.intern_pool;
27288
27289 const struct_type = zcu.typeToStruct(struct_ty).?;
27290 const field_is_comptime = struct_type.fieldIsComptime(ip, field_index);
2729126346
27292 // Comptime fields are handled later
27293 if (!field_is_comptime) {
27294 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
27295 const val = try struct_ptr_val.ptrField(field_index, pt);
27296 return Air.internedToRef(val.toIntern());
27297 }
27298 }
27299
27300 const field_ty = struct_type.field_types.get(ip)[field_index];
26347 struct_ty.assertHasLayout(zcu);
2730126348 const struct_ptr_ty = sema.typeOf(struct_ptr);
27302 const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(zcu);
27303
27304 var ptr_ty_data: InternPool.Key.PtrType = .{
27305 .child = field_ty,
27306 .flags = .{
27307 .is_const = struct_ptr_ty_info.flags.is_const,
27308 .is_volatile = struct_ptr_ty_info.flags.is_volatile,
27309 .address_space = struct_ptr_ty_info.flags.address_space,
27310 },
27311 };
2731226349
27313 const parent_align = if (struct_ptr_ty_info.flags.alignment != .none)
27314 struct_ptr_ty_info.flags.alignment
27315 else
27316 try Type.fromInterned(struct_ptr_ty_info.child).abiAlignmentSema(pt);
27317
27318 if (struct_type.layout == .@"packed") {
27319 assert(!field_is_comptime);
27320 const packed_offset = struct_ty.packedStructFieldPtrInfo(struct_ptr_ty, field_index, pt);
27321 ptr_ty_data.flags.alignment = parent_align;
27322 ptr_ty_data.packed_offset = packed_offset;
27323 } else if (struct_type.layout == .@"extern") {
27324 assert(!field_is_comptime);
27325 // For extern structs, field alignment might be bigger than type's
27326 // natural alignment. Eg, in `extern struct { x: u32, y: u16 }` the
27327 // second field is aligned as u32.
27328 const field_offset = struct_ty.structFieldOffset(field_index, zcu);
27329 ptr_ty_data.flags.alignment = if (parent_align == .none)
27330 .none
27331 else
27332 @enumFromInt(@min(@intFromEnum(parent_align), @ctz(field_offset)));
26350 if (struct_ty.structFieldIsComptime(field_index, zcu)) {
26351 const field_ptr_ty = try struct_ptr_ty.fieldPtrType(field_index, pt);
26352 return .fromIntern(try pt.intern(.{ .ptr = .{
26353 .ty = field_ptr_ty.toIntern(),
26354 .base_addr = .{ .comptime_field = struct_ty.structFieldDefaultValue(field_index, zcu).?.toIntern() },
26355 .byte_offset = 0,
26356 } }));
26357 } else if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
26358 return .fromValue(try struct_ptr_val.ptrField(field_index, pt));
2733326359 } else {
27334 // Our alignment is capped at the field alignment.
27335 const field_align = try Type.fromInterned(field_ty).structFieldAlignmentSema(
27336 struct_type.fieldAlign(ip, field_index),
27337 struct_type.layout,
27338 pt,
27339 );
27340 ptr_ty_data.flags.alignment = if (struct_ptr_ty_info.flags.alignment == .none)
27341 field_align
27342 else
27343 field_align.min(parent_align);
26360 const field_ptr_ty = try struct_ptr_ty.fieldPtrType(field_index, pt);
26361 return block.addStructFieldPtr(struct_ptr, field_index, field_ptr_ty);
2734426362 }
27345
27346 const ptr_field_ty = try pt.ptrTypeSema(ptr_ty_data);
27347
27348 if (field_is_comptime) {
27349 try struct_ty.resolveStructFieldInits(pt);
27350 const val = try pt.intern(.{ .ptr = .{
27351 .ty = ptr_field_ty.toIntern(),
27352 .base_addr = .{ .comptime_field = struct_type.field_inits.get(ip)[field_index] },
27353 .byte_offset = 0,
27354 } });
27355 return Air.internedToRef(val);
27356 }
27357
27358 return block.addStructFieldPtr(struct_ptr, field_index, ptr_field_ty);
27359}
26363}
2736026364
2736126365fn structFieldVal(
2736226366 sema: *Sema,
......@@ -27370,8 +26374,8 @@ fn structFieldVal(
2737026374 const zcu = pt.zcu;
2737126375 const ip = &zcu.intern_pool;
2737226376 assert(struct_ty.zigTypeTag(zcu) == .@"struct");
27373
27374 try struct_ty.resolveFields(pt);
26377 assert(sema.typeOf(struct_byval).toIntern() == struct_ty.toIntern());
26378 struct_ty.assertHasLayout(zcu);
2737526379
2737626380 switch (ip.indexToKey(struct_ty.toIntern())) {
2737726381 .struct_type => {
......@@ -27379,24 +26383,19 @@ fn structFieldVal(
2737926383
2738026384 const field_index = struct_type.nameIndex(ip, field_name) orelse
2738126385 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);
27382 if (struct_type.fieldIsComptime(ip, field_index)) {
27383 try struct_ty.resolveStructFieldInits(pt);
27384 return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]);
26386 if (struct_type.field_is_comptime_bits.get(ip, field_index)) {
26387 return .fromIntern(struct_type.field_defaults.get(ip)[field_index]);
2738526388 }
2738626389
2738726390 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
27388 if (try sema.typeHasOnePossibleValue(field_ty)) |field_val|
27389 return Air.internedToRef(field_val.toIntern());
26391 if (try field_ty.onePossibleValue(pt)) |field_val|
26392 return .fromValue(field_val);
2739026393
27391 if (try sema.resolveValue(struct_byval)) |struct_val| {
26394 if (sema.resolveValue(struct_byval)) |struct_val| {
2739226395 if (struct_val.isUndef(zcu)) return pt.undefRef(field_ty);
27393 if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| {
27394 return Air.internedToRef(opv.toIntern());
27395 }
27396 return Air.internedToRef((try struct_val.fieldValue(pt, field_index)).toIntern());
26396 return .fromValue(try struct_val.fieldValue(pt, field_index));
2739726397 }
2739826398
27399 try field_ty.resolveLayout(pt);
2740026399 return block.addStructFieldVal(struct_byval, field_index, field_ty);
2740126400 },
2740226401 .tuple_type => {
......@@ -27457,16 +26456,13 @@ fn tupleFieldValByIndex(
2745726456 const zcu = pt.zcu;
2745826457 const field_ty = tuple_ty.fieldType(field_index, zcu);
2745926458
27460 if (tuple_ty.structFieldIsComptime(field_index, zcu))
27461 try tuple_ty.resolveStructFieldInits(pt);
2746226459 if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_value| {
2746326460 return Air.internedToRef(default_value.toIntern());
2746426461 }
2746526462
27466 if (try sema.resolveValue(tuple_byval)) |tuple_val| {
27467 if ((try sema.typeHasOnePossibleValue(field_ty))) |opv| {
27468 return Air.internedToRef(opv.toIntern());
27469 }
26463 if (try field_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
26464
26465 if (sema.resolveValue(tuple_byval)) |tuple_val| {
2747026466 return switch (zcu.intern_pool.indexToKey(tuple_val.toIntern())) {
2747126467 .undef => pt.undefRef(field_ty),
2747226468 .aggregate => |aggregate| Air.internedToRef(switch (aggregate.storage) {
......@@ -27478,10 +26474,10 @@ fn tupleFieldValByIndex(
2747826474 };
2747926475 }
2748026476
27481 try field_ty.resolveLayout(pt);
2748226477 return block.addStructFieldVal(tuple_byval, field_index, field_ty);
2748326478}
2748426479
26480/// Asserts that the layout of `union_ty` is already resolved.
2748526481fn unionFieldPtr(
2748626482 sema: *Sema,
2748726483 block: *Block,
......@@ -27497,35 +26493,17 @@ fn unionFieldPtr(
2749726493 const ip = &zcu.intern_pool;
2749826494
2749926495 assert(union_ty.zigTypeTag(zcu) == .@"union");
26496 union_ty.assertHasLayout(zcu);
2750026497
27501 const union_ptr_ty = sema.typeOf(union_ptr);
27502 const union_ptr_info = union_ptr_ty.ptrInfo(zcu);
27503 try union_ty.resolveFields(pt);
2750426498 const union_obj = zcu.typeToUnion(union_ty).?;
26499 const tag_ty: Type = .fromInterned(union_obj.enum_tag_type);
26500
2750526501 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
2750626502 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);
27507 const ptr_field_ty = try pt.ptrTypeSema(.{
27508 .child = field_ty.toIntern(),
27509 .flags = .{
27510 .is_const = union_ptr_info.flags.is_const,
27511 .is_volatile = union_ptr_info.flags.is_volatile,
27512 .address_space = union_ptr_info.flags.address_space,
27513 .alignment = if (union_obj.flagsUnordered(ip).layout == .auto) blk: {
27514 const union_align = if (union_ptr_info.flags.alignment != .none)
27515 union_ptr_info.flags.alignment
27516 else
27517 try union_ty.abiAlignmentSema(pt);
27518 const field_align = try union_ty.fieldAlignmentSema(field_index, pt);
27519 break :blk union_align.min(field_align);
27520 } else union_ptr_info.flags.alignment,
27521 },
27522 .packed_offset = union_ptr_info.packed_offset,
27523 });
27524 const enum_field_index: u32 = @intCast(Type.fromInterned(union_obj.enum_tag_ty).enumFieldIndex(field_name, zcu).?);
2752526503
27526 if (initializing and field_ty.zigTypeTag(zcu) == .noreturn) {
26504 if (initializing and field_ty.classify(zcu) == .no_possible_value) {
2752726505 const msg = msg: {
27528 const msg = try sema.errMsg(src, "cannot initialize 'noreturn' field of union", .{});
26506 const msg = try sema.errMsg(src, "cannot initialize union field with uninstantiable type '{f}'", .{field_ty.fmt(pt)});
2752926507 errdefer msg.destroy(sema.gpa);
2753026508
2753126509 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{f}' declared here", .{
......@@ -27538,30 +26516,24 @@ fn unionFieldPtr(
2753826516 }
2753926517
2754026518 if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| ct: {
27541 switch (union_obj.flagsUnordered(ip).layout) {
26519 switch (union_obj.layout) {
2754226520 .auto => if (initializing) {
2754326521 if (!sema.isComptimeMutablePtr(union_ptr_val)) {
2754426522 // The initialization is a runtime operation.
2754526523 break :ct;
2754626524 }
2754726525 // Store to the union to initialize the tag.
27548 const field_tag = try pt.enumValueFieldIndex(.fromInterned(union_obj.enum_tag_ty), enum_field_index);
27549 const payload_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);
27550 const new_union_val = try pt.unionValue(union_ty, field_tag, try pt.undefValue(payload_ty));
26526 const field_tag = try pt.enumValueFieldIndex(tag_ty, field_index);
26527 const payload_val = try field_ty.onePossibleValue(pt) orelse try pt.undefValue(field_ty);
26528 const new_union_val = try pt.unionValue(union_ty, field_tag, payload_val);
2755126529 try sema.storePtrVal(block, src, union_ptr_val, new_union_val, union_ty);
2755226530 } else {
27553 const union_val = (try sema.pointerDeref(block, src, union_ptr_val, union_ptr_ty)) orelse
27554 break :ct;
27555 if (union_val.isUndef(zcu)) {
27556 return sema.failWithUseOfUndef(block, src, null);
27557 }
27558 const un = ip.indexToKey(union_val.toIntern()).un;
27559 const field_tag = try pt.enumValueFieldIndex(.fromInterned(union_obj.enum_tag_ty), enum_field_index);
27560 const tag_matches = un.tag == field_tag.toIntern();
27561 if (!tag_matches) {
26531 const union_val = try sema.pointerDeref(block, src, union_ptr_val, union_ptr_val.typeOf(zcu)) orelse break :ct;
26532 if (union_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, src, null);
26533 const active_index = tag_ty.enumTagFieldIndex(union_val.unionTag(zcu).?, zcu).?;
26534 if (active_index != field_index) {
2756226535 const msg = msg: {
27563 const active_index = Type.fromInterned(union_obj.enum_tag_ty).enumTagFieldIndex(Value.fromInterned(un.tag), zcu).?;
27564 const active_field_name = Type.fromInterned(union_obj.enum_tag_ty).enumFieldName(active_index, zcu);
26536 const active_field_name = tag_ty.enumFieldName(active_index, zcu);
2756526537 const msg = try sema.errMsg(src, "access of union field '{f}' while field '{f}' is active", .{
2756626538 field_name.fmt(ip),
2756726539 active_field_name.fmt(ip),
......@@ -27575,34 +26547,34 @@ fn unionFieldPtr(
2757526547 },
2757626548 .@"packed", .@"extern" => {},
2757726549 }
27578 const field_ptr_val = try union_ptr_val.ptrField(field_index, pt);
27579 return Air.internedToRef(field_ptr_val.toIntern());
26550 return .fromValue(try union_ptr_val.ptrField(field_index, pt));
2758026551 }
2758126552
2758226553 // If the union has a tag, we must either set or or safety check it depending on `initializing`.
2758326554 tag: {
2758426555 if (union_ty.containerLayout(zcu) != .auto) break :tag;
27585 const tag_ty: Type = .fromInterned(union_obj.enum_tag_ty);
27586 if (try sema.typeHasOnePossibleValue(tag_ty) != null) break :tag;
26556 if (tag_ty.classify(zcu) == .one_possible_value) break :tag;
2758726557 // There is a hypothetical non-trivial tag. We must set it even if not there at runtime, but
2758826558 // only emit a safety check if it's available at runtime (i.e. it's safety-tagged).
27589 const want_tag = try pt.enumValueFieldIndex(tag_ty, enum_field_index);
26559 const want_tag = try pt.enumValueFieldIndex(tag_ty, field_index);
2759026560 if (initializing) {
2759126561 const set_tag_inst = try block.addBinOp(.set_union_tag, union_ptr, .fromValue(want_tag));
2759226562 try sema.checkComptimeKnownStore(block, set_tag_inst, .unneeded); // `unneeded` since this isn't a "proper" store
27593 } else if (block.wantSafety() and union_obj.hasTag(ip)) {
27594 // The tag exists at runtime (safety tag), so emit a safety check.
26563 } else if (block.wantSafety() and union_obj.has_runtime_tag) {
26564 // The tag exists at runtime (actual or safety tag), so emit a safety check.
2759526565 // TODO would it be better if get_union_tag supported pointers to unions?
2759626566 const union_val = try block.addTyOp(.load, union_ty, union_ptr);
2759726567 const active_tag = try block.addTyOp(.get_union_tag, tag_ty, union_val);
2759826568 try sema.addSafetyCheckInactiveUnionField(block, src, active_tag, .fromValue(want_tag));
2759926569 }
2760026570 }
27601 if (field_ty.zigTypeTag(zcu) == .noreturn) {
26571 if (field_ty.classify(zcu) == .no_possible_value) {
2760226572 _ = try block.addNoOp(.unreach);
2760326573 return .unreachable_value;
2760426574 }
27605 return block.addStructFieldPtr(union_ptr, field_index, ptr_field_ty);
26575
26576 const field_ptr_ty = try sema.typeOf(union_ptr).fieldPtrType(field_index, pt);
26577 return block.addStructFieldPtr(union_ptr, field_index, field_ptr_ty);
2760626578}
2760726579
2760826580fn unionFieldVal(
......@@ -27618,71 +26590,57 @@ fn unionFieldVal(
2761826590 const zcu = pt.zcu;
2761926591 const ip = &zcu.intern_pool;
2762026592 assert(union_ty.zigTypeTag(zcu) == .@"union");
26593 assert(sema.typeOf(union_byval).toIntern() == union_ty.toIntern());
26594 union_ty.assertHasLayout(zcu);
2762126595
27622 try union_ty.resolveFields(pt);
2762326596 const union_obj = zcu.typeToUnion(union_ty).?;
2762426597 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
2762526598 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);
27626 const enum_field_index: u32 = @intCast(Type.fromInterned(union_obj.enum_tag_ty).enumFieldIndex(field_name, zcu).?);
26599 const enum_tag_ty: Type = .fromInterned(union_obj.enum_tag_type);
2762726600
27628 if (try sema.resolveValue(union_byval)) |union_val| {
26601 if (sema.resolveValue(union_byval)) |union_val| {
2762926602 if (union_val.isUndef(zcu)) return pt.undefRef(field_ty);
27630
27631 const un = ip.indexToKey(union_val.toIntern()).un;
27632 const field_tag = try pt.enumValueFieldIndex(.fromInterned(union_obj.enum_tag_ty), enum_field_index);
27633 const tag_matches = un.tag == field_tag.toIntern();
27634 switch (union_obj.flagsUnordered(ip).layout) {
26603 switch (union_obj.layout) {
2763526604 .auto => {
27636 if (tag_matches) {
27637 return Air.internedToRef(un.val);
27638 } else {
27639 const msg = msg: {
27640 const active_index = Type.fromInterned(union_obj.enum_tag_ty).enumTagFieldIndex(Value.fromInterned(un.tag), zcu).?;
27641 const active_field_name = Type.fromInterned(union_obj.enum_tag_ty).enumFieldName(active_index, zcu);
27642 const msg = try sema.errMsg(src, "access of union field '{f}' while field '{f}' is active", .{
27643 field_name.fmt(ip), active_field_name.fmt(ip),
27644 });
27645 errdefer msg.destroy(sema.gpa);
27646 try sema.addDeclaredHereNote(msg, union_ty);
27647 break :msg msg;
27648 };
27649 return sema.failWithOwnedErrorMsg(block, msg);
27650 }
26605 const active_tag_val = union_val.unionTag(zcu).?;
26606 const active_index = enum_tag_ty.enumTagFieldIndex(active_tag_val, zcu).?;
26607 if (active_index == field_index) return .fromValue(union_val.unionPayload(zcu));
26608 return sema.failWithOwnedErrorMsg(block, msg: {
26609 const msg = try sema.errMsg(src, "access of union field '{f}' while field '{f}' is active", .{
26610 field_name.fmt(ip), enum_tag_ty.enumFieldName(active_index, zcu).fmt(ip),
26611 });
26612 errdefer msg.destroy(zcu.comp.gpa);
26613 try sema.addDeclaredHereNote(msg, union_ty);
26614 break :msg msg;
26615 });
2765126616 },
27652 .@"extern" => if (tag_matches) {
27653 // Fast path - no need to use bitcast logic.
27654 return Air.internedToRef(un.val);
27655 } else if (try sema.bitCastVal(union_val, field_ty, 0, 0, 0)) |field_val| {
27656 return Air.internedToRef(field_val.toIntern());
26617 .@"extern" => if (try sema.bitCastVal(union_val, field_ty, 0, 0, 0)) |field_val| {
26618 return .fromValue(field_val);
26619 } else {
26620 // Runtime-known due to a pointer-to-integer conversion.
2765726621 },
27658 .@"packed" => if (tag_matches) {
27659 // Fast path - no need to use bitcast logic.
27660 return Air.internedToRef(un.val);
27661 } else if (try sema.bitCastVal(union_val, field_ty, 0, try union_ty.bitSizeSema(pt), 0)) |field_val| {
27662 return Air.internedToRef(field_val.toIntern());
26622 .@"packed" => {
26623 const field_val = try sema.bitCastVal(union_val, field_ty, 0, union_ty.bitSize(zcu), 0) orelse {
26624 unreachable; // `null` is only possible if the input value contains a pointer, which a packed union cannot.
26625 };
26626 return .fromValue(field_val);
2766326627 },
2766426628 }
2766526629 }
2766626630
27667 if (union_obj.flagsUnordered(ip).layout == .auto and block.wantSafety() and
27668 union_ty.unionTagTypeSafety(zcu) != null and union_obj.field_types.len > 1)
27669 {
27670 const wanted_tag_val = try pt.enumValueFieldIndex(.fromInterned(union_obj.enum_tag_ty), enum_field_index);
27671 const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern());
27672 const active_tag = try block.addTyOp(.get_union_tag, .fromInterned(union_obj.enum_tag_ty), union_byval);
27673 try sema.addSafetyCheckInactiveUnionField(block, src, active_tag, wanted_tag);
26631 if (union_obj.layout == .auto and block.wantSafety() and union_obj.has_runtime_tag) {
26632 const wanted_tag_val = try pt.enumValueFieldIndex(enum_tag_ty, field_index);
26633 const active_tag = try block.addTyOp(.get_union_tag, enum_tag_ty, union_byval);
26634 try sema.addSafetyCheckInactiveUnionField(block, src, active_tag, .fromValue(wanted_tag_val));
2767426635 }
2767526636
27676 if (field_ty.zigTypeTag(zcu) == .noreturn) {
26637 if (field_ty.classify(zcu) == .no_possible_value) {
2767726638 _ = try block.addNoOp(.unreach);
2767826639 return .unreachable_value;
2767926640 }
2768026641
27681 if (try sema.typeHasOnePossibleValue(field_ty)) |field_only_value| {
27682 return Air.internedToRef(field_only_value.toIntern());
27683 }
26642 if (try field_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
2768426643
27685 try field_ty.resolveLayout(pt);
2768626644 return block.addStructFieldVal(union_byval, field_index, field_ty);
2768726645}
2768826646
......@@ -27706,17 +26664,15 @@ fn elemPtr(
2770626664 else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{f}'", .{indexable_ptr_ty.fmt(pt)}),
2770726665 };
2770826666 try sema.checkIndexable(block, src, indexable_ty);
26667 try sema.ensureLayoutResolved(indexable_ty, src, .ptr_access);
2770926668
2771026669 const elem_ptr = switch (indexable_ty.zigTypeTag(zcu)) {
27711 .array, .vector => try sema.elemPtrArray(block, src, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init, oob_safety),
27712 .@"struct" => blk: {
27713 // Tuple field access.
27714 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{ .simple = .tuple_field_index });
27715 const index: u32 = @intCast(try index_val.toUnsignedIntSema(pt));
27716 break :blk try sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index, init);
27717 },
26670 .vector => try sema.elemPtrVector(block, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init),
26671 .array => try sema.elemPtrArray(block, src, indexable_ptr_src, indexable_ptr, elem_index_src, elem_index, init, oob_safety),
26672 .@"struct" => try sema.tupleElemPtr(block, src, indexable_ptr, elem_index, elem_index_src),
2771826673 else => {
2771926674 const indexable = try sema.analyzeLoad(block, indexable_ptr_src, indexable_ptr, indexable_ptr_src);
26675 try sema.ensureLayoutResolved(sema.typeOf(indexable).childType(zcu), src, .ptr_access);
2772026676 return elemPtrOneLayerOnly(sema, block, src, indexable, elem_index, elem_index_src, init, oob_safety);
2772126677 },
2772226678 };
......@@ -27725,7 +26681,7 @@ fn elemPtr(
2772526681 return elem_ptr;
2772626682}
2772726683
27728/// Asserts that the type of indexable is pointer.
26684/// Asserts that `indexable` is an indexable pointer whose child type has its layout already resolved.
2772926685fn elemPtrOneLayerOnly(
2773026686 sema: *Sema,
2773126687 block: *Block,
......@@ -27741,28 +26697,31 @@ fn elemPtrOneLayerOnly(
2774126697 const pt = sema.pt;
2774226698 const zcu = pt.zcu;
2774326699
27744 try sema.checkIndexable(block, src, indexable_ty);
26700 assert(indexable_ty.isIndexable(zcu));
26701 assert(indexable_ty.zigTypeTag(zcu) == .pointer);
26702 const child_ty = indexable_ty.childType(zcu);
26703 child_ty.assertHasLayout(zcu);
2774526704
2774626705 switch (indexable_ty.ptrSize(zcu)) {
2774726706 .slice => return sema.elemPtrSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),
2774826707 .many, .c => {
2774926708 const maybe_ptr_val = try sema.resolveDefinedValue(block, indexable_src, indexable);
2775026709 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
26710 const maybe_index: ?u64 = if (maybe_index_val) |val| val.toUnsignedInt(zcu) else null;
2775126711 ct: {
2775226712 const ptr_val = maybe_ptr_val orelse break :ct;
27753 const index_val = maybe_index_val orelse break :ct;
27754 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));
27755 const elem_ptr = try ptr_val.ptrElem(index, pt);
27756 return Air.internedToRef(elem_ptr.toIntern());
26713 const index: usize = @intCast(maybe_index orelse break :ct);
26714 return .fromValue(try ptr_val.ptrElem(index, pt));
2775726715 }
2775826716
2775926717 try sema.checkLogicalPtrOperation(block, src, indexable_ty);
27760 const result_ty = try indexable_ty.elemPtrType(null, pt);
26718
26719 const result_ty = try indexable_ty.elemPtrType(maybe_index, pt);
2776126720
2776226721 try sema.validateRuntimeElemAccess(block, elem_index_src, result_ty, indexable_ty, indexable_src);
2776326722 try sema.validateRuntimeValue(block, indexable_src, indexable);
2776426723
27765 if (!try result_ty.childType(zcu).hasRuntimeBitsIgnoreComptimeSema(pt)) {
26724 if (child_ty.abiSize(zcu) == 0) {
2776626725 // zero-bit child type; just bitcast the pointer
2776726726 return block.addBitCast(result_ty, indexable);
2776826727 }
......@@ -27770,15 +26729,10 @@ fn elemPtrOneLayerOnly(
2777026729 return block.addPtrElemPtr(indexable, elem_index, result_ty);
2777126730 },
2777226731 .one => {
27773 const child_ty = indexable_ty.childType(zcu);
2777426732 const elem_ptr = switch (child_ty.zigTypeTag(zcu)) {
27775 .array, .vector => try sema.elemPtrArray(block, src, indexable_src, indexable, elem_index_src, elem_index, init, oob_safety),
27776 .@"struct" => blk: {
27777 assert(child_ty.isTuple(zcu));
27778 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{ .simple = .tuple_field_index });
27779 const index: u32 = @intCast(try index_val.toUnsignedIntSema(pt));
27780 break :blk try sema.tupleFieldPtr(block, indexable_src, indexable, elem_index_src, index, false);
27781 },
26733 .vector => try sema.elemPtrVector(block, indexable_src, indexable, elem_index_src, elem_index, init),
26734 .array => try sema.elemPtrArray(block, src, indexable_src, indexable, elem_index_src, elem_index, init, oob_safety),
26735 .@"struct" => try sema.tupleElemPtr(block, indexable_src, indexable, elem_index, elem_index_src),
2778226736 else => unreachable, // Guaranteed by checkIndexable
2778326737 };
2778426738 try sema.checkKnownAllocPtr(block, indexable, elem_ptr);
......@@ -27808,45 +26762,51 @@ fn elemVal(
2780826762 const elem_index = try sema.coerce(block, .usize, elem_index_uncasted, elem_index_src);
2780926763
2781026764 switch (indexable_ty.zigTypeTag(zcu)) {
27811 .pointer => switch (indexable_ty.ptrSize(zcu)) {
27812 .slice => return sema.elemValSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),
27813 .many, .c => {
27814 const maybe_indexable_val = try sema.resolveDefinedValue(block, indexable_src, indexable);
27815 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
27816 const elem_ty = indexable_ty.elemType2(zcu);
27817
27818 ct: {
27819 const indexable_val = maybe_indexable_val orelse break :ct;
27820 const index_val = maybe_index_val orelse break :ct;
27821 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));
27822 const many_ptr_ty = try pt.manyConstPtrType(elem_ty);
27823 const many_ptr_val = try pt.getCoerced(indexable_val, many_ptr_ty);
27824 const elem_ptr_ty = try pt.singleConstPtrType(elem_ty);
27825 const elem_ptr_val = try many_ptr_val.ptrElem(index, pt);
27826 const elem_val = try sema.pointerDeref(block, indexable_src, elem_ptr_val, elem_ptr_ty) orelse break :ct;
27827 return Air.internedToRef((try pt.getCoerced(elem_val, elem_ty)).toIntern());
27828 }
26765 .pointer => {
26766 const child_ty = indexable_ty.childType(zcu);
26767 try sema.ensureLayoutResolved(child_ty, src, .ptr_access);
26768 switch (indexable_ty.ptrSize(zcu)) {
26769 .slice => return sema.elemValSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),
26770 .many, .c => {
26771 const maybe_indexable_val = try sema.resolveDefinedValue(block, indexable_src, indexable);
26772 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
26773
26774 ct: {
26775 const indexable_val = maybe_indexable_val orelse break :ct;
26776 const index_val = maybe_index_val orelse break :ct;
26777 const index: usize = @intCast(index_val.toUnsignedInt(zcu));
26778 const many_ptr_ty = try pt.manyConstPtrType(child_ty);
26779 const many_ptr_val = try pt.getCoerced(indexable_val, many_ptr_ty);
26780 const elem_ptr_val = try many_ptr_val.ptrElem(index, pt);
26781 return sema.analyzeLoad(block, src, .fromValue(elem_ptr_val), indexable_src);
26782 }
2782926783
27830 if (try sema.typeHasOnePossibleValue(elem_ty)) |elem_only_value| {
27831 return Air.internedToRef(elem_only_value.toIntern());
27832 }
26784 try sema.validateRuntimeElemAccess(block, elem_index_src, child_ty, indexable_ty, src);
26785 switch (child_ty.classify(zcu)) {
26786 .runtime => {},
26787 .one_possible_value => return .fromValue((try child_ty.onePossibleValue(pt)).?),
26788 .no_possible_value => switch (child_ty.zigTypeTag(zcu)) {
26789 .@"opaque" => return sema.fail(block, src, "cannot load opaque type '{f}'", .{child_ty.fmt(pt)}),
26790 else => return sema.fail(block, src, "cannot load uninstantiable type '{f}'", .{child_ty.fmt(pt)}),
26791 },
26792 .partially_comptime, .fully_comptime => unreachable, // caught by `validateRuntimeElemAccess`
26793 }
2783326794
27834 try sema.checkLogicalPtrOperation(block, src, indexable_ty);
27835 return block.addBinOp(.ptr_elem_val, indexable, elem_index);
27836 },
27837 .one => {
27838 arr_sent: {
27839 const inner_ty = indexable_ty.childType(zcu);
27840 if (inner_ty.zigTypeTag(zcu) != .array) break :arr_sent;
27841 const sentinel = inner_ty.sentinel(zcu) orelse break :arr_sent;
27842 const index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index) orelse break :arr_sent;
27843 const index = try sema.usizeCast(block, src, try index_val.toUnsignedIntSema(pt));
27844 if (index != inner_ty.arrayLen(zcu)) break :arr_sent;
27845 return Air.internedToRef(sentinel.toIntern());
27846 }
27847 const elem_ptr = try sema.elemPtr(block, indexable_src, indexable, elem_index, elem_index_src, false, oob_safety);
27848 return sema.analyzeLoad(block, indexable_src, elem_ptr, elem_index_src);
27849 },
26795 return block.addBinOp(.ptr_elem_val, indexable, elem_index);
26796 },
26797 .one => {
26798 arr_sent: {
26799 if (child_ty.zigTypeTag(zcu) != .array) break :arr_sent;
26800 const sentinel = child_ty.sentinel(zcu) orelse break :arr_sent;
26801 const index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index) orelse break :arr_sent;
26802 const index = try sema.usizeCast(block, src, index_val.toUnsignedInt(zcu));
26803 if (index != child_ty.arrayLen(zcu)) break :arr_sent;
26804 return .fromValue(sentinel);
26805 }
26806 const elem_ptr = try sema.elemPtr(block, indexable_src, indexable, elem_index, elem_index_src, false, oob_safety);
26807 return sema.analyzeLoad(block, indexable_src, elem_ptr, elem_index_src);
26808 },
26809 }
2785026810 },
2785126811 .array => return sema.elemValArray(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety),
2785226812 .vector => {
......@@ -27856,7 +26816,7 @@ fn elemVal(
2785626816 .@"struct" => {
2785726817 // Tuple field access.
2785826818 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{ .simple = .tuple_field_index });
27859 const index: u32 = @intCast(try index_val.toUnsignedIntSema(pt));
26819 const index: u32 = @intCast(index_val.toUnsignedInt(zcu));
2786026820 return sema.tupleField(block, indexable_src, indexable, elem_index_src, index);
2786126821 },
2786226822 else => unreachable,
......@@ -27864,6 +26824,7 @@ fn elemVal(
2786426824}
2786526825
2786626826/// Called when the index or indexable is runtime known.
26827/// Asserts that the layout of `elem_ty` is already resolved.
2786726828fn validateRuntimeElemAccess(
2786826829 sema: *Sema,
2786926830 block: *Block,
......@@ -27875,16 +26836,16 @@ fn validateRuntimeElemAccess(
2787526836 const pt = sema.pt;
2787626837 const zcu = pt.zcu;
2787726838
27878 if (try elem_ty.comptimeOnlySema(sema.pt)) {
26839 if (elem_ty.comptimeOnly(zcu)) {
2787926840 const msg = msg: {
2788026841 const msg = try sema.errMsg(
2788126842 elem_index_src,
2788226843 "values of type '{f}' must be comptime-known, but index value is runtime-known",
27883 .{parent_ty.fmt(sema.pt)},
26844 .{elem_ty.fmt(sema.pt)},
2788426845 );
2788526846 errdefer msg.destroy(sema.gpa);
2788626847
27887 try sema.explainWhyTypeIsComptime(msg, parent_src, parent_ty);
26848 try sema.explainWhyTypeIsComptime(msg, parent_src, elem_ty);
2788826849
2788926850 break :msg msg;
2789026851 };
......@@ -27900,71 +26861,38 @@ fn validateRuntimeElemAccess(
2790026861 }
2790126862}
2790226863
27903fn tupleFieldPtr(
26864/// Validates `elem_index`, and returns a pointer to that field using `structFieldPtrByIndex`.
26865///
26866/// Asserts that the type of `tuple_ptr` is a single-item pointer whose child type is a tuple.
26867fn tupleElemPtr(
2790426868 sema: *Sema,
2790526869 block: *Block,
27906 tuple_ptr_src: LazySrcLoc,
26870 src: LazySrcLoc,
2790726871 tuple_ptr: Air.Inst.Ref,
27908 field_index_src: LazySrcLoc,
27909 field_index: u32,
27910 init: bool,
26872 elem_index: Air.Inst.Ref,
26873 elem_index_src: LazySrcLoc,
2791126874) CompileError!Air.Inst.Ref {
2791226875 const pt = sema.pt;
2791326876 const zcu = pt.zcu;
2791426877 const tuple_ptr_ty = sema.typeOf(tuple_ptr);
27915 const tuple_ptr_info = tuple_ptr_ty.ptrInfo(zcu);
27916 const tuple_ty: Type = .fromInterned(tuple_ptr_info.child);
27917 try tuple_ty.resolveFields(pt);
27918 const field_count = tuple_ty.structFieldCount(zcu);
26878 assert(tuple_ptr_ty.isSinglePointer(zcu));
26879 const tuple_ty = tuple_ptr_ty.childType(zcu);
26880 assert(tuple_ty.isTuple(zcu));
2791926881
26882 const field_count = tuple_ty.structFieldCount(zcu);
2792026883 if (field_count == 0) {
27921 return sema.fail(block, tuple_ptr_src, "indexing into empty tuple is not allowed", .{});
26884 return sema.fail(block, src, "indexing into empty tuple is not allowed", .{});
2792226885 }
2792326886
27924 if (field_index >= field_count) {
27925 return sema.fail(block, field_index_src, "index {d} outside tuple of length {d}", .{
27926 field_index, field_count,
26887 const elem_index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{ .simple = .tuple_field_index });
26888 const index = elem_index_val.getUnsignedInt(zcu);
26889 if (index == null or index.? >= field_count) {
26890 return sema.fail(block, elem_index_src, "index '{f}' out of bounds of tuple '{f}'", .{
26891 elem_index_val.fmtValueSema(pt, sema), tuple_ty.fmt(pt),
2792726892 });
2792826893 }
2792926894
27930 const field_ty = tuple_ty.fieldType(field_index, zcu);
27931 const ptr_field_ty = try pt.ptrTypeSema(.{
27932 .child = field_ty.toIntern(),
27933 .flags = .{
27934 .is_const = tuple_ptr_info.flags.is_const,
27935 .is_volatile = tuple_ptr_info.flags.is_volatile,
27936 .address_space = tuple_ptr_info.flags.address_space,
27937 .alignment = a: {
27938 if (tuple_ptr_info.flags.alignment == .none) break :a .none;
27939 // The tuple pointer isn't naturally aligned, so the field pointer might be underaligned.
27940 const tuple_align = tuple_ptr_info.flags.alignment;
27941 const field_align = try field_ty.abiAlignmentSema(pt);
27942 break :a tuple_align.min(field_align);
27943 },
27944 },
27945 });
27946
27947 if (tuple_ty.structFieldIsComptime(field_index, zcu))
27948 try tuple_ty.resolveStructFieldInits(pt);
27949
27950 if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_val| {
27951 return Air.internedToRef((try pt.intern(.{ .ptr = .{
27952 .ty = ptr_field_ty.toIntern(),
27953 .base_addr = .{ .comptime_field = default_val.toIntern() },
27954 .byte_offset = 0,
27955 } })));
27956 }
27957
27958 if (try sema.resolveValue(tuple_ptr)) |tuple_ptr_val| {
27959 const field_ptr_val = try tuple_ptr_val.ptrField(field_index, pt);
27960 return Air.internedToRef(field_ptr_val.toIntern());
27961 }
27962
27963 if (!init) {
27964 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_ptr_src);
27965 }
27966
27967 return block.addStructFieldPtr(tuple_ptr, field_index, ptr_field_ty);
26895 return sema.structFieldPtrByIndex(block, src, tuple_ptr, @intCast(index.?), tuple_ty);
2796826896}
2796926897
2797026898fn tupleField(
......@@ -27978,7 +26906,6 @@ fn tupleField(
2797826906 const pt = sema.pt;
2797926907 const zcu = pt.zcu;
2798026908 const tuple_ty = sema.typeOf(tuple);
27981 try tuple_ty.resolveFields(pt);
2798226909 const field_count = tuple_ty.structFieldCount(zcu);
2798326910
2798426911 if (field_count == 0) {
......@@ -27993,20 +26920,17 @@ fn tupleField(
2799326920
2799426921 const field_ty = tuple_ty.fieldType(field_index, zcu);
2799526922
27996 if (tuple_ty.structFieldIsComptime(field_index, zcu))
27997 try tuple_ty.resolveStructFieldInits(pt);
2799826923 if (try tuple_ty.structFieldValueComptime(pt, field_index)) |default_value| {
2799926924 return Air.internedToRef(default_value.toIntern()); // comptime field
2800026925 }
2800126926
28002 if (try sema.resolveValue(tuple)) |tuple_val| {
26927 if (sema.resolveValue(tuple)) |tuple_val| {
2800326928 if (tuple_val.isUndef(zcu)) return pt.undefRef(field_ty);
2800426929 return Air.internedToRef((try tuple_val.fieldValue(pt, field_index)).toIntern());
2800526930 }
2800626931
2800726932 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);
2800826933
28009 try field_ty.resolveLayout(pt);
2801026934 return block.addStructFieldVal(tuple, field_index, field_ty);
2801126935}
2801226936
......@@ -28032,12 +26956,12 @@ fn elemValArray(
2803226956 return sema.fail(block, array_src, "indexing into empty array is not allowed", .{});
2803326957 }
2803426958
28035 const maybe_undef_array_val = try sema.resolveValue(array);
26959 const maybe_undef_array_val = sema.resolveValue(array);
2803626960 // index must be defined since it can access out of bounds
2803726961 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
2803826962
2803926963 if (maybe_index_val) |index_val| {
28040 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));
26964 const index: usize = @intCast(index_val.toUnsignedInt(zcu));
2804126965 if (array_sent) |s| {
2804226966 if (index == array_len) {
2804326967 return Air.internedToRef(s.toIntern());
......@@ -28053,10 +26977,11 @@ fn elemValArray(
2805326977 return pt.undefRef(elem_ty);
2805426978 }
2805526979 if (maybe_index_val) |index_val| {
28056 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));
28057 const elem_val = try array_val.elemValue(pt, index);
28058 return Air.internedToRef(elem_val.toIntern());
26980 const index: usize = @intCast(index_val.toUnsignedInt(zcu));
26981 return .fromValue(try array_val.elemValue(pt, index));
2805926982 }
26983 // Since the array is comptime-known, it might be OPV, in which case the index is irrelevant.
26984 if (try elem_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
2806026985 }
2806126986
2806226987 try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ty, array_ty, array_src);
......@@ -28071,12 +26996,105 @@ fn elemValArray(
2807126996 }
2807226997 }
2807326998
28074 if (try sema.typeHasOnePossibleValue(elem_ty)) |elem_val|
28075 return Air.internedToRef(elem_val.toIntern());
28076
2807726999 return block.addBinOp(.array_elem_val, array, elem_index);
2807827000}
2807927001
27002fn elemPtrVector(
27003 sema: *Sema,
27004 block: *Block,
27005 vector_ptr_src: LazySrcLoc,
27006 vector_ptr: Air.Inst.Ref,
27007 elem_index_src: LazySrcLoc,
27008 elem_index: Air.Inst.Ref,
27009 init: bool,
27010) CompileError!Air.Inst.Ref {
27011 const pt = sema.pt;
27012 const zcu = pt.zcu;
27013 const vector_ptr_ty = sema.typeOf(vector_ptr);
27014 const vector_ty = vector_ptr_ty.childType(zcu);
27015 assert(vector_ty.zigTypeTag(zcu) == .vector);
27016 const vector_len = vector_ty.vectorLen(zcu);
27017
27018 if (vector_len == 0) {
27019 return sema.fail(block, vector_ptr_src, "cannot index into empty vector", .{});
27020 }
27021
27022 const maybe_vector_ptr_val = sema.resolveValue(vector_ptr);
27023 // The index must not be undefined since it can be out of bounds.
27024 const index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index) orelse {
27025 return sema.fail(block, elem_index_src, "vector index not comptime known", .{});
27026 };
27027 const index = index_val.toUnsignedInt(zcu);
27028 if (index >= vector_len) {
27029 return sema.fail(block, elem_index_src, "index {d} outside vector of length {d}", .{ index, vector_len });
27030 }
27031
27032 const elem_ty = vector_ty.childType(zcu);
27033 const elem_bits = elem_ty.bitSize(zcu);
27034 // Exiting this block means the operation is a runtime one.
27035 const elem_ptr_ty: Type = if (elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits)) elem_ptr_ty: {
27036 // Use a packed pointer (i.e. vector_index != 0)
27037 const vector_ptr_info = vector_ptr_ty.ptrInfo(zcu);
27038 const elem_ptr_ty = try pt.ptrType(.{
27039 .child = elem_ty.toIntern(),
27040 .flags = .{
27041 .size = .one,
27042 .alignment = vector_ptr_info.flags.alignment,
27043 .is_const = vector_ptr_info.flags.is_const,
27044 .is_volatile = vector_ptr_info.flags.is_volatile,
27045 .is_allowzero = vector_ptr_info.flags.is_allowzero,
27046 .address_space = vector_ptr_info.flags.address_space,
27047 .vector_index = @enumFromInt(index),
27048 },
27049 .packed_offset = .{
27050 .host_size = @intCast(vector_len),
27051 .bit_offset = 0,
27052 },
27053 });
27054 if (maybe_vector_ptr_val) |ptr_val| {
27055 if (ptr_val.isUndef(zcu)) return pt.undefRef(elem_ptr_ty);
27056 return .fromValue(try pt.getCoerced(ptr_val, elem_ptr_ty));
27057 }
27058 break :elem_ptr_ty elem_ptr_ty;
27059 } else elem_ptr_ty: {
27060 // Use a normal pointer (i.e. vector_index == 0)
27061 const vector_ptr_info = vector_ptr_ty.ptrInfo(zcu);
27062 const elem_ptr_ty = try pt.ptrType(.{
27063 .child = elem_ty.toIntern(),
27064 .flags = .{
27065 .size = .one,
27066 // TODO: this logic was ported from old code, but it's bogus. This entire block will
27067 // go away when https://github.com/ziglang/zig/issues/24061 is implemented anyway.
27068 .alignment = switch (vector_ptr_info.flags.alignment) {
27069 .none => .none,
27070 else => |vec_align| switch (index * elem_ty.abiSize(zcu)) {
27071 0 => vec_align,
27072 else => |byte_offset| .minStrict(vec_align, .fromLog2Units(@ctz(byte_offset))),
27073 },
27074 },
27075 .is_const = vector_ptr_info.flags.is_const,
27076 .is_volatile = vector_ptr_info.flags.is_volatile,
27077 .is_allowzero = vector_ptr_info.flags.is_allowzero,
27078 .address_space = vector_ptr_info.flags.address_space,
27079 },
27080 });
27081 if (maybe_vector_ptr_val) |ptr_val| {
27082 if (ptr_val.isUndef(zcu)) return pt.undefRef(elem_ptr_ty);
27083 const bit_offset = index * @divExact(elem_ty.bitSize(zcu), 8);
27084 return .fromValue(try ptr_val.getOffsetPtr(bit_offset, elem_ptr_ty, pt));
27085 }
27086 break :elem_ptr_ty elem_ptr_ty;
27087 };
27088
27089 if (!init) {
27090 try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ty, vector_ty, vector_ptr_src);
27091 try sema.validateRuntimeValue(block, vector_ptr_src, vector_ptr);
27092 }
27093
27094 return block.addPtrElemPtr(vector_ptr, elem_index, elem_ptr_ty);
27095}
27096
27097/// Asserts that the layout of the array is already resolved.
2808027098fn elemPtrArray(
2808127099 sema: *Sema,
2808227100 block: *Block,
......@@ -28091,19 +27109,21 @@ fn elemPtrArray(
2809127109 const pt = sema.pt;
2809227110 const zcu = pt.zcu;
2809327111 const array_ptr_ty = sema.typeOf(array_ptr);
27112 assert(array_ptr_ty.ptrSize(zcu) == .one);
2809427113 const array_ty = array_ptr_ty.childType(zcu);
27114 assert(array_ty.zigTypeTag(zcu) == .array);
2809527115 const array_sent = array_ty.sentinel(zcu) != null;
2809627116 const array_len = array_ty.arrayLen(zcu);
2809727117 const array_len_s = array_len + @intFromBool(array_sent);
2809827118
2809927119 if (array_len_s == 0) {
28100 return sema.fail(block, array_ptr_src, "indexing into empty array is not allowed", .{});
27120 return sema.fail(block, array_ptr_src, "cannot index into empty array", .{});
2810127121 }
2810227122
28103 const maybe_undef_array_ptr_val = try sema.resolveValue(array_ptr);
27123 const maybe_undef_array_ptr_val = sema.resolveValue(array_ptr);
2810427124 // The index must not be undefined since it can be out of bounds.
28105 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {
28106 const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntSema(pt));
27125 const maybe_index: ?u64 = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {
27126 const index = index_val.toUnsignedInt(zcu);
2810727127 if (index >= array_len_s) {
2810827128 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";
2810927129 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });
......@@ -28111,37 +27131,39 @@ fn elemPtrArray(
2811127131 break :o index;
2811227132 } else null;
2811327133
28114 if (offset == null and array_ty.zigTypeTag(zcu) == .vector) {
28115 return sema.fail(block, elem_index_src, "vector index not comptime known", .{});
28116 }
28117
28118 const elem_ptr_ty = try array_ptr_ty.elemPtrType(offset, pt);
27134 array_ty.assertHasLayout(zcu);
27135 const elem_ptr_ty = try array_ptr_ty.elemPtrType(maybe_index, pt);
2811927136
2812027137 if (maybe_undef_array_ptr_val) |array_ptr_val| {
2812127138 if (array_ptr_val.isUndef(zcu)) {
2812227139 return pt.undefRef(elem_ptr_ty);
2812327140 }
28124 if (offset) |index| {
28125 const elem_ptr = try array_ptr_val.ptrElem(index, pt);
28126 return Air.internedToRef(elem_ptr.toIntern());
27141 if (maybe_index) |index| {
27142 return .fromValue(try array_ptr_val.ptrElem(index, pt));
2812727143 }
2812827144 }
2812927145
2813027146 if (!init) {
28131 try sema.validateRuntimeElemAccess(block, elem_index_src, array_ty.elemType2(zcu), array_ty, array_ptr_src);
27147 try sema.validateRuntimeElemAccess(block, elem_index_src, array_ty.childType(zcu), array_ty, array_ptr_src);
2813227148 try sema.validateRuntimeValue(block, array_ptr_src, array_ptr);
2813327149 }
2813427150
2813527151 // Runtime check is only needed if unable to comptime check.
28136 if (oob_safety and block.wantSafety() and offset == null) {
27152 if (oob_safety and block.wantSafety() and maybe_index == null) {
2813727153 const len_inst = try pt.intRef(.usize, array_len);
2813827154 const cmp_op: Air.Inst.Tag = if (array_sent) .cmp_lte else .cmp_lt;
2813927155 try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op);
2814027156 }
2814127157
27158 if (array_ty.childType(zcu).abiSize(zcu) == 0) {
27159 // zero-bit child type; just bitcast the pointer
27160 return block.addBitCast(elem_ptr_ty, array_ptr);
27161 }
27162
2814227163 return block.addPtrElemPtr(array_ptr, elem_index, elem_ptr_ty);
2814327164}
2814427165
27166/// Asserts that the layout of the slice element type is already resolved.
2814527167fn elemValSlice(
2814627168 sema: *Sema,
2814727169 block: *Block,
......@@ -28155,9 +27177,11 @@ fn elemValSlice(
2815527177 const pt = sema.pt;
2815627178 const zcu = pt.zcu;
2815727179 const slice_ty = sema.typeOf(slice);
27180 assert(slice_ty.isSlice(zcu));
2815827181 const slice_sent = slice_ty.sentinel(zcu) != null;
28159 const elem_ty = slice_ty.elemType2(zcu);
28160 var runtime_src = slice_src;
27182 const elem_ty = slice_ty.childType(zcu);
27183
27184 elem_ty.assertHasLayout(zcu);
2816127185
2816227186 // slice must be defined since it can dereferenced as null
2816327187 const maybe_slice_val = try sema.resolveDefinedValue(block, slice_src, slice);
......@@ -28165,37 +27189,30 @@ fn elemValSlice(
2816527189 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
2816627190
2816727191 if (maybe_slice_val) |slice_val| {
28168 runtime_src = elem_index_src;
28169 const slice_len = try slice_val.sliceLen(pt);
27192 const slice_len = slice_val.sliceLen(zcu);
2817027193 const slice_len_s = slice_len + @intFromBool(slice_sent);
2817127194 if (slice_len_s == 0) {
2817227195 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
2817327196 }
2817427197 if (maybe_index_val) |index_val| {
28175 const index: usize = @intCast(try index_val.toUnsignedIntSema(pt));
27198 const index: usize = @intCast(index_val.toUnsignedInt(zcu));
2817627199 if (index >= slice_len_s) {
2817727200 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
2817827201 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
2817927202 }
28180 const elem_ptr_ty = try slice_ty.elemPtrType(index, pt);
2818127203 const elem_ptr_val = try slice_val.ptrElem(index, pt);
28182 if (try sema.pointerDeref(block, slice_src, elem_ptr_val, elem_ptr_ty)) |elem_val| {
28183 return Air.internedToRef(elem_val.toIntern());
28184 }
28185 runtime_src = slice_src;
27204 return sema.analyzeLoad(block, src, .fromValue(elem_ptr_val), slice_src);
2818627205 }
2818727206 }
2818827207
28189 if (try sema.typeHasOnePossibleValue(elem_ty)) |elem_only_value| {
28190 return Air.internedToRef(elem_only_value.toIntern());
28191 }
27208 if (try elem_ty.onePossibleValue(pt)) |opv| return .fromValue(opv);
2819227209
2819327210 try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ty, slice_ty, slice_src);
2819427211 try sema.validateRuntimeValue(block, slice_src, slice);
2819527212
2819627213 if (oob_safety and block.wantSafety()) {
2819727214 const len_inst = if (maybe_slice_val) |slice_val|
28198 try pt.intRef(.usize, try slice_val.sliceLen(pt))
27215 try pt.intRef(.usize, slice_val.sliceLen(zcu))
2819927216 else
2820027217 try block.addTyOp(.slice_len, .usize, slice);
2820127218 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
......@@ -28204,6 +27221,7 @@ fn elemValSlice(
2820427221 return block.addBinOp(.slice_elem_val, slice, elem_index);
2820527222}
2820627223
27224/// Asserts that the layout of the slice element type is already resolved.
2820727225fn elemPtrSlice(
2820827226 sema: *Sema,
2820927227 block: *Block,
......@@ -28217,33 +27235,35 @@ fn elemPtrSlice(
2821727235 const pt = sema.pt;
2821827236 const zcu = pt.zcu;
2821927237 const slice_ty = sema.typeOf(slice);
27238 assert(slice_ty.isSlice(zcu));
2822027239 const slice_sent = slice_ty.sentinel(zcu) != null;
27240 const elem_ty = slice_ty.childType(zcu);
27241 elem_ty.assertHasLayout(zcu);
2822127242
28222 const maybe_undef_slice_val = try sema.resolveValue(slice);
27243 const maybe_undef_slice_val = sema.resolveValue(slice);
2822327244 // The index must not be undefined since it can be out of bounds.
28224 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {
28225 const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntSema(pt));
28226 break :o index;
27245 const offset: ?u64 = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {
27246 break :o index_val.toUnsignedInt(zcu);
2822727247 } else null;
2822827248
2822927249 const elem_ptr_ty = try slice_ty.elemPtrType(offset, pt);
27250 assert(elem_ptr_ty.childType(zcu).toIntern() == elem_ty.toIntern());
2823027251
2823127252 if (maybe_undef_slice_val) |slice_val| {
2823227253 if (slice_val.isUndef(zcu)) {
2823327254 return pt.undefRef(elem_ptr_ty);
2823427255 }
28235 const slice_len = try slice_val.sliceLen(pt);
27256 const slice_len = slice_val.sliceLen(zcu);
2823627257 const slice_len_s = slice_len + @intFromBool(slice_sent);
2823727258 if (slice_len_s == 0) {
28238 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
27259 return sema.fail(block, slice_src, "cannot index into empty slice", .{});
2823927260 }
2824027261 if (offset) |index| {
2824127262 if (index >= slice_len_s) {
2824227263 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
2824327264 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
2824427265 }
28245 const elem_ptr_val = try slice_val.ptrElem(index, pt);
28246 return Air.internedToRef(elem_ptr_val.toIntern());
27266 return .fromValue(try slice_val.ptrElem(index, pt));
2824727267 }
2824827268 }
2824927269
......@@ -28254,13 +27274,13 @@ fn elemPtrSlice(
2825427274 const len_inst = len: {
2825527275 if (maybe_undef_slice_val) |slice_val|
2825627276 if (!slice_val.isUndef(zcu))
28257 break :len try pt.intRef(.usize, try slice_val.sliceLen(pt));
27277 break :len try pt.intRef(.usize, slice_val.sliceLen(zcu));
2825827278 break :len try block.addTyOp(.slice_len, .usize, slice);
2825927279 };
2826027280 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
2826127281 try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op);
2826227282 }
28263 if (!try slice_ty.childType(zcu).hasRuntimeBitsIgnoreComptimeSema(pt)) {
27283 if (elem_ty.abiSize(zcu) == 0) {
2826427284 // zero-bit child type; just extract the pointer and bitcast it
2826527285 const slice_ptr = try block.addTyOp(.slice_ptr, slice_ty.slicePtrFieldType(zcu), slice);
2826627286 return block.addBitCast(elem_ptr_ty, slice_ptr);
......@@ -28331,15 +27351,17 @@ fn coerceExtra(
2833127351 if (dest_ty.isGenericPoison()) return inst;
2833227352
2833327353 const dest_ty_src = inst_src; // TODO better source location
28334 try dest_ty.resolveFields(pt);
2833527354 const inst_ty = sema.typeOf(inst);
28336 try inst_ty.resolveFields(pt);
2833727355 const target = zcu.getTarget();
27356
27357 inst_ty.assertHasLayout(zcu);
27358 try sema.ensureLayoutResolved(dest_ty, inst_src, .coerce);
27359
2833827360 // If the types are the same, we can return the operand.
2833927361 if (dest_ty.eql(inst_ty, zcu))
2834027362 return inst;
2834127363
28342 const maybe_inst_val = try sema.resolveValue(inst);
27364 const maybe_inst_val = sema.resolveValue(inst);
2834327365
2834427366 var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src, maybe_inst_val);
2834527367 if (in_memory_result == .ok) {
......@@ -28357,7 +27379,7 @@ fn coerceExtra(
2835727379 if (maybe_inst_val) |val| {
2835827380 // undefined sets the optional bit also to undefined.
2835927381 if (val.toIntern() == .undef) {
28360 return pt.undefRef(dest_ty);
27382 return .fromValue(try dest_ty.onePossibleValue(pt) orelse try pt.undefValue(dest_ty));
2836127383 }
2836227384
2836327385 // null to ?T
......@@ -28372,11 +27394,11 @@ fn coerceExtra(
2837227394 // cast from ?*T and ?[*]T to ?*anyopaque
2837327395 // but don't do it if the source type is a double pointer
2837427396 if (dest_ty.isPtrLikeOptional(zcu) and
28375 dest_ty.elemType2(zcu).toIntern() == .anyopaque_type and
27397 dest_ty.nullablePtrElem(zcu).toIntern() == .anyopaque_type and
2837627398 inst_ty.isPtrAtRuntime(zcu))
2837727399 anyopaque_check: {
2837827400 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :optional;
28379 const elem_ty = inst_ty.elemType2(zcu);
27401 const elem_ty = inst_ty.nullablePtrElem(zcu);
2838027402 if (elem_ty.zigTypeTag(zcu) == .pointer or elem_ty.isPtrLikeOptional(zcu)) {
2838127403 in_memory_result = .{ .double_ptr_to_anyopaque = .{
2838227404 .actual = inst_ty,
......@@ -28409,7 +27431,7 @@ fn coerceExtra(
2840927431
2841027432 // Function body to function pointer.
2841127433 if (inst_ty.zigTypeTag(zcu) == .@"fn") {
28412 const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
27434 const fn_val = sema.resolveValue(inst).?;
2841327435 const fn_nav = switch (zcu.intern_pool.indexToKey(fn_val.toIntern())) {
2841427436 .func => |f| f.owner_nav,
2841527437 .@"extern" => |e| e.owner_nav,
......@@ -28430,7 +27452,7 @@ fn coerceExtra(
2843027452 const array_elem_ty = array_ty.childType(zcu);
2843127453 if (array_ty.arrayLen(zcu) != 1) break :single_item;
2843227454 const dest_is_mut = !dest_info.flags.is_const;
28433 switch (try sema.coerceInMemoryAllowed(block, array_elem_ty, ptr_elem_ty, dest_is_mut, target, dest_ty_src, inst_src, maybe_inst_val)) {
27455 switch (try sema.coerceInMemoryAllowed(block, array_elem_ty, ptr_elem_ty, dest_is_mut, target, dest_ty_src, inst_src, null)) {
2843427456 .ok => {},
2843527457 else => break :single_item,
2843627458 }
......@@ -28448,7 +27470,7 @@ fn coerceExtra(
2844827470 const dest_is_mut = !dest_info.flags.is_const;
2844927471
2845027472 const dst_elem_type: Type = .fromInterned(dest_info.child);
28451 const elem_res = try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src, maybe_inst_val);
27473 const elem_res = try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src, null);
2845227474 switch (elem_res) {
2845327475 .ok => {},
2845427476 else => {
......@@ -28509,7 +27531,7 @@ fn coerceExtra(
2850927531 const src_elem_ty = inst_ty.childType(zcu);
2851027532 const dest_is_mut = !dest_info.flags.is_const;
2851127533 const dst_elem_type: Type = .fromInterned(dest_info.child);
28512 switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, src_elem_ty, dest_is_mut, target, dest_ty_src, inst_src, maybe_inst_val)) {
27534 switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, src_elem_ty, dest_is_mut, target, dest_ty_src, inst_src, null)) {
2851327535 .ok => {},
2851427536 else => break :src_c_ptr,
2851527537 }
......@@ -28520,7 +27542,7 @@ fn coerceExtra(
2852027542 // but don't do it if the source type is a double pointer
2852127543 if (dest_info.child == .anyopaque_type and inst_ty.zigTypeTag(zcu) == .pointer) to_anyopaque: {
2852227544 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
28523 const elem_ty = inst_ty.elemType2(zcu);
27545 const elem_ty = inst_ty.childType(zcu);
2852427546 if (elem_ty.zigTypeTag(zcu) == .pointer or elem_ty.isPtrLikeOptional(zcu)) {
2852527547 in_memory_result = .{ .double_ptr_to_anyopaque = .{
2852627548 .actual = inst_ty,
......@@ -28580,7 +27602,7 @@ fn coerceExtra(
2858027602 target,
2858127603 dest_ty_src,
2858227604 inst_src,
28583 maybe_inst_val,
27605 null,
2858427606 )) {
2858527607 .ok => {},
2858627608 else => break :p,
......@@ -28616,16 +27638,14 @@ fn coerceExtra(
2861627638 // empty tuple to zero-length slice
2861727639 // note that this allows coercing to a mutable slice.
2861827640 if (inst_child_ty.structFieldCount(zcu) == 0) {
28619 const align_val = try dest_ty.ptrAlignmentSema(pt);
28620 return Air.internedToRef(try pt.intern(.{ .slice = .{
28621 .ty = dest_ty.toIntern(),
28622 .ptr = try pt.intern(.{ .ptr = .{
28623 .ty = dest_ty.slicePtrFieldType(zcu).toIntern(),
28624 .base_addr = .int,
28625 .byte_offset = align_val.toByteUnits().?,
28626 } }),
28627 .len = .zero_usize,
28628 } }));
27641 const empty_array_ty = try pt.arrayType(.{
27642 .len = 0,
27643 .child = dest_info.child,
27644 .sentinel = dest_info.sentinel,
27645 });
27646 const empty_array_val = try pt.aggregateValue(empty_array_ty, &.{});
27647 const empty_array_ptr = try sema.uavRef(empty_array_val);
27648 return sema.coerceArrayPtrToSlice(block, dest_ty, empty_array_ptr, inst_src);
2862927649 }
2863027650
2863127651 // pointer to tuple to slice
......@@ -28653,7 +27673,7 @@ fn coerceExtra(
2865327673 target,
2865427674 dest_ty_src,
2865527675 inst_src,
28656 maybe_inst_val,
27676 null,
2865727677 )) {
2865827678 .ok => {},
2865927679 else => break :p,
......@@ -28684,12 +27704,12 @@ fn coerceExtra(
2868427704 .int, .comptime_int => {
2868527705 if (maybe_inst_val) |val| {
2868627706 // comptime-known integer to other number
28687 if (!(try sema.intFitsInType(val, dest_ty, null))) {
27707 if (!val.intFitsInType(dest_ty, null, zcu)) {
2868827708 if (!opts.report_err) return error.NotCoercible;
2868927709 return sema.fail(block, inst_src, "type '{f}' cannot represent integer value '{f}'", .{ dest_ty.fmt(pt), val.fmtValueSema(pt, sema) });
2869027710 }
2869127711 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
28692 .undef => try pt.undefRef(dest_ty),
27712 .undef => .fromValue(try dest_ty.onePossibleValue(pt) orelse try pt.undefValue(dest_ty)),
2869327713 .int => |int| Air.internedToRef(
2869427714 try zcu.intern_pool.getCoercedInts(gpa, io, pt.tid, int, dest_ty.toIntern()),
2869527715 ),
......@@ -28717,7 +27737,7 @@ fn coerceExtra(
2871727737 },
2871827738 .float, .comptime_float => switch (inst_ty.zigTypeTag(zcu)) {
2871927739 .comptime_float => {
28720 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
27740 const val = sema.resolveValue(inst).?;
2872127741 const result_val = try val.floatCast(dest_ty, pt);
2872227742 return Air.internedToRef(result_val.toIntern());
2872327743 },
......@@ -28768,28 +27788,26 @@ fn coerceExtra(
2876827788 }
2876927789 break :int;
2877027790 };
28771 const result_val = try val.floatFromIntAdvanced(sema.arena, inst_ty, dest_ty, pt, .sema);
28772 const fits: bool = switch (ip.indexToKey(result_val.toIntern())) {
28773 else => unreachable,
28774 .undef => true,
28775 .float => |float| fits: {
28776 var buffer: InternPool.Key.Int.Storage.BigIntSpace = undefined;
28777 const operand_big_int = val.toBigInt(&buffer, zcu);
28778 switch (float.storage) {
28779 inline else => |x| {
28780 if (!std.math.isFinite(x)) break :fits false;
28781 var result_big_int: std.math.big.int.Mutable = .{
28782 .limbs = try sema.arena.alloc(std.math.big.Limb, std.math.big.int.calcLimbLen(x)),
28783 .len = undefined,
28784 .positive = undefined,
28785 };
28786 switch (result_big_int.setFloat(x, .nearest_even)) {
28787 .inexact => break :fits false,
28788 .exact => {},
28789 }
28790 break :fits result_big_int.toConst().eql(operand_big_int);
28791 },
27791 if (val.isUndef(zcu)) {
27792 return .fromValue(try pt.undefValue(dest_ty));
27793 }
27794 const result_val = try pt.floatValue(dest_ty, val.toFloat(f128, zcu));
27795 const float = ip.indexToKey(result_val.toIntern()).float;
27796 var buffer: InternPool.Key.Int.Storage.BigIntSpace = undefined;
27797 const operand_big_int = val.toBigInt(&buffer, zcu);
27798 const fits = switch (float.storage) {
27799 inline else => |x| fits: {
27800 if (!std.math.isFinite(x)) break :fits false;
27801 var result_big_int: std.math.big.int.Mutable = .{
27802 .limbs = try sema.arena.alloc(std.math.big.Limb, std.math.big.int.calcLimbLen(x)),
27803 .len = undefined,
27804 .positive = undefined,
27805 };
27806 switch (result_big_int.setFloat(x, .nearest_even)) {
27807 .inexact => break :fits false,
27808 .exact => {},
2879227809 }
27810 break :fits result_big_int.toConst().eql(operand_big_int);
2879327811 },
2879427812 };
2879527813 if (!fits) return sema.fail(
......@@ -28805,7 +27823,7 @@ fn coerceExtra(
2880527823 .@"enum" => switch (inst_ty.zigTypeTag(zcu)) {
2880627824 .enum_literal => {
2880727825 // enum literal to enum
28808 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
27826 const val = sema.resolveValue(inst).?;
2880927827 const string = zcu.intern_pool.indexToKey(val.toIntern()).enum_literal;
2881027828 const field_index = dest_ty.enumFieldIndex(string, zcu) orelse {
2881127829 return sema.fail(block, inst_src, "no field named '{f}' in enum '{f}'", .{
......@@ -28814,33 +27832,36 @@ fn coerceExtra(
2881427832 };
2881527833 return Air.internedToRef((try pt.enumValueFieldIndex(dest_ty, @intCast(field_index))).toIntern());
2881627834 },
28817 .@"union" => blk: {
27835 .@"union" => if (inst_ty.unionTagType(zcu)) |enum_tag_ty| {
2881827836 // union to its own tag type
28819 const union_tag_ty = inst_ty.unionTagType(zcu) orelse break :blk;
28820 if (union_tag_ty.eql(dest_ty, zcu)) {
28821 return sema.unionToTag(block, dest_ty, inst, inst_src);
27837 if (enum_tag_ty.toIntern() == dest_ty.toIntern()) {
27838 return sema.unionToTag(block, inst);
2882227839 }
2882327840 },
2882427841 else => {},
2882527842 },
2882627843 .error_union => switch (inst_ty.zigTypeTag(zcu)) {
28827 .error_set => {
28828 // E to E!T
28829 return sema.wrapErrorUnionSet(block, dest_ty, inst, inst_src);
27844 // E to E!T
27845 .error_set => if (sema.wrapErrorUnionSet(block, dest_ty, inst, inst_src)) |res| {
27846 return res;
27847 } else |err| switch (err) {
27848 error.NotCoercible => if (in_memory_result == .no_match) {
27849 // Try to give more useful notes
27850 const err_set_type = dest_ty.errorUnionSet(zcu);
27851 in_memory_result = try sema.coerceInMemoryAllowed(block, err_set_type, inst_ty, false, target, dest_ty_src, inst_src, maybe_inst_val);
27852 },
27853 else => |e| return e,
2883027854 },
28831 else => eu: {
28832 // T to E!T
28833 return sema.wrapErrorUnionPayload(block, dest_ty, inst, inst_src) catch |err| switch (err) {
28834 error.NotCoercible => {
28835 if (in_memory_result == .no_match) {
28836 const payload_type = dest_ty.errorUnionPayload(zcu);
28837 // Try to give more useful notes
28838 in_memory_result = try sema.coerceInMemoryAllowed(block, payload_type, inst_ty, false, target, dest_ty_src, inst_src, maybe_inst_val);
28839 }
28840 break :eu;
28841 },
28842 else => |e| return e,
28843 };
27855 // T to E!T
27856 else => if (sema.wrapErrorUnionPayload(block, dest_ty, inst, inst_src)) |res| {
27857 return res;
27858 } else |err| switch (err) {
27859 error.NotCoercible => if (in_memory_result == .no_match) {
27860 // Try to give more useful notes
27861 const payload_type = dest_ty.errorUnionPayload(zcu);
27862 in_memory_result = try sema.coerceInMemoryAllowed(block, payload_type, inst_ty, false, target, dest_ty_src, inst_src, maybe_inst_val);
27863 },
27864 else => |e| return e,
2884427865 },
2884527866 },
2884627867 .@"union" => switch (inst_ty.zigTypeTag(zcu)) {
......@@ -28858,7 +27879,7 @@ fn coerceExtra(
2885827879 target,
2885927880 dest_ty_src,
2886027881 inst_src,
28861 maybe_inst_val,
27882 null,
2886227883 )) {
2886327884 break :array_to_array;
2886427885 }
......@@ -28900,18 +27921,16 @@ fn coerceExtra(
2890027921 else => {},
2890127922 }
2890227923
28903 const can_coerce_to = switch (dest_ty.zigTypeTag(zcu)) {
28904 .noreturn, .@"opaque" => false,
28905 else => true,
27924 const dest_is_npv = switch (dest_ty.classify(zcu)) {
27925 .no_possible_value => true,
27926 .one_possible_value => if (inst == .undef) {
27927 return .fromValue((try dest_ty.onePossibleValue(pt)).?);
27928 } else false,
27929 .runtime, .fully_comptime, .partially_comptime => if (inst == .undef) {
27930 return .fromValue(try pt.undefValue(dest_ty));
27931 } else false,
2890627932 };
2890727933
28908 if (can_coerce_to) {
28909 // undefined to anything. We do this after the big switch above so that
28910 // special logic has a chance to run first, such as `*[N]T` to `[]T` which
28911 // should initialize the length field of the slice.
28912 if (maybe_inst_val) |val| if (val.toIntern() == .undef) return pt.undefRef(dest_ty);
28913 }
28914
2891527934 if (!opts.report_err) return error.NotCoercible;
2891627935
2891727936 if (opts.is_ret and dest_ty.zigTypeTag(zcu) == .noreturn) {
......@@ -28933,13 +27952,13 @@ fn coerceExtra(
2893327952 const msg = try sema.typeMismatchErrMsg(inst_src, dest_ty, inst_ty);
2893427953 errdefer msg.destroy(sema.gpa);
2893527954
28936 if (!can_coerce_to) {
28937 try sema.errNote(inst_src, msg, "cannot coerce to '{f}'", .{dest_ty.fmt(pt)});
27955 if (dest_is_npv) {
27956 try sema.errNote(inst_src, msg, "cannot coerce to uninstantiable type '{f}'", .{dest_ty.fmt(pt)});
2893827957 }
2893927958
2894027959 // E!T to T
2894127960 if (inst_ty.zigTypeTag(zcu) == .error_union and
28942 (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(zcu), dest_ty, false, target, dest_ty_src, inst_src, maybe_inst_val)) == .ok)
27961 (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(zcu), dest_ty, false, target, dest_ty_src, inst_src, null)) == .ok)
2894327962 {
2894427963 try sema.errNote(inst_src, msg, "cannot convert error union to payload type", .{});
2894527964 try sema.errNote(inst_src, msg, "consider using 'try', 'catch', or 'if'", .{});
......@@ -28947,7 +27966,7 @@ fn coerceExtra(
2894727966
2894827967 // ?T to T
2894927968 if (inst_ty.zigTypeTag(zcu) == .optional and
28950 (try sema.coerceInMemoryAllowed(block, inst_ty.optionalChild(zcu), dest_ty, false, target, dest_ty_src, inst_src, maybe_inst_val)) == .ok)
27969 (try sema.coerceInMemoryAllowed(block, inst_ty.optionalChild(zcu), dest_ty, false, target, dest_ty_src, inst_src, null)) == .ok)
2895127970 {
2895227971 try sema.errNote(inst_src, msg, "cannot convert optional to payload type", .{});
2895327972 try sema.errNote(inst_src, msg, "consider using '.?', 'orelse', or 'if'", .{});
......@@ -29394,6 +28413,10 @@ pub fn coerceInMemoryAllowed(
2939428413 const pt = sema.pt;
2939528414 const zcu = pt.zcu;
2939628415
28416 if (src_val) |val| {
28417 assert(val.typeOf(zcu).toIntern() == src_ty.toIntern());
28418 }
28419
2939728420 if (dest_ty.eql(src_ty, zcu))
2939828421 return .ok;
2939928422
......@@ -29428,7 +28451,7 @@ pub fn coerceInMemoryAllowed(
2942828451 // Comptime int to regular int.
2942928452 if (dest_tag == .int and src_tag == .comptime_int) {
2943028453 if (src_val) |val| {
29431 if (!(try sema.intFitsInType(val, dest_ty, null))) {
28454 if (!val.intFitsInType(dest_ty, null, zcu)) {
2943228455 return .{ .comptime_int_not_coercible = .{ .wanted = dest_ty, .actual = val } };
2943328456 }
2943428457 }
......@@ -29444,17 +28467,13 @@ pub fn coerceInMemoryAllowed(
2944428467 }
2944528468
2944628469 // Pointers / Pointer-like Optionals
29447 const maybe_dest_ptr_ty = try sema.typePtrOrOptionalPtrTy(dest_ty);
29448 const maybe_src_ptr_ty = try sema.typePtrOrOptionalPtrTy(src_ty);
29449 if (maybe_dest_ptr_ty) |dest_ptr_ty| {
29450 if (maybe_src_ptr_ty) |src_ptr_ty| {
29451 return try sema.coerceInMemoryAllowedPtrs(block, dest_ty, src_ty, dest_ptr_ty, src_ptr_ty, dest_is_mut, target, dest_src, src_src);
29452 }
28470 if (dest_ty.isPtrAtRuntime(zcu) and src_ty.isPtrAtRuntime(zcu)) {
28471 return try sema.coerceInMemoryAllowedPtrs(block, dest_ty, src_ty, dest_is_mut, target, dest_src, src_src);
2945328472 }
2945428473
2945528474 // Slices
2945628475 if (dest_ty.isSlice(zcu) and src_ty.isSlice(zcu)) {
29457 return try sema.coerceInMemoryAllowedPtrs(block, dest_ty, src_ty, dest_ty, src_ty, dest_is_mut, target, dest_src, src_src);
28476 return try sema.coerceInMemoryAllowedPtrs(block, dest_ty, src_ty, dest_is_mut, target, dest_src, src_src);
2945828477 }
2945928478
2946028479 // Functions
......@@ -29554,7 +28573,8 @@ pub fn coerceInMemoryAllowed(
2955428573
2955528574 // Optionals
2955628575 if (dest_tag == .optional and src_tag == .optional) {
29557 if ((maybe_dest_ptr_ty != null) != (maybe_src_ptr_ty != null)) {
28576 if (dest_ty.isPtrAtRuntime(zcu) or src_ty.isPtrAtRuntime(zcu)) {
28577 // Only one is, because we already handled when both are.
2955828578 return .{ .optional_shape = .{
2955928579 .actual = src_ty,
2956028580 .wanted = dest_ty,
......@@ -29581,7 +28601,6 @@ pub fn coerceInMemoryAllowed(
2958128601 const field_count = dest_ty.structFieldCount(zcu);
2958228602 for (0..field_count) |field_idx| {
2958328603 if (dest_ty.structFieldIsComptime(field_idx, zcu) != src_ty.structFieldIsComptime(field_idx, zcu)) break :tuple;
29584 if (dest_ty.fieldAlignment(field_idx, zcu) != src_ty.fieldAlignment(field_idx, zcu)) break :tuple;
2958528604 const dest_field_ty = dest_ty.fieldType(field_idx, zcu);
2958628605 const src_field_ty = src_ty.fieldType(field_idx, zcu);
2958728606 const field = try sema.coerceInMemoryAllowed(block, dest_field_ty, src_field_ty, dest_is_mut, target, dest_src, src_src, null);
......@@ -29609,89 +28628,62 @@ fn coerceInMemoryAllowedErrorSets(
2960928628 const gpa = sema.gpa;
2961028629 const ip = &zcu.intern_pool;
2961128630
29612 // Coercion to `anyerror`. Note that this check can return false negatives
29613 // in case the error sets did not get resolved.
29614 if (dest_ty.isAnyError(zcu)) {
29615 return .ok;
29616 }
29617
29618 if (dest_ty.toIntern() == .adhoc_inferred_error_set_type) {
29619 // We are trying to coerce an error set to the current function's
29620 // inferred error set.
29621 const dst_ies = sema.fn_ret_ty_ies.?;
29622 try dst_ies.addErrorSet(src_ty, ip, sema.arena);
29623 return .ok;
29624 }
29625
29626 if (ip.isInferredErrorSetType(dest_ty.toIntern())) {
29627 const dst_ies_func_index = ip.iesFuncIndex(dest_ty.toIntern());
29628 if (sema.fn_ret_ty_ies) |dst_ies| {
29629 if (dst_ies.func == dst_ies_func_index) {
29630 // We are trying to coerce an error set to the current function's
29631 // inferred error set.
29632 try dst_ies.addErrorSet(src_ty, ip, sema.arena);
29633 return .ok;
29634 }
29635 }
29636 switch (try sema.resolveInferredErrorSet(block, dest_src, dest_ty.toIntern())) {
29637 // isAnyError might have changed from a false negative to a true
29638 // positive after resolution.
29639 .anyerror_type => return .ok,
29640 else => {},
29641 }
29642 }
29643
29644 var missing_error_buf = std.array_list.Managed(InternPool.NullTerminatedString).init(gpa);
29645 defer missing_error_buf.deinit();
29646
29647 switch (src_ty.toIntern()) {
29648 .anyerror_type => switch (ip.indexToKey(dest_ty.toIntern())) {
29649 .simple_type => unreachable, // filtered out above
29650 .error_set_type, .inferred_error_set_type => return .from_anyerror,
29651 else => unreachable,
28631 const dest_set: InternPool.Key.ErrorSetType = err_set: switch (dest_ty.toIntern()) {
28632 .anyerror_type => return .ok,
28633 .adhoc_inferred_error_set_type => {
28634 // We are trying to coerce an error set to the current function's
28635 // inferred error set.
28636 const dst_ies = sema.fn_ret_ty_ies.?;
28637 try dst_ies.addErrorSet(src_ty, ip, sema.arena);
28638 return .ok;
2965228639 },
29653
29654 else => switch (ip.indexToKey(src_ty.toIntern())) {
29655 .inferred_error_set_type => {
29656 const resolved_src_ty = try sema.resolveInferredErrorSet(block, src_src, src_ty.toIntern());
29657 // src anyerror status might have changed after the resolution.
29658 if (resolved_src_ty == .anyerror_type) {
29659 // dest_ty.isAnyError(zcu) == true is already checked for at this point.
29660 return .from_anyerror;
29661 }
29662
29663 for (ip.indexToKey(resolved_src_ty).error_set_type.names.get(ip)) |key| {
29664 if (!Type.errorSetHasFieldIp(ip, dest_ty.toIntern(), key)) {
29665 try missing_error_buf.append(key);
28640 else => |err_set_ty| switch (ip.indexToKey(err_set_ty)) {
28641 .inferred_error_set_type => |func_index| {
28642 if (sema.fn_ret_ty_ies) |dst_ies| {
28643 if (dst_ies.func == func_index) {
28644 // We are trying to coerce an error set to the current function's
28645 // inferred error set.
28646 try dst_ies.addErrorSet(src_ty, ip, sema.arena);
28647 return .ok;
2966628648 }
2966728649 }
29668
29669 if (missing_error_buf.items.len != 0) {
29670 return InMemoryCoercionResult{
29671 .missing_error = try sema.arena.dupe(InternPool.NullTerminatedString, missing_error_buf.items),
29672 };
29673 }
29674
29675 return .ok;
28650 try sema.ensureFuncIesResolved(block, dest_src, func_index);
28651 continue :err_set ip.funcIesResolvedUnordered(func_index);
2967628652 },
29677 .error_set_type => |error_set_type| {
29678 for (error_set_type.names.get(ip)) |name| {
29679 if (!Type.errorSetHasFieldIp(ip, dest_ty.toIntern(), name)) {
29680 try missing_error_buf.append(name);
29681 }
29682 }
29683
29684 if (missing_error_buf.items.len != 0) {
29685 return InMemoryCoercionResult{
29686 .missing_error = try sema.arena.dupe(InternPool.NullTerminatedString, missing_error_buf.items),
29687 };
29688 }
28653 .error_set_type => |err_set| err_set,
28654 else => unreachable,
28655 },
28656 };
2968928657
29690 return .ok;
28658 const src_names: InternPool.NullTerminatedString.Slice = err_set: switch (src_ty.toIntern()) {
28659 .anyerror_type => return .from_anyerror,
28660 else => |err_set_ty| switch (ip.indexToKey(err_set_ty)) {
28661 .inferred_error_set_type => |func_index| {
28662 try sema.ensureFuncIesResolved(block, src_src, func_index);
28663 continue :err_set ip.funcIesResolvedUnordered(func_index);
2969128664 },
28665 .error_set_type => |err_set| err_set.names,
2969228666 else => unreachable,
2969328667 },
28668 };
28669
28670 var missing_error_buf: std.ArrayList(InternPool.NullTerminatedString) = .empty;
28671 defer missing_error_buf.deinit(gpa);
28672
28673 for (src_names.get(ip)) |name| {
28674 if (dest_set.nameIndex(ip, name) == null) {
28675 try missing_error_buf.append(gpa, name);
28676 }
28677 }
28678
28679 if (missing_error_buf.items.len != 0) {
28680 return .{ .missing_error = try sema.arena.dupe(
28681 InternPool.NullTerminatedString,
28682 missing_error_buf.items,
28683 ) };
2969428684 }
28685
28686 return .ok;
2969528687}
2969628688
2969728689fn coerceInMemoryAllowedFns(
......@@ -29714,11 +28706,7 @@ fn coerceInMemoryAllowedFns(
2971428706
2971528707 {
2971628708 if (dest_info.is_var_args != src_info.is_var_args) {
29717 return InMemoryCoercionResult{ .fn_var_args = dest_info.is_var_args };
29718 }
29719
29720 if (dest_info.is_generic != src_info.is_generic) {
29721 return InMemoryCoercionResult{ .fn_generic = dest_info.is_generic };
28709 return .{ .fn_var_args = dest_info.is_var_args };
2972228710 }
2972328711
2972428712 const callconv_ok = callconvCoerceAllowed(target, src_info.cc, dest_info.cc) and
......@@ -29731,6 +28719,12 @@ fn coerceInMemoryAllowedFns(
2973128719 } };
2973228720 }
2973328721
28722 try sema.ensureLayoutResolved(src_ty, src_src, .coerce);
28723 try sema.ensureLayoutResolved(dest_ty, dest_src, .coerce);
28724 const src_is_runtime = src_ty.fnHasRuntimeBits(zcu);
28725 const dest_is_runtime = dest_ty.fnHasRuntimeBits(zcu);
28726 if (src_is_runtime != dest_is_runtime) return .{ .fn_generic = !dest_is_runtime };
28727
2973428728 if (!switch (src_info.return_type) {
2973528729 .generic_poison_type => true,
2973628730 .noreturn_type => !dest_is_mut,
......@@ -29780,7 +28774,7 @@ fn coerceInMemoryAllowedFns(
2978028774 const src_is_comptime = src_info.paramIsComptime(@intCast(param_i));
2978128775 const dest_is_comptime = dest_info.paramIsComptime(@intCast(param_i));
2978228776 if (src_is_comptime == dest_is_comptime) break :comptime_param;
29783 if (!dest_is_mut and src_is_comptime and !dest_is_comptime and try dest_param_ty.comptimeOnlySema(pt)) {
28777 if (!dest_is_mut and src_is_comptime and !dest_is_comptime and dest_param_ty.comptimeOnly(zcu)) {
2978428778 // A parameter which is marked `comptime` can drop that annotation if the type is comptime-only.
2978528779 // The function remains generic, and the parameter is going to be comptime-resolved either way,
2978628780 // so this just affects whether or not the argument is comptime-evaluated at the call site.
......@@ -29861,8 +28855,6 @@ fn coerceInMemoryAllowedPtrs(
2986128855 block: *Block,
2986228856 dest_ty: Type,
2986328857 src_ty: Type,
29864 dest_ptr_ty: Type,
29865 src_ptr_ty: Type,
2986628858 /// If set, the coercion must be valid in both directions.
2986728859 dest_is_mut: bool,
2986828860 target: *const std.Target,
......@@ -29875,8 +28867,8 @@ fn coerceInMemoryAllowedPtrs(
2987528867 const gpa = comp.gpa;
2987628868 const io = comp.io;
2987728869
29878 const dest_info = dest_ptr_ty.ptrInfo(zcu);
29879 const src_info = src_ptr_ty.ptrInfo(zcu);
28870 const dest_info = dest_ty.ptrInfo(zcu);
28871 const src_info = src_ty.ptrInfo(zcu);
2988028872
2988128873 const ok_ptr_size = src_info.flags.size == dest_info.flags.size or
2988228874 src_info.flags.size == .c or dest_info.flags.size == .c;
......@@ -30008,16 +29000,14 @@ fn coerceInMemoryAllowedPtrs(
3000829000 if (src_info.flags.alignment != .none or dest_info.flags.alignment != .none or
3000929001 dest_info.child != src_info.child)
3001029002 {
30011 const src_align = if (src_info.flags.alignment != .none)
30012 src_info.flags.alignment
30013 else
30014 try Type.fromInterned(src_info.child).abiAlignmentSema(pt);
30015
30016 const dest_align = if (dest_info.flags.alignment != .none)
30017 dest_info.flags.alignment
30018 else
30019 try Type.fromInterned(dest_info.child).abiAlignmentSema(pt);
30020
29003 const src_align = if (src_info.flags.alignment == .none) a: {
29004 try sema.ensureLayoutResolved(src_child, src_src, .align_check);
29005 break :a src_child.abiAlignment(zcu);
29006 } else src_info.flags.alignment;
29007 const dest_align = if (dest_info.flags.alignment == .none) a: {
29008 try sema.ensureLayoutResolved(dest_child, dest_src, .align_check);
29009 break :a dest_child.abiAlignment(zcu);
29010 } else dest_info.flags.alignment;
3002129011 if (dest_align.compare(if (dest_is_mut) .neq else .gt, src_align)) {
3002229012 return InMemoryCoercionResult{ .ptr_alignment = .{
3002329013 .actual = src_align,
......@@ -30049,7 +29039,7 @@ fn coerceVarArgParam(
3004929039 .{},
3005029040 ),
3005129041 .@"fn" => fn_ptr: {
30052 const fn_val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, inst, undefined);
29042 const fn_val = sema.resolveValue(inst).?;
3005329043 const fn_nav = zcu.funcInfo(fn_val.toIntern()).owner_nav;
3005429044 break :fn_ptr try sema.analyzeNavRef(block, inst_src, fn_nav);
3005529045 },
......@@ -30066,7 +29056,7 @@ fn coerceVarArgParam(
3006629056 }
3006729057 },
3006829058 else => if (uncasted_ty.isAbiInt(zcu)) int: {
30069 if (!try sema.validateExternType(uncasted_ty, .param_ty)) break :int inst;
29059 if (!uncasted_ty.validateExtern(.param_ty, zcu)) break :int inst;
3007029060 const target = zcu.getTarget();
3007129061 const uncasted_info = uncasted_ty.intInfo(zcu);
3007229062 if (uncasted_info.bits <= target.cTypeBitSize(switch (uncasted_info.signedness) {
......@@ -30095,7 +29085,7 @@ fn coerceVarArgParam(
3009529085 };
3009629086
3009729087 const coerced_ty = sema.typeOf(coerced);
30098 if (!try sema.validateExternType(coerced_ty, .param_ty)) {
29088 if (!coerced_ty.validateExtern(.param_ty, zcu)) {
3009929089 const msg = msg: {
3010029090 const msg = try sema.errMsg(inst_src, "cannot pass '{f}' to variadic function", .{coerced_ty.fmt(pt)});
3010129091 errdefer msg.destroy(sema.gpa);
......@@ -30140,38 +29130,20 @@ fn storePtr2(
3014029130
3014129131 const elem_ty = ptr_ty.childType(zcu);
3014229132
30143 // To generate better code for tuples, we detect a tuple operand here, and
30144 // analyze field loads and stores directly. This avoids an extra allocation + memcpy
30145 // which would occur if we used `coerce`.
30146 // However, we avoid this mechanism if the destination element type is a tuple,
30147 // because the regular store will be better for this case.
30148 // If the destination type is a struct we don't want this mechanism to trigger, because
30149 // this code does not handle tuple-to-struct coercion which requires dealing with missing
30150 // fields.
30151 const operand_ty = sema.typeOf(uncasted_operand);
30152 if (operand_ty.isTuple(zcu) and elem_ty.zigTypeTag(zcu) == .array) {
30153 const field_count = operand_ty.structFieldCount(zcu);
30154 var i: u32 = 0;
30155 while (i < field_count) : (i += 1) {
30156 const elem_src = operand_src; // TODO better source location
30157 const elem = try sema.tupleField(block, operand_src, uncasted_operand, elem_src, i);
30158 const elem_index = try pt.intRef(.usize, i);
30159 const elem_ptr = try sema.elemPtr(block, ptr_src, ptr, elem_index, elem_src, false, true);
30160 try sema.storePtr2(block, src, elem_ptr, elem_src, elem, elem_src, .store);
30161 }
30162 return;
30163 }
30164
30165 // TODO do the same thing for anon structs as for tuples above.
30166 // However, beware of the need to handle missing/extra fields.
30167
3016829133 const is_ret = air_tag == .ret_ptr;
3016929134
3017029135 const operand = sema.coerceExtra(block, elem_ty, uncasted_operand, operand_src, .{ .is_ret = is_ret }) catch |err| switch (err) {
3017129136 error.NotCoercible => unreachable,
3017229137 else => |e| return e,
3017329138 };
30174 const maybe_operand_val = try sema.resolveValue(operand);
29139 const maybe_operand_val = sema.resolveValue(operand);
29140
29141 const comptime_only = switch (elem_ty.classify(zcu)) {
29142 .no_possible_value => unreachable, // the coercion should have failed
29143 .one_possible_value => return, // no actual store operation is necessary
29144 .runtime => false,
29145 .partially_comptime, .fully_comptime => true,
29146 };
3017529147
3017629148 const runtime_src = rs: {
3017729149 const ptr_val = try sema.resolveDefinedValue(block, ptr_src, ptr) orelse break :rs ptr_src;
......@@ -30180,22 +29152,13 @@ fn storePtr2(
3018029152 return sema.storePtrVal(block, src, ptr_val, operand_val, elem_ty);
3018129153 };
3018229154
30183 // We're performing the store at runtime; as such, we need to make sure the pointee type
30184 // is not comptime-only. We can hit this case with a `@ptrFromInt` pointer.
30185 if (try elem_ty.comptimeOnlySema(pt)) {
30186 return sema.failWithOwnedErrorMsg(block, msg: {
30187 const msg = try sema.errMsg(src, "cannot store comptime-only type '{f}' at runtime", .{elem_ty.fmt(pt)});
30188 errdefer msg.destroy(sema.gpa);
30189 try sema.errNote(ptr_src, msg, "operation is runtime due to this pointer", .{});
30190 break :msg msg;
30191 });
30192 }
30193
30194 // We do this after the possible comptime store above, for the case of field_ptr stores
30195 // to unions because we want the comptime tag to be set, even if the field type is void.
30196 if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) {
30197 return;
30198 }
29155 // We're performing the store at runtime, so the pointee type must not be comptime-only.
29156 if (comptime_only) return sema.failWithOwnedErrorMsg(block, msg: {
29157 const msg = try sema.errMsg(src, "cannot store comptime-only type '{f}' at runtime", .{elem_ty.fmt(pt)});
29158 errdefer msg.destroy(sema.gpa);
29159 try sema.errNote(ptr_src, msg, "operation is runtime due to this pointer", .{});
29160 break :msg msg;
29161 });
3019929162
3020029163 try sema.requireRuntimeBlock(block, src, runtime_src);
3020129164
......@@ -30223,7 +29186,7 @@ fn checkComptimeKnownStore(sema: *Sema, block: *Block, store_inst_ref: Air.Inst.
3022329186 const maybe_base_alloc = sema.base_allocs.get(ptr) orelse break :known;
3022429187 const maybe_comptime_alloc = sema.maybe_comptime_allocs.getPtr(maybe_base_alloc) orelse break :known;
3022529188
30226 if ((try sema.resolveValue(operand)) != null and
29189 if (sema.resolveValue(operand) != null and
3022729190 block.runtime_index == maybe_comptime_alloc.runtime_index)
3022829191 {
3022929192 try maybe_comptime_alloc.stores.append(sema.arena, .{
......@@ -30272,7 +29235,7 @@ fn checkKnownAllocPtr(sema: *Sema, block: *Block, base_ptr: Air.Inst.Ref, new_pt
3027229235
3027329236 // If the index value is runtime-known, this pointer is also runtime-known, so
3027429237 // we must in turn make the alloc value runtime-known.
30275 if (null == try sema.resolveValue(index_ref)) {
29238 if (null == sema.resolveValue(index_ref)) {
3027629239 try sema.markMaybeComptimeAllocRuntime(block, alloc_inst);
3027729240 }
3027829241 },
......@@ -30361,10 +29324,10 @@ fn bitCast(
3036129324) CompileError!Air.Inst.Ref {
3036229325 const pt = sema.pt;
3036329326 const zcu = pt.zcu;
30364 try dest_ty.resolveLayout(pt);
30365
3036629327 const old_ty = sema.typeOf(inst);
30367 try old_ty.resolveLayout(pt);
29328
29329 old_ty.assertHasLayout(zcu);
29330 try sema.ensureLayoutResolved(dest_ty, inst_src, .init);
3036829331
3036929332 const dest_bits = dest_ty.bitSize(zcu);
3037029333 const old_bits = old_ty.bitSize(zcu);
......@@ -30378,7 +29341,7 @@ fn bitCast(
3037829341 });
3037929342 }
3038029343
30381 if (try sema.resolveValue(inst)) |val| {
29344 if (sema.resolveValue(inst)) |val| {
3038229345 if (val.isUndef(zcu))
3038329346 return pt.undefRef(dest_ty);
3038429347 if (old_ty.zigTypeTag(zcu) == .error_set and dest_ty.zigTypeTag(zcu) == .error_set) {
......@@ -30404,7 +29367,7 @@ fn coerceArrayPtrToSlice(
3040429367) CompileError!Air.Inst.Ref {
3040529368 const pt = sema.pt;
3040629369 const zcu = pt.zcu;
30407 if (try sema.resolveValue(inst)) |val| {
29370 if (sema.resolveValue(inst)) |val| {
3040829371 const ptr_array_ty = sema.typeOf(inst);
3040929372 const array_ty = ptr_array_ty.childType(zcu);
3041029373 const slice_ptr_ty = dest_ty.slicePtrFieldType(zcu);
......@@ -30499,7 +29462,7 @@ fn coerceCompatiblePtrs(
3049929462 const pt = sema.pt;
3050029463 const zcu = pt.zcu;
3050129464 const inst_ty = sema.typeOf(inst);
30502 if (try sema.resolveValue(inst)) |val| {
29465 if (sema.resolveValue(inst)) |val| {
3050329466 if (!val.isUndef(zcu) and val.isNull(zcu) and !dest_ty.isAllowzeroPtr(zcu)) {
3050429467 return sema.fail(block, inst_src, "null pointer casted to type '{f}'", .{dest_ty.fmt(pt)});
3050529468 }
......@@ -30510,9 +29473,7 @@ fn coerceCompatiblePtrs(
3051029473 }
3051129474 try sema.requireRuntimeBlock(block, inst_src, null);
3051229475 const inst_allows_zero = inst_ty.zigTypeTag(zcu) != .pointer or inst_ty.ptrAllowsZero(zcu);
30513 if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero(zcu) and
30514 (try dest_ty.elemType2(zcu).hasRuntimeBitsSema(pt) or dest_ty.elemType2(zcu).zigTypeTag(zcu) == .@"fn"))
30515 {
29476 if (block.wantSafety() and inst_allows_zero and !dest_ty.ptrAllowsZero(zcu)) {
3051629477 try sema.checkLogicalPtrOperation(block, inst_src, inst_ty);
3051729478 const actual_ptr = if (inst_ty.isSlice(zcu))
3051829479 try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty)
......@@ -30532,6 +29493,7 @@ fn coerceCompatiblePtrs(
3053229493 return new_ptr;
3053329494}
3053429495
29496/// Asserts that the layout of `union_ty` is already resolved.
3053529497fn coerceEnumToUnion(
3053629498 sema: *Sema,
3053729499 block: *Block,
......@@ -30545,18 +29507,21 @@ fn coerceEnumToUnion(
3054529507 const ip = &zcu.intern_pool;
3054629508 const inst_ty = sema.typeOf(inst);
3054729509
30548 const tag_ty = union_ty.unionTagType(zcu) orelse {
30549 const msg = msg: {
30550 const msg = try sema.typeMismatchErrMsg(inst_src, union_ty, inst_ty);
30551 errdefer msg.destroy(sema.gpa);
30552 try sema.errNote(union_ty_src, msg, "cannot coerce enum to untagged union", .{});
30553 try sema.addDeclaredHereNote(msg, union_ty);
30554 break :msg msg;
30555 };
30556 return sema.failWithOwnedErrorMsg(block, msg);
30557 };
29510 union_ty.assertHasLayout(zcu);
29511
29512 const union_obj = zcu.typeToUnion(union_ty).?;
29513 const enum_ty: Type = .fromInterned(union_obj.enum_tag_type);
29514 const enum_obj = ip.loadEnumType(enum_ty.toIntern());
29515
29516 if (union_obj.tag_usage != .tagged) return sema.failWithOwnedErrorMsg(block, msg: {
29517 const msg = try sema.typeMismatchErrMsg(inst_src, union_ty, inst_ty);
29518 errdefer msg.destroy(sema.gpa);
29519 try sema.errNote(union_ty_src, msg, "cannot coerce enum to untagged union", .{});
29520 try sema.addDeclaredHereNote(msg, union_ty);
29521 break :msg msg;
29522 });
3055829523
30559 const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src);
29524 const enum_tag = try sema.coerce(block, enum_ty, inst, inst_src);
3056029525 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {
3056129526 const field_index = union_ty.unionTagFieldIndex(val, pt.zcu) orelse {
3056229527 return sema.fail(block, inst_src, "union '{f}' has no tag with value '{f}'", .{
......@@ -30564,101 +29529,88 @@ fn coerceEnumToUnion(
3056429529 });
3056529530 };
3056629531
30567 const union_obj = zcu.typeToUnion(union_ty).?;
29532 const field_name = enum_obj.field_names.get(ip)[field_index];
3056829533 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);
30569 try field_ty.resolveFields(pt);
30570 if (field_ty.zigTypeTag(zcu) == .noreturn) {
30571 const msg = msg: {
30572 const msg = try sema.errMsg(inst_src, "cannot initialize 'noreturn' field of union", .{});
29534 switch (field_ty.classify(zcu)) {
29535 .one_possible_value => return .fromValue(try pt.unionValue(
29536 union_ty,
29537 val,
29538 (try field_ty.onePossibleValue(pt)).?,
29539 )),
29540
29541 .no_possible_value => return sema.failWithOwnedErrorMsg(block, msg: {
29542 const msg = try sema.errMsg(inst_src, "cannot initialize union field with uninstantiable type '{f}'", .{field_ty.fmt(pt)});
3057329543 errdefer msg.destroy(sema.gpa);
30574
30575 const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index];
3057629544 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{f}' declared here", .{
3057729545 field_name.fmt(ip),
3057829546 });
3057929547 try sema.addDeclaredHereNote(msg, union_ty);
3058029548 break :msg msg;
30581 };
30582 return sema.failWithOwnedErrorMsg(block, msg);
30583 }
30584 const opv = (try sema.typeHasOnePossibleValue(field_ty)) orelse {
30585 const msg = msg: {
30586 const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index];
29549 }),
29550
29551 else => return sema.failWithOwnedErrorMsg(block, msg: {
3058729552 const msg = try sema.errMsg(inst_src, "coercion from enum '{f}' to union '{f}' must initialize '{f}' field '{f}'", .{
3058829553 inst_ty.fmt(pt), union_ty.fmt(pt),
3058929554 field_ty.fmt(pt), field_name.fmt(ip),
3059029555 });
3059129556 errdefer msg.destroy(sema.gpa);
3059229557
30593 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{f}' declared here", .{
30594 field_name.fmt(ip),
30595 });
29558 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{f}' declared here", .{field_name.fmt(ip)});
3059629559 try sema.addDeclaredHereNote(msg, union_ty);
3059729560 break :msg msg;
30598 };
30599 return sema.failWithOwnedErrorMsg(block, msg);
30600 };
30601
30602 return Air.internedToRef((try pt.unionValue(union_ty, val, opv)).toIntern());
29561 }),
29562 }
3060329563 }
3060429564
3060529565 try sema.requireRuntimeBlock(block, inst_src, null);
3060629566
30607 if (tag_ty.isNonexhaustiveEnum(zcu)) {
29567 if (enum_ty.isNonexhaustiveEnum(zcu)) {
3060829568 const msg = msg: {
3060929569 const msg = try sema.errMsg(inst_src, "runtime coercion to union '{f}' from non-exhaustive enum", .{
3061029570 union_ty.fmt(pt),
3061129571 });
3061229572 errdefer msg.destroy(sema.gpa);
30613 try sema.addDeclaredHereNote(msg, tag_ty);
29573 try sema.addDeclaredHereNote(msg, enum_ty);
3061429574 break :msg msg;
3061529575 };
3061629576 return sema.failWithOwnedErrorMsg(block, msg);
3061729577 }
3061829578
30619 const union_obj = zcu.typeToUnion(union_ty).?;
30620 {
30621 var msg: ?*Zcu.ErrorMsg = null;
30622 errdefer if (msg) |some| some.destroy(sema.gpa);
30623
30624 for (union_obj.field_types.get(ip), 0..) |field_ty, field_index| {
30625 if (Type.fromInterned(field_ty).zigTypeTag(zcu) == .noreturn) {
30626 const err_msg = msg orelse try sema.errMsg(
30627 inst_src,
30628 "runtime coercion from enum '{f}' to union '{f}' which has a 'noreturn' field",
30629 .{ tag_ty.fmt(pt), union_ty.fmt(pt) },
30630 );
30631 msg = err_msg;
30632
30633 try sema.addFieldErrNote(union_ty, field_index, err_msg, "'noreturn' field here", .{});
30634 }
30635 }
30636 if (msg) |some| {
30637 msg = null;
30638 try sema.addDeclaredHereNote(some, union_ty);
30639 return sema.failWithOwnedErrorMsg(block, some);
29579 for (union_obj.field_types.get(ip)) |field_ty_ip| {
29580 if (Type.fromInterned(field_ty_ip).classify(zcu) != .one_possible_value) break;
29581 } else {
29582 // All fields are OPV, so the coercion is okay.
29583 if (try union_ty.onePossibleValue(pt)) |opv| {
29584 // The tag had redundant bits, but we've omitted the tag from the union's runtime layout, so the union is OPV and hence runtime-known.
29585 return .fromValue(opv);
29586 } else {
29587 // The union layout is just the tag, so we can bitcast the enum straight to the union.
29588 return block.addBitCast(union_ty, enum_tag);
3064029589 }
3064129590 }
3064229591
30643 // If the union has all fields 0 bits, the union value is just the enum value.
30644 if (union_ty.unionHasAllZeroBitFieldTypes(zcu)) {
30645 return block.addBitCast(union_ty, enum_tag);
30646 }
29592 // The coercion is invalid because one or more fields is not OPV.
3064729593
3064829594 const msg = msg: {
3064929595 const msg = try sema.errMsg(
3065029596 inst_src,
3065129597 "runtime coercion from enum '{f}' to union '{f}' which has non-void fields",
30652 .{ tag_ty.fmt(pt), union_ty.fmt(pt) },
29598 .{ enum_ty.fmt(pt), union_ty.fmt(pt) },
3065329599 );
3065429600 errdefer msg.destroy(sema.gpa);
3065529601
3065629602 for (0..union_obj.field_types.len) |field_index| {
30657 const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index];
29603 const field_name = enum_obj.field_names.get(ip)[field_index];
3065829604 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);
30659 if (!(try field_ty.hasRuntimeBitsSema(pt))) continue;
30660 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{f}' has type '{f}'", .{
29605 const ty_description: []const u8 = switch (field_ty.classify(zcu)) {
29606 .one_possible_value => continue,
29607 .no_possible_value => "uninstantiable type",
29608 else => "type",
29609 };
29610 if (field_ty.classify(zcu) == .one_possible_value) continue;
29611 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{f}' has {s} '{f}'", .{
3066129612 field_name.fmt(ip),
29613 ty_description,
3066229614 field_ty.fmt(pt),
3066329615 });
3066429616 }
......@@ -30685,7 +29637,7 @@ fn coerceArrayLike(
3068529637 // try coercion of the whole array
3068629638 const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src, null);
3068729639 if (in_memory_result == .ok) {
30688 if (try sema.resolveValue(inst)) |inst_val| {
29640 if (sema.resolveValue(inst)) |inst_val| {
3068929641 // These types share the same comptime value representation.
3069029642 return sema.coerceInMemory(inst_val, dest_ty);
3069129643 }
......@@ -30708,7 +29660,7 @@ fn coerceArrayLike(
3070829660 }
3070929661
3071029662 const dest_elem_ty = dest_ty.childType(zcu);
30711 if (dest_ty.isVector(zcu) and inst_ty.isVector(zcu) and (try sema.resolveValue(inst)) == null) {
29663 if (dest_ty.isVector(zcu) and inst_ty.isVector(zcu) and sema.resolveValue(inst) == null) {
3071229664 const inst_elem_ty = inst_ty.childType(zcu);
3071329665 switch (dest_elem_ty.zigTypeTag(zcu)) {
3071429666 .int => if (inst_elem_ty.isInt(zcu)) {
......@@ -30748,7 +29700,7 @@ fn coerceArrayLike(
3074829700 const coerced = try sema.coerce(block, dest_elem_ty, elem_ref, elem_src);
3074929701 ref.* = coerced;
3075029702 if (runtime_src == null) {
30751 if (try sema.resolveValue(coerced)) |elem_val| {
29703 if (sema.resolveValue(coerced)) |elem_val| {
3075229704 val.* = elem_val.toIntern();
3075329705 } else {
3075429706 runtime_src = elem_src;
......@@ -30809,7 +29761,7 @@ fn coerceTupleToArray(
3080929761 const coerced = try sema.coerce(block, dest_elem_ty, elem_ref, elem_src);
3081029762 ref.* = coerced;
3081129763 if (runtime_src == null) {
30812 if (try sema.resolveValue(coerced)) |elem_val| {
29764 if (sema.resolveValue(coerced)) |elem_val| {
3081329765 val.* = elem_val.toIntern();
3081429766 } else {
3081529767 runtime_src = elem_src;
......@@ -30845,10 +29797,7 @@ fn coerceTupleToSlicePtrs(
3084529797 .child = slice_info.child,
3084629798 });
3084729799 const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src);
30848 if (slice_info.flags.alignment != .none) {
30849 return sema.fail(block, slice_ty_src, "TODO: override the alignment of the array decl we create here", .{});
30850 }
30851 const ptr_array = try sema.analyzeRef(block, slice_ty_src, array_inst);
29800 const ptr_array = try sema.analyzeRef(block, slice_ty_src, array_inst, slice_info.flags.alignment);
3085229801 return sema.coerceArrayPtrToSlice(block, slice_ty, ptr_array, slice_ty_src);
3085329802}
3085429803
......@@ -30867,10 +29816,7 @@ fn coerceTupleToArrayPtrs(
3086729816 const ptr_info = ptr_array_ty.ptrInfo(zcu);
3086829817 const array_ty: Type = .fromInterned(ptr_info.child);
3086929818 const array_inst = try sema.coerceTupleToArray(block, array_ty, array_ty_src, tuple, tuple_src);
30870 if (ptr_info.flags.alignment != .none) {
30871 return sema.fail(block, array_ty_src, "TODO: override the alignment of the array decl we create here", .{});
30872 }
30873 const ptr_array = try sema.analyzeRef(block, array_ty_src, array_inst);
29819 const ptr_array = try sema.analyzeRef(block, array_ty_src, array_inst, ptr_info.flags.alignment);
3087429820 return ptr_array;
3087529821}
3087629822
......@@ -30904,24 +29850,21 @@ fn coerceTupleToTuple(
3090429850 const field_i: u32 = @intCast(field_index_usize);
3090529851 const field_src = inst_src; // TODO better source location
3090629852
30907 const field_ty = switch (ip.indexToKey(tuple_ty.toIntern())) {
30908 .tuple_type => |tuple_type| tuple_type.types.get(ip)[field_index_usize],
30909 .struct_type => ip.loadStructType(tuple_ty.toIntern()).field_types.get(ip)[field_index_usize],
30910 else => unreachable,
30911 };
30912 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {
30913 .tuple_type => |tuple_type| tuple_type.values.get(ip)[field_index_usize],
30914 .struct_type => ip.loadStructType(tuple_ty.toIntern()).fieldInit(ip, field_index_usize),
30915 else => unreachable,
30916 };
30917
3091829853 const field_index: u32 = @intCast(field_index_usize);
3091929854
29855 const field_ty, const default_val = field: {
29856 const tuple_type = ip.indexToKey(tuple_ty.toIntern()).tuple_type;
29857 break :field .{
29858 tuple_type.types.get(ip)[field_index],
29859 tuple_type.values.get(ip)[field_index],
29860 };
29861 };
29862
3092029863 const elem_ref = try sema.tupleField(block, inst_src, inst, field_src, field_i);
3092129864 const coerced = try sema.coerce(block, .fromInterned(field_ty), elem_ref, field_src);
3092229865 field_refs[field_index] = coerced;
3092329866 if (default_val != .none) {
30924 const init_val = (try sema.resolveValue(coerced)) orelse {
29867 const init_val = sema.resolveValue(coerced) orelse {
3092529868 return sema.failWithNeededComptime(block, field_src, .{ .simple = .stored_to_comptime_field });
3092629869 };
3092729870
......@@ -30930,7 +29873,7 @@ fn coerceTupleToTuple(
3093029873 }
3093129874 }
3093229875 if (runtime_src == null) {
30933 if (try sema.resolveValue(coerced)) |field_val| {
29876 if (sema.resolveValue(coerced)) |field_val| {
3093429877 field_vals[field_index] = field_val.toIntern();
3093529878 } else {
3093629879 runtime_src = field_src;
......@@ -30946,11 +29889,7 @@ fn coerceTupleToTuple(
3094629889 const i: u32 = @intCast(i_usize);
3094729890 if (field_ref.* != .none) continue;
3094829891
30949 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {
30950 .tuple_type => |tuple_type| tuple_type.values.get(ip)[i],
30951 .struct_type => ip.loadStructType(tuple_ty.toIntern()).fieldInit(ip, i),
30952 else => unreachable,
30953 };
29892 const default_val = ip.indexToKey(tuple_ty.toIntern()).tuple_type.values.get(ip)[i];
3095429893
3095529894 const field_src = inst_src; // TODO better source location
3095629895 if (default_val == .none) {
......@@ -30993,7 +29932,7 @@ fn analyzeNavVal(
3099329932 return sema.analyzeLoad(block, src, ref, src);
3099429933}
3099529934
30996fn addReferenceEntry(
29935pub fn addReferenceEntry(
3099729936 sema: *Sema,
3099829937 opt_block: ?*Block,
3099929938 src: LazySrcLoc,
......@@ -31005,7 +29944,6 @@ fn addReferenceEntry(
3100529944 .func => |f| assert(ip.unwrapCoercedFunc(f) == f), // for `.{ .func = f }`, `f` must be uncoerced
3100629945 else => {},
3100729946 }
31008 if (!zcu.comp.config.incremental and zcu.comp.reference_trace == 0) return;
3100929947 const gop = try sema.references.getOrPut(sema.gpa, referenced_unit);
3101029948 if (gop.found_existing) return;
3101129949 try zcu.addUnitReference(sema.owner, referenced_unit, src, inline_frame: {
......@@ -31019,13 +29957,12 @@ fn addReferenceEntry(
3101929957pub fn addTypeReferenceEntry(
3102029958 sema: *Sema,
3102129959 src: LazySrcLoc,
31022 referenced_type: InternPool.Index,
29960 referenced_type: Type,
3102329961) !void {
3102429962 const zcu = sema.pt.zcu;
31025 if (!zcu.comp.config.incremental and zcu.comp.reference_trace == 0) return;
31026 const gop = try sema.type_references.getOrPut(sema.gpa, referenced_type);
29963 const gop = try sema.type_references.getOrPut(sema.gpa, referenced_type.toIntern());
3102729964 if (gop.found_existing) return;
31028 try zcu.addTypeReference(sema.owner, referenced_type, src);
29965 try zcu.addTypeReference(sema.owner, referenced_type.toIntern(), src);
3102929966}
3103029967
3103129968fn ensureMemoizedStateResolved(sema: *Sema, src: LazySrcLoc, stage: InternPool.MemoizedStateStage) SemaError!void {
......@@ -31035,10 +29972,11 @@ fn ensureMemoizedStateResolved(sema: *Sema, src: LazySrcLoc, stage: InternPool.M
3103529972 try sema.addReferenceEntry(null, src, unit);
3103629973 try sema.declareDependency(.{ .memoized_state = stage });
3103729974
29975 const reason: Zcu.DependencyReason = .{ .src = src, .type_layout_reason = undefined };
3103829976 if (pt.zcu.analysis_in_progress.contains(unit)) {
31039 return sema.failWithOwnedErrorMsg(null, try sema.errMsg(src, "dependency loop detected", .{}));
29977 return sema.failWithDependencyLoop(unit, &reason);
3104029978 }
31041 try pt.ensureMemoizedStateUpToDate(stage);
29979 try pt.ensureMemoizedStateUpToDate(stage, &reason);
3104229980}
3104329981
3104429982pub fn ensureNavResolved(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index: InternPool.Nav.Index, kind: enum { type, fully }) CompileError!void {
......@@ -31052,11 +29990,6 @@ pub fn ensureNavResolved(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index:
3105229990 return;
3105329991 }
3105429992
31055 try sema.declareDependency(switch (kind) {
31056 .type => .{ .nav_ty = nav_index },
31057 .fully => .{ .nav_val = nav_index },
31058 });
31059
3106029993 // Note that even if `nav.status == .resolved`, we must still trigger `ensureNavValUpToDate`
3106129994 // to make sure the value is up-to-date on incremental updates.
3106229995
......@@ -31065,32 +29998,37 @@ pub fn ensureNavResolved(sema: *Sema, block: *Block, src: LazySrcLoc, nav_index:
3106529998 .fully => .{ .nav_val = nav_index },
3106629999 });
3106730000 try sema.addReferenceEntry(block, src, anal_unit);
30001 try sema.declareDependency(switch (kind) {
30002 .type => .{ .nav_ty = nav_index },
30003 .fully => .{ .nav_val = nav_index },
30004 });
30005
30006 const reason: Zcu.DependencyReason = .{ .src = src, .type_layout_reason = undefined };
3106830007
3106930008 if (zcu.analysis_in_progress.contains(anal_unit)) {
31070 return sema.failWithOwnedErrorMsg(null, try sema.errMsg(.{
31071 .base_node_inst = nav.analysis.?.zir_index,
31072 .offset = LazySrcLoc.Offset.nodeOffset(.zero),
31073 }, "dependency loop detected", .{}));
30009 return sema.failWithDependencyLoop(anal_unit, &reason);
3107430010 }
3107530011
3107630012 switch (kind) {
3107730013 .type => {
3107830014 try zcu.ensureNavValAnalysisQueued(nav_index);
31079 return pt.ensureNavTypeUpToDate(nav_index);
30015 return pt.ensureNavTypeUpToDate(nav_index, &reason);
3108030016 },
31081 .fully => return pt.ensureNavValUpToDate(nav_index),
30017 .fully => return pt.ensureNavValUpToDate(nav_index, &reason),
3108230018 }
3108330019}
3108430020
3108530021fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
3108630022 const pt = sema.pt;
3108730023 const ptr_anyopaque_ty = try pt.singleConstPtrType(.anyopaque);
31088 return Value.fromInterned(try pt.intern(.{ .opt = .{
31089 .ty = (try pt.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(),
31090 .val = if (opt_val) |val| (try pt.getCoerced(
31091 Value.fromInterned(try pt.refValue(val.toIntern())),
31092 ptr_anyopaque_ty,
31093 )).toIntern() else .none,
30024 const opt_ptr_anyopaque_ty = try pt.optionalType(ptr_anyopaque_ty.toIntern());
30025 return .fromInterned(try pt.intern(.{ .opt = .{
30026 .ty = opt_ptr_anyopaque_ty.toIntern(),
30027 .val = payload: {
30028 const val = opt_val orelse break :payload .none;
30029 const ptr_val = try pt.getCoerced(try pt.uavValue(val), ptr_anyopaque_ty);
30030 break :payload ptr_val.toIntern();
30031 },
3109430032 } }));
3109530033}
3109630034
......@@ -31143,7 +30081,7 @@ fn analyzeNavRefInner(sema: *Sema, block: *Block, src: LazySrcLoc, orig_nav_inde
3114330081 .type_resolved => |r| .{ r.type, r.alignment, r.@"addrspace", r.is_const },
3114430082 .fully_resolved => |r| .{ ip.typeOf(r.val), r.alignment, r.@"addrspace", r.is_const },
3114530083 };
31146 const ptr_ty = try pt.ptrTypeSema(.{
30084 const ptr_ty = try pt.ptrType(.{
3114730085 .child = ty,
3114830086 .flags = .{
3114930087 .alignment = alignment,
......@@ -31185,7 +30123,7 @@ fn maybeQueueFuncBodyAnalysis(sema: *Sema, block: *Block, src: LazySrcLoc, nav_i
3118530123 try sema.ensureNavResolved(block, src, nav_index, .type);
3118630124 const nav_ty: Type = .fromInterned(ip.getNav(nav_index).typeOf(ip));
3118730125 if (nav_ty.zigTypeTag(zcu) != .@"fn") return;
31188 if (!try nav_ty.fnHasRuntimeBitsSema(pt)) return;
30126 if (!nav_ty.fnHasRuntimeBits(zcu)) return;
3118930127
3119030128 try sema.ensureNavResolved(block, src, nav_index, .fully);
3119130129 const nav_val = zcu.navValue(nav_index);
......@@ -31201,34 +30139,48 @@ fn analyzeRef(
3120130139 block: *Block,
3120230140 src: LazySrcLoc,
3120330141 operand: Air.Inst.Ref,
30142 alignment: Alignment,
3120430143) CompileError!Air.Inst.Ref {
3120530144 const pt = sema.pt;
3120630145 const zcu = pt.zcu;
3120730146 const operand_ty = sema.typeOf(operand);
3120830147
31209 if (try sema.resolveValue(operand)) |val| {
30148 const address_space = target_util.defaultAddressSpace(zcu.getTarget(), .local);
30149 const ptr_type = try pt.ptrType(.{
30150 .child = operand_ty.toIntern(),
30151 .flags = .{
30152 .alignment = alignment,
30153 .is_const = true,
30154 .address_space = address_space,
30155 },
30156 });
30157
30158 if (sema.resolveValue(operand)) |val| {
3121030159 switch (zcu.intern_pool.indexToKey(val.toIntern())) {
3121130160 .@"extern" => |e| return sema.analyzeNavRef(block, src, e.owner_nav),
3121230161 .func => |f| return sema.analyzeNavRef(block, src, f.owner_nav),
31213 else => return uavRef(sema, val.toIntern()),
30162 else => return .fromIntern(try pt.intern(.{ .ptr = .{
30163 .ty = ptr_type.toIntern(),
30164 .base_addr = .{ .uav = .{
30165 .val = val.toIntern(),
30166 .orig_ty = ptr_type.toIntern(),
30167 } },
30168 .byte_offset = 0,
30169 } })),
3121430170 }
3121530171 }
3121630172
3121730173 // No `requireRuntimeBlock`; it's okay to `ref` to a runtime value in a comptime context,
3121830174 // it's just that we can only use the *type* of the result, since the value is runtime-known.
3121930175
31220 const address_space = target_util.defaultAddressSpace(zcu.getTarget(), .local);
31221 const ptr_type = try pt.ptrTypeSema(.{
30176 const mut_ptr_type = try pt.ptrType(.{
3122230177 .child = operand_ty.toIntern(),
3122330178 .flags = .{
31224 .is_const = true,
30179 .alignment = alignment,
30180 .is_const = false,
3122530181 .address_space = address_space,
3122630182 },
3122730183 });
31228 const mut_ptr_type = try pt.ptrTypeSema(.{
31229 .child = operand_ty.toIntern(),
31230 .flags = .{ .address_space = address_space },
31231 });
3123230184 const alloc = try block.addTy(.alloc, mut_ptr_type);
3123330185
3123430186 // In a comptime context, the store would fail, since the operand is runtime-known. But that's
......@@ -31257,13 +30209,18 @@ fn analyzeLoad(
3125730209 .pointer => ptr_ty.childType(zcu),
3125830210 else => return sema.fail(block, ptr_src, "expected pointer, found '{f}'", .{ptr_ty.fmt(pt)}),
3125930211 };
31260 if (elem_ty.zigTypeTag(zcu) == .@"opaque") {
31261 return sema.fail(block, ptr_src, "cannot load opaque type '{f}'", .{elem_ty.fmt(pt)});
31262 }
3126330212
31264 if (try sema.typeHasOnePossibleValue(elem_ty)) |opv| {
31265 return Air.internedToRef(opv.toIntern());
31266 }
30213 try sema.ensureLayoutResolved(elem_ty, src, .ptr_access);
30214
30215 const comptime_only = switch (elem_ty.classify(zcu)) {
30216 .no_possible_value => switch (elem_ty.zigTypeTag(zcu)) {
30217 .@"opaque" => return sema.fail(block, src, "cannot load opaque type '{f}'", .{elem_ty.fmt(pt)}),
30218 else => return sema.fail(block, src, "cannot load uninstantiable type '{f}'", .{elem_ty.fmt(pt)}),
30219 },
30220 .one_possible_value => return .fromValue((try elem_ty.onePossibleValue(pt)).?),
30221 .runtime => false,
30222 .partially_comptime, .fully_comptime => true,
30223 };
3126730224
3126830225 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| {
3126930226 if (try sema.pointerDeref(block, src, ptr_val, ptr_ty)) |elem_val| {
......@@ -31271,6 +30228,13 @@ fn analyzeLoad(
3127130228 }
3127230229 }
3127330230
30231 if (comptime_only) return sema.failWithOwnedErrorMsg(block, msg: {
30232 const msg = try sema.errMsg(src, "cannot load comptime-only type '{f}'", .{elem_ty.fmt(pt)});
30233 errdefer msg.destroy(zcu.gpa);
30234 try sema.errNote(ptr_src, msg, "pointer of type '{f}' is runtime-known", .{ptr_ty.fmt(pt)});
30235 break :msg msg;
30236 });
30237
3127430238 return block.addTyOp(.load, elem_ty, ptr);
3127530239}
3127630240
......@@ -31284,7 +30248,7 @@ fn analyzeSlicePtr(
3128430248 const pt = sema.pt;
3128530249 const zcu = pt.zcu;
3128630250 const result_ty = slice_ty.slicePtrFieldType(zcu);
31287 if (try sema.resolveValue(slice)) |val| {
30251 if (sema.resolveValue(slice)) |val| {
3128830252 if (val.isUndef(zcu)) return pt.undefRef(result_ty);
3128930253 return Air.internedToRef(val.slicePtr(zcu).toIntern());
3129030254 }
......@@ -31304,7 +30268,7 @@ fn analyzeOptionalSlicePtr(
3130430268 const slice_ty = opt_slice_ty.optionalChild(zcu);
3130530269 const result_ty = slice_ty.slicePtrFieldType(zcu);
3130630270
31307 if (try sema.resolveValue(opt_slice)) |opt_val| {
30271 if (sema.resolveValue(opt_slice)) |opt_val| {
3130830272 if (opt_val.isUndef(zcu)) return pt.undefRef(result_ty);
3130930273 const slice_ptr: InternPool.Index = if (opt_val.optionalValue(zcu)) |val|
3131030274 val.slicePtr(zcu).toIntern()
......@@ -31328,11 +30292,11 @@ fn analyzeSliceLen(
3132830292) CompileError!Air.Inst.Ref {
3132930293 const pt = sema.pt;
3133030294 const zcu = pt.zcu;
31331 if (try sema.resolveValue(slice_inst)) |slice_val| {
30295 if (sema.resolveValue(slice_inst)) |slice_val| {
3133230296 if (slice_val.isUndef(zcu)) {
3133330297 return .undef_usize;
3133430298 }
31335 return pt.intRef(.usize, try slice_val.sliceLen(pt));
30299 return pt.intRef(.usize, slice_val.sliceLen(zcu));
3133630300 }
3133730301 try sema.requireRuntimeBlock(block, src, null);
3133830302 return block.addTyOp(.slice_len, .usize, slice_inst);
......@@ -31341,25 +30305,25 @@ fn analyzeSliceLen(
3134130305fn analyzeIsNull(
3134230306 sema: *Sema,
3134330307 block: *Block,
30308 src: LazySrcLoc,
3134430309 operand: Air.Inst.Ref,
3134530310 invert_logic: bool,
3134630311) CompileError!Air.Inst.Ref {
3134730312 const pt = sema.pt;
3134830313 const zcu = pt.zcu;
31349 const result_ty: Type = .bool;
31350 if (try sema.resolveValue(operand)) |opt_val| {
30314
30315 if (try sema.resolveIsNullFromType(block, src, sema.typeOf(operand))) |is_null| {
30316 return .fromValue(.makeBool(is_null != invert_logic)); // XOR
30317 }
30318
30319 if (sema.resolveValue(operand)) |opt_val| {
3135130320 if (opt_val.isUndef(zcu)) {
31352 return pt.undefRef(result_ty);
30321 return pt.undefRef(.bool);
3135330322 }
3135430323 const is_null = opt_val.isNull(zcu);
31355 const bool_value = if (invert_logic) !is_null else is_null;
31356 return if (bool_value) .bool_true else .bool_false;
30324 return .fromValue(.makeBool(is_null != invert_logic)); // XOR
3135730325 }
3135830326
31359 if (sema.typeOf(operand).isNullFromType(zcu)) |is_null| {
31360 const result = is_null != invert_logic;
31361 return if (result) .bool_true else .bool_false;
31362 }
3136330327 const air_tag: Air.Inst.Tag = if (invert_logic) .is_non_null else .is_null;
3136430328 return block.addUnOp(air_tag, operand);
3136530329}
......@@ -31381,7 +30345,7 @@ fn resolvePtrIsNonErrVal(
3138130345 }
3138230346 assert(child_ty.zigTypeTag(zcu) == .error_union);
3138330347
31384 if (try sema.resolveValue(operand)) |eu_ptr_val| {
30348 if (sema.resolveValue(operand)) |eu_ptr_val| {
3138530349 if (eu_ptr_val.isUndef(zcu)) return .undef_bool;
3138630350 if (try sema.pointerDeref(block, src, eu_ptr_val, ptr_ty)) |err_union| {
3138730351 if (err_union.isUndef(zcu)) return .undef_bool;
......@@ -31404,7 +30368,7 @@ fn resolveIsNonErrVal(
3140430368 }
3140530369 assert(sema.typeOf(operand).zigTypeTag(zcu) == .error_union);
3140630370
31407 if (try sema.resolveValue(operand)) |err_union| {
30371 if (sema.resolveValue(operand)) |err_union| {
3140830372 if (err_union.isUndef(zcu)) return .undef_bool;
3140930373 return .makeBool(err_union.getErrorName(zcu) == .none);
3141030374 }
......@@ -31412,6 +30376,35 @@ fn resolveIsNonErrVal(
3141230376 return null;
3141330377}
3141430378
30379fn resolveIsNullFromType(
30380 sema: *Sema,
30381 block: *Block,
30382 src: LazySrcLoc,
30383 ty: Type,
30384) CompileError!?bool {
30385 const zcu = sema.pt.zcu;
30386 return switch (ty.zigTypeTag(zcu)) {
30387 else => false,
30388 .null => true,
30389 .pointer => switch (ty.ptrSize(zcu)) {
30390 .c => null,
30391 else => false,
30392 },
30393 .optional => {
30394 const payload_ty = ty.optionalChild(zcu);
30395 if (payload_ty.classify(zcu) == .no_possible_value) {
30396 return true; // e.g. `?noreturn`
30397 }
30398 if (payload_ty.zigTypeTag(zcu) == .error_set and
30399 try sema.resolveErrSetIsEmpty(block, src, payload_ty))
30400 {
30401 return true; // e.g. `?error{}`
30402 }
30403 return null;
30404 },
30405 };
30406}
30407
3141530408fn resolveIsNonErrFromType(
3141630409 sema: *Sema,
3141730410 block: *Block,
......@@ -31420,89 +30413,71 @@ fn resolveIsNonErrFromType(
3142030413) CompileError!?Value {
3142130414 const pt = sema.pt;
3142230415 const zcu = pt.zcu;
31423 const ip = &zcu.intern_pool;
3142430416 const ot = operand_ty.zigTypeTag(zcu);
3142530417 if (ot != .error_set and ot != .error_union) return .true;
3142630418 if (ot == .error_set) return .false;
3142730419 assert(ot == .error_union);
3142830420
3142930421 const payload_ty = operand_ty.errorUnionPayload(zcu);
31430 if (payload_ty.zigTypeTag(zcu) == .noreturn) {
30422 if (payload_ty.classify(zcu) == .no_possible_value) {
3143130423 return .false;
3143230424 }
30425 if (try sema.resolveErrSetIsEmpty(block, src, operand_ty.errorUnionSet(zcu))) {
30426 return .true;
30427 }
30428 return null;
30429}
3143330430
31434 // exception if the error union error set is known to be empty,
31435 // we allow the comparison but always make it comptime-known.
31436 const set_ty = ip.errorUnionSet(operand_ty.toIntern());
31437 switch (set_ty) {
31438 .anyerror_type => {},
31439 .adhoc_inferred_error_set_type => if (sema.fn_ret_ty_ies) |ies| blk: {
31440 // If the error set is empty, we must return a comptime true or false.
31441 // However we want to avoid unnecessarily resolving an inferred error set
31442 // in case it is already non-empty.
31443 switch (ies.resolved) {
31444 .anyerror_type => break :blk,
31445 .none => {},
31446 else => |i| if (ip.indexToKey(i).error_set_type.names.len != 0) break :blk,
31447 }
31448
31449 if (ies.errors.count() != 0) return null;
31450 switch (ies.resolved) {
31451 .anyerror_type => return null,
31452 .none => {},
31453 else => switch (ip.indexToKey(ies.resolved).error_set_type.names.len) {
31454 0 => return .true,
31455 else => return null,
31456 },
31457 }
31458 // We do not have a comptime answer because this inferred error
31459 // set is not resolved, and an instruction later in this function
31460 // body may or may not cause an error to be added to this set.
31461 return null;
31462 },
31463 else => switch (ip.indexToKey(set_ty)) {
31464 .error_set_type => |error_set_type| {
31465 if (error_set_type.names.len == 0) return .true;
31466 },
31467 .inferred_error_set_type => |func_index| blk: {
31468 // If the error set is empty, we must return a comptime true or false.
31469 // However we want to avoid unnecessarily resolving an inferred error set
31470 // in case it is already non-empty.
31471 try zcu.maybeUnresolveIes(func_index);
31472 switch (ip.funcIesResolvedUnordered(func_index)) {
31473 .anyerror_type => break :blk,
31474 .none => {},
31475 else => |i| if (ip.indexToKey(i).error_set_type.names.len != 0) break :blk,
31476 }
30431/// Returns `true` iff the error set type `orig_err_set_ty` contains no errors.
30432///
30433/// This is used to give comptime answers for whether `error{}!T` is an error or a payload, as well
30434/// as whether `?error{}` is null. The type `error{}` cannot be NPV, as it has runtime bits, but the
30435/// only value of that type which can exist is `undefined`; semantically it has no "legal" value.
30436/// TODO: this runs into some unsolved language design questions about such types. Performing a
30437/// coercion from `@as(E, undefined)` to `E!T` needs to semantically result in an `undefined` error
30438/// union if our implementation is to be legal, and likewise for coercing `@as(E, undefined)` to
30439/// `?E` (for an error set `E`) because our implementation uses the zero error value at runtime to
30440/// represent `null`. The unsolved problem is the exact rules for `undefined` propagation through
30441/// these types: for instance, what if `@as(u32, undfined)` is coerced to `?u32`? What about error
30442/// union *payloads*, i.e. `@as(u32, undefined)` to `E!u32`? That one is analagous to the optional
30443/// example in some ways, but right now I believe there is code which relies on that coercion giving
30444/// a well-defined error union with an `undefined` payload.
30445/// Relevant issues/discussions:
30446/// * https://github.com/ziglang/zig/issues/1831
30447/// * https://github.com/ziglang/zig/issues/6762
30448/// * https://github.com/ziglang/zig/issues/1831#issuecomment-722129239
30449fn resolveErrSetIsEmpty(
30450 sema: *Sema,
30451 block: *Block,
30452 src: LazySrcLoc,
30453 orig_err_set_ty: Type,
30454) CompileError!bool {
30455 const ip = &sema.pt.zcu.intern_pool;
30456 err_set: switch (orig_err_set_ty.toIntern()) {
30457 .anyerror_type => return false,
30458 .adhoc_inferred_error_set_type => {
30459 // This is *our* error set; that is, we're currently analyzing the function
30460 // which owns it. Trying to resolve it now would cause a dependency loop.
30461 // Instead, accept that we don't know.
30462 return false;
30463 },
30464 else => |err_set_ty| switch (ip.indexToKey(err_set_ty)) {
30465 .error_set_type => |es| return es.names.len == 0,
30466 .inferred_error_set_type => |func_index| {
3147730467 if (sema.fn_ret_ty_ies) |ies| {
3147830468 if (ies.func == func_index) {
31479 // Try to avoid resolving inferred error set if possible.
31480 if (ies.errors.count() != 0) return null;
31481 switch (ies.resolved) {
31482 .anyerror_type => return null,
31483 .none => {},
31484 else => switch (ip.indexToKey(ies.resolved).error_set_type.names.len) {
31485 0 => return .true,
31486 else => return null,
31487 },
31488 }
31489 // We do not have a comptime answer because this inferred error
31490 // set is not resolved, and an instruction later in this function
31491 // body may or may not cause an error to be added to this set.
31492 return null;
30469 // This is *our* error set; that is, we're currently analyzing the function
30470 // which owns it. Trying to resolve it now would cause a dependency loop.
30471 // Instead, accept that we don't know.
30472 return false;
3149330473 }
3149430474 }
31495 const resolved_ty = try sema.resolveInferredErrorSet(block, src, set_ty);
31496 if (resolved_ty == .anyerror_type)
31497 break :blk;
31498 if (ip.indexToKey(resolved_ty).error_set_type.names.len == 0)
31499 return .true;
30475 try sema.ensureFuncIesResolved(block, src, func_index);
30476 continue :err_set ip.funcIesResolvedUnordered(func_index);
3150030477 },
3150130478 else => unreachable,
3150230479 },
3150330480 }
31504
31505 return null;
3150630481}
3150730482
3150830483fn analyzeIsNonErr(
......@@ -31682,6 +30657,8 @@ fn analyzeSlice(
3168230657 else => return sema.fail(block, src, "slice of non-array type '{f}'", .{ptr_ptr_child_ty.fmt(pt)}),
3168330658 }
3168430659
30660 try sema.ensureLayoutResolved(elem_ty, src, .ptr_access);
30661
3168530662 const ptr = if (slice_ty.isSlice(zcu))
3168630663 try sema.analyzeSlicePtr(block, ptr_src, ptr_or_slice, slice_ty)
3168730664 else if (array_ty.zigTypeTag(zcu) == .array) ptr: {
......@@ -31690,11 +30667,11 @@ fn analyzeSlice(
3169030667 assert(manyptr_ty_key.flags.size == .one);
3169130668 manyptr_ty_key.child = elem_ty.toIntern();
3169230669 manyptr_ty_key.flags.size = .many;
31693 break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrTypeSema(manyptr_ty_key), ptr_or_slice, ptr_src);
30670 break :ptr try sema.coerceCompatiblePtrs(block, try pt.ptrType(manyptr_ty_key), ptr_or_slice, ptr_src);
3169430671 } else ptr_or_slice;
3169530672
3169630673 const start = try sema.coerce(block, .usize, uncasted_start, start_src);
31697 const new_ptr = try sema.analyzePtrArithmetic(block, src, ptr, start, .ptr_add, ptr_src, start_src);
30674 const new_ptr = try sema.analyzePtrArithmetic(block, src, ptr, start, .ptr_add, start_src);
3169830675 const new_ptr_ty = sema.typeOf(new_ptr);
3169930676
3170030677 // true if and only if the end index of the slice, implicitly or explicitly, equals
......@@ -31754,12 +30731,12 @@ fn analyzeSlice(
3175430731 break :end try sema.coerce(block, .usize, uncasted_end, end_src);
3175530732 } else try sema.coerce(block, .usize, uncasted_end_opt, end_src);
3175630733 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {
31757 if (try sema.resolveValue(ptr_or_slice)) |slice_val| {
30734 if (sema.resolveValue(ptr_or_slice)) |slice_val| {
3175830735 if (slice_val.isUndef(zcu)) {
3175930736 return sema.fail(block, src, "slice of undefined", .{});
3176030737 }
3176130738 const has_sentinel = slice_ty.sentinel(zcu) != null;
31762 const slice_len = try slice_val.sliceLen(pt);
30739 const slice_len = slice_val.sliceLen(zcu);
3176330740 const len_plus_sent = slice_len + @intFromBool(has_sentinel);
3176430741 const slice_len_val_with_sentinel = try pt.intValue(.usize, len_plus_sent);
3176530742 if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, .usize))) {
......@@ -31774,7 +30751,7 @@ fn analyzeSlice(
3177430751 "end index {f} out of bounds for slice of length {d}{s}",
3177530752 .{
3177630753 end_val.fmtValueSema(pt, sema),
31777 try slice_val.sliceLen(pt),
30754 slice_val.sliceLen(zcu),
3177830755 sentinel_label,
3177930756 },
3178030757 );
......@@ -31832,7 +30809,7 @@ fn analyzeSlice(
3183230809 break :msg msg;
3183330810 });
3183430811 }
31835 return sema.analyzePtrArithmetic(block, src, ptr, start, .ptr_add, ptr_src, start_src);
30812 return sema.analyzePtrArithmetic(block, src, ptr, start, .ptr_add, start_src);
3183630813 };
3183730814
3183830815 const sentinel = s: {
......@@ -31876,7 +30853,7 @@ fn analyzeSlice(
3187630853 );
3187730854 }
3187830855 checked_start_lte_end = true;
31879 if (try sema.resolveValue(new_ptr)) |ptr_val| sentinel_check: {
30856 if (sema.resolveValue(new_ptr)) |ptr_val| sentinel_check: {
3188030857 const expected_sentinel = sentinel orelse break :sentinel_check;
3188130858 const start_int = start_val.toUnsignedInt(zcu);
3188230859 const end_int = end_val.toUnsignedInt(zcu);
......@@ -31943,9 +30920,9 @@ fn analyzeSlice(
3194330920 const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(zcu) != .c;
3194430921
3194530922 if (opt_new_len_val) |new_len_val| {
31946 const new_len_int = try new_len_val.toUnsignedIntSema(pt);
30923 const new_len_int = new_len_val.toUnsignedInt(zcu);
3194730924
31948 const return_ty = try pt.ptrTypeSema(.{
30925 const return_ty = try pt.ptrType(.{
3194930926 .child = (try pt.arrayType(.{
3195030927 .len = new_len_int,
3195130928 .sentinel = if (sentinel) |s| s.toIntern() else .none,
......@@ -31960,13 +30937,13 @@ fn analyzeSlice(
3196030937 },
3196130938 });
3196230939
31963 const opt_new_ptr_val = try sema.resolveValue(new_ptr);
30940 const opt_new_ptr_val = sema.resolveValue(new_ptr);
3196430941 const new_ptr_val = opt_new_ptr_val orelse {
3196530942 const result = try block.addBitCast(return_ty, new_ptr);
3196630943 if (block.wantSafety()) {
3196730944 // requirement: slicing C ptr is non-null
3196830945 if (ptr_ptr_child_ty.isCPtr(zcu)) {
31969 const is_non_null = try sema.analyzeIsNull(block, ptr, true);
30946 const is_non_null = try block.addUnOp(.is_non_null, ptr);
3197030947 try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null);
3197130948 }
3197230949
......@@ -32009,7 +30986,7 @@ fn analyzeSlice(
3200930986 return sema.fail(block, src, "non-zero length slice of undefined pointer", .{});
3201030987 }
3201130988
32012 const return_ty = try pt.ptrTypeSema(.{
30989 const return_ty = try pt.ptrType(.{
3201330990 .child = elem_ty.toIntern(),
3201430991 .sentinel = if (sentinel) |s| s.toIntern() else .none,
3201530992 .flags = .{
......@@ -32026,7 +31003,7 @@ fn analyzeSlice(
3202631003 if (block.wantSafety()) {
3202731004 // requirement: slicing C ptr is non-null
3202831005 if (ptr_ptr_child_ty.isCPtr(zcu)) {
32029 const is_non_null = try sema.analyzeIsNull(block, ptr, true);
31006 const is_non_null = try block.addUnOp(.is_non_null, ptr);
3203031007 try sema.addSafetyCheck(block, src, is_non_null, .unwrap_null);
3203131008 }
3203231009
......@@ -32037,7 +31014,7 @@ fn analyzeSlice(
3203731014 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {
3203831015 // we don't need to add one for sentinels because the
3203931016 // underlying value data includes the sentinel
32040 break :blk try pt.intRef(.usize, try slice_val.sliceLen(pt));
31017 break :blk try pt.intRef(.usize, slice_val.sliceLen(zcu));
3204131018 }
3204231019
3204331020 const slice_len_inst = try block.addTyOp(.slice_len, .usize, ptr_or_slice);
......@@ -32107,8 +31084,8 @@ fn cmpNumeric(
3210731084 else
3210831085 uncasted_rhs;
3210931086
32110 const maybe_lhs_val = try sema.resolveValue(lhs);
32111 const maybe_rhs_val = try sema.resolveValue(rhs);
31087 const maybe_lhs_val = sema.resolveValue(lhs);
31088 const maybe_rhs_val = sema.resolveValue(rhs);
3211231089
3211331090 // If the LHS is const, check if there is a guaranteed result which does not depend on ths RHS value.
3211431091 if (maybe_lhs_val) |lhs_val| {
......@@ -32158,16 +31135,10 @@ fn cmpNumeric(
3215831135
3215931136 const runtime_src: LazySrcLoc = if (maybe_lhs_val) |lhs_val| rs: {
3216031137 if (maybe_rhs_val) |rhs_val| {
32161 const res = try Value.compareHeteroSema(lhs_val, op, rhs_val, pt);
32162 return if (res) .bool_true else .bool_false;
31138 return .fromValue(.makeBool(Value.compareHetero(lhs_val, op, rhs_val, zcu)));
3216331139 } else break :rs rhs_src;
3216431140 } else lhs_src;
3216531141
32166 // TODO handle comparisons against lazy zero values
32167 // Some values can be compared against zero without being runtime-known or without forcing
32168 // a full resolution of their value, for example `@sizeOf(@Frame(function))` is known to
32169 // always be nonzero, and we benefit from not forcing the full evaluation and stack frame layout
32170 // of this function if we don't need to.
3217131142 try sema.requireRuntimeBlock(block, src, runtime_src);
3217231143
3217331144 // For floats, emit a float comparison instruction.
......@@ -32207,11 +31178,11 @@ fn cmpNumeric(
3220731178 // a signed integer with mantissa bits + 1, and if there was any non-integral part of the float,
3220831179 // add/subtract 1.
3220931180 const lhs_is_signed = if (maybe_lhs_val) |lhs_val|
32210 !(try lhs_val.compareAllWithZeroSema(.gte, pt))
31181 !lhs_val.compareAllWithZero(.gte, zcu)
3221131182 else
3221231183 (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt(zcu));
3221331184 const rhs_is_signed = if (maybe_rhs_val) |rhs_val|
32214 !(try rhs_val.compareAllWithZeroSema(.gte, pt))
31185 !rhs_val.compareAllWithZero(.gte, zcu)
3221531186 else
3221631187 (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt(zcu));
3221731188 const dest_int_is_signed = lhs_is_signed or rhs_is_signed;
......@@ -32219,10 +31190,9 @@ fn cmpNumeric(
3221931190 var dest_float_type: ?Type = null;
3222031191
3222131192 var lhs_bits: usize = undefined;
32222 if (maybe_lhs_val) |unresolved_lhs_val| {
32223 const lhs_val = try sema.resolveLazyValue(unresolved_lhs_val);
31193 if (maybe_lhs_val) |lhs_val| {
3222431194 if (!rhs_is_signed) {
32225 switch (lhs_val.orderAgainstZero(zcu)) {
31195 switch (Value.order(lhs_val, .zero_comptime_int, zcu)) {
3222631196 .gt => {},
3222731197 .eq => switch (op) { // LHS = 0, RHS is unsigned
3222831198 .lte => return .bool_true,
......@@ -32263,10 +31233,9 @@ fn cmpNumeric(
3226331233 }
3226431234
3226531235 var rhs_bits: usize = undefined;
32266 if (maybe_rhs_val) |unresolved_rhs_val| {
32267 const rhs_val = try sema.resolveLazyValue(unresolved_rhs_val);
31236 if (maybe_rhs_val) |rhs_val| {
3226831237 if (!lhs_is_signed) {
32269 switch (rhs_val.orderAgainstZero(zcu)) {
31238 switch (Value.order(rhs_val, .zero_comptime_int, zcu)) {
3227031239 .gt => {},
3227131240 .eq => switch (op) { // RHS = 0, LHS is unsigned
3227231241 .gte => return .bool_true,
......@@ -32328,7 +31297,7 @@ fn compareIntsOnlyPossibleResult(
3232831297 lhs_val: Value,
3232931298 op: std.math.CompareOperator,
3233031299 rhs_ty: Type,
32331) SemaError!?bool {
31300) Allocator.Error!?bool {
3233231301 const pt = sema.pt;
3233331302 const zcu = pt.zcu;
3233431303
......@@ -32337,11 +31306,11 @@ fn compareIntsOnlyPossibleResult(
3233731306
3233831307 if (min_rhs.toIntern() == max_rhs.toIntern()) {
3233931308 // RHS is effectively comptime-known.
32340 return try Value.compareHeteroSema(lhs_val, op, min_rhs, pt);
31309 return Value.compareHetero(lhs_val, op, min_rhs, zcu);
3234131310 }
3234231311
32343 const against_min = try lhs_val.orderAdvanced(min_rhs, .sema, zcu, pt.tid);
32344 const against_max = try lhs_val.orderAdvanced(max_rhs, .sema, zcu, pt.tid);
31312 const against_min = lhs_val.order(min_rhs, zcu);
31313 const against_max = lhs_val.order(max_rhs, zcu);
3234531314
3234631315 switch (op) {
3234731316 .eq => {
......@@ -32401,8 +31370,8 @@ fn cmpVector(
3240131370 .child = .bool_type,
3240231371 });
3240331372
32404 const maybe_lhs_val = try sema.resolveValue(casted_lhs);
32405 const maybe_rhs_val = try sema.resolveValue(casted_rhs);
31373 const maybe_lhs_val = sema.resolveValue(casted_lhs);
31374 const maybe_rhs_val = sema.resolveValue(casted_rhs);
3240631375 if (maybe_lhs_val) |v| if (v.isUndef(zcu)) return pt.undefRef(result_ty);
3240731376 if (maybe_rhs_val) |v| if (v.isUndef(zcu)) return pt.undefRef(result_ty);
3240831377
......@@ -32424,7 +31393,7 @@ fn wrapOptional(
3242431393 inst: Air.Inst.Ref,
3242531394 inst_src: LazySrcLoc,
3242631395) !Air.Inst.Ref {
32427 if (try sema.resolveValue(inst)) |val| {
31396 if (sema.resolveValue(inst)) |val| {
3242831397 return Air.internedToRef((try sema.pt.intern(.{ .opt = .{
3242931398 .ty = dest_ty.toIntern(),
3243031399 .val = val.toIntern(),
......@@ -32446,7 +31415,7 @@ fn wrapErrorUnionPayload(
3244631415 const zcu = pt.zcu;
3244731416 const dest_payload_ty = dest_ty.errorUnionPayload(zcu);
3244831417 const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, .{ .report_err = false });
32449 if (try sema.resolveValue(coerced)) |val| {
31418 if (sema.resolveValue(coerced)) |val| {
3245031419 return Air.internedToRef((try pt.intern(.{ .error_union = .{
3245131420 .ty = dest_ty.toIntern(),
3245231421 .val = .{ .payload = val.toIntern() },
......@@ -32466,80 +31435,40 @@ fn wrapErrorUnionSet(
3246631435 const pt = sema.pt;
3246731436 const zcu = pt.zcu;
3246831437 const ip = &zcu.intern_pool;
32469 const inst_ty = sema.typeOf(inst);
3247031438 const dest_err_set_ty = dest_ty.errorUnionSet(zcu);
32471 if (try sema.resolveValue(inst)) |val| {
32472 const expected_name = zcu.intern_pool.indexToKey(val.toIntern()).err.name;
32473 switch (dest_err_set_ty.toIntern()) {
32474 .anyerror_type => {},
32475 .adhoc_inferred_error_set_type => ok: {
32476 const ies = sema.fn_ret_ty_ies.?;
32477 switch (ies.resolved) {
32478 .anyerror_type => break :ok,
32479 .none => if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) {
32480 break :ok;
32481 },
32482 else => |i| if (ip.indexToKey(i).error_set_type.nameIndex(ip, expected_name) != null) {
32483 break :ok;
32484 },
32485 }
32486 return sema.failWithTypeMismatch(block, inst_src, dest_err_set_ty, inst_ty);
32487 },
32488 else => switch (ip.indexToKey(dest_err_set_ty.toIntern())) {
32489 .error_set_type => |error_set_type| ok: {
32490 if (error_set_type.nameIndex(ip, expected_name) != null) break :ok;
32491 return sema.failWithTypeMismatch(block, inst_src, dest_err_set_ty, inst_ty);
32492 },
32493 .inferred_error_set_type => |func_index| ok: {
32494 // We carefully do this in an order that avoids unnecessarily
32495 // resolving the destination error set type.
32496 try zcu.maybeUnresolveIes(func_index);
32497 switch (ip.funcIesResolvedUnordered(func_index)) {
32498 .anyerror_type => break :ok,
32499 .none => if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) {
32500 break :ok;
32501 },
32502 else => |i| if (ip.indexToKey(i).error_set_type.nameIndex(ip, expected_name) != null) {
32503 break :ok;
32504 },
32505 }
32506
32507 return sema.failWithTypeMismatch(block, inst_src, dest_err_set_ty, inst_ty);
32508 },
32509 else => unreachable,
32510 },
32511 }
32512 return Air.internedToRef((try pt.intern(.{ .error_union = .{
31439 const coerced = try sema.coerceExtra(block, dest_err_set_ty, inst, inst_src, .{ .report_err = false });
31440 if (try sema.resolveDefinedValue(block, inst_src, coerced)) |error_val| {
31441 return .fromIntern(try pt.intern(.{ .error_union = .{
3251331442 .ty = dest_ty.toIntern(),
32514 .val = .{ .err_name = expected_name },
32515 } })));
31443 .val = .{ .err_name = ip.indexToKey(error_val.toIntern()).err.name },
31444 } }));
31445 } else {
31446 return block.addTyOp(.wrap_errunion_err, dest_ty, coerced);
3251631447 }
32517
32518 try sema.requireRuntimeBlock(block, inst_src, null);
32519 const coerced = try sema.coerce(block, dest_err_set_ty, inst, inst_src);
32520 return block.addTyOp(.wrap_errunion_err, dest_ty, coerced);
3252131448}
3252231449
32523fn unionToTag(
32524 sema: *Sema,
32525 block: *Block,
32526 enum_ty: Type,
32527 un: Air.Inst.Ref,
32528 un_src: LazySrcLoc,
32529) !Air.Inst.Ref {
31450/// Returns the enum tag value for the active tag of a tagged union value.
31451///
31452/// Asserts that the type of `un` is a tagged union type.
31453fn unionToTag(sema: *Sema, block: *Block, un: Air.Inst.Ref) !Air.Inst.Ref {
3253031454 const pt = sema.pt;
3253131455 const zcu = pt.zcu;
32532 if ((try sema.typeHasOnePossibleValue(enum_ty))) |opv| {
32533 return Air.internedToRef(opv.toIntern());
31456 const ip = &zcu.intern_pool;
31457 const union_obj = ip.loadUnionType(sema.typeOf(un).toIntern());
31458 assert(union_obj.tag_usage == .tagged);
31459 if (sema.resolveValue(un)) |un_val| {
31460 return .fromValue(un_val.unionTag(zcu).?);
3253431461 }
32535 if (try sema.resolveValue(un)) |un_val| {
32536 const tag_val = un_val.unionTag(zcu).?;
32537 if (tag_val.isUndef(zcu))
32538 return try pt.undefRef(enum_ty);
32539 return Air.internedToRef(tag_val.toIntern());
31462 const enum_tag_ty: Type = .fromInterned(union_obj.enum_tag_type);
31463 if (!union_obj.has_runtime_tag) {
31464 // This means that only one field is possible.
31465 const field_index = for (union_obj.field_types.get(ip), 0..) |field_ty_ip, field_index| {
31466 const field_ty: Type = .fromInterned(field_ty_ip);
31467 if (field_ty.classify(zcu) != .no_possible_value) break field_index;
31468 } else unreachable;
31469 return .fromValue(try pt.enumValueFieldIndex(enum_tag_ty, @intCast(field_index)));
3254031470 }
32541 try sema.requireRuntimeBlock(block, un_src, null);
32542 return block.addTyOp(.get_union_tag, enum_ty, un);
31471 return block.addTyOp(.get_union_tag, enum_tag_ty, un);
3254331472}
3254431473
3254531474const PeerResolveStrategy = enum {
......@@ -32879,7 +31808,7 @@ fn resolvePeerTypes(
3287931808
3288031809 for (instructions, peer_tys, peer_vals) |inst, *ty, *val| {
3288131810 ty.* = sema.typeOf(inst);
32882 val.* = try sema.resolveValue(inst);
31811 val.* = sema.resolveValue(inst);
3288331812 }
3288431813
3288531814 switch (try sema.resolvePeerTypesInner(block, src, peer_tys, peer_vals)) {
......@@ -33240,18 +32169,24 @@ fn resolvePeerTypesInner(
3324032169 ptr_info.sentinel = .none;
3324132170 }
3324232171
33243 // Note that the align can be always non-zero; Zcu.ptrType will canonicalize it
33244 ptr_info.flags.alignment = InternPool.Alignment.min(
33245 if (ptr_info.flags.alignment != .none)
33246 ptr_info.flags.alignment
33247 else
33248 Type.fromInterned(ptr_info.child).abiAlignment(zcu),
33249
33250 if (peer_info.flags.alignment != .none)
33251 peer_info.flags.alignment
33252 else
33253 Type.fromInterned(peer_info.child).abiAlignment(zcu),
33254 );
32172 ptr_info.flags.alignment = a: {
32173 // If both alignments are implicit, the result alignment is implicit.
32174 // e.g. '[*c]u32' + '[*c]c_uint' -> '[*c]u32'
32175 if (ptr_info.flags.alignment == .none and peer_info.flags.alignment == .none) {
32176 break :a .none;
32177 }
32178 // Otherwise (if either alignment is explicit), the result alignment is explicit.
32179 // e.g. '[*c]u32' + '[*c]align(4) c_uint' -> '[*c]align(4) u32'
32180 const cur_align = switch (ptr_info.flags.alignment) {
32181 .none => Type.fromInterned(ptr_info.child).abiAlignment(zcu),
32182 else => ptr_info.flags.alignment,
32183 };
32184 const new_align = switch (peer_info.flags.alignment) {
32185 .none => Type.fromInterned(peer_info.child).abiAlignment(zcu),
32186 else => peer_info.flags.alignment,
32187 };
32188 break :a .minStrict(cur_align, new_align);
32189 };
3325532190 if (ptr_info.flags.address_space != peer_info.flags.address_space) {
3325632191 return .{ .conflict = .{
3325732192 .peer_idx_a = first_idx,
......@@ -33273,7 +32208,7 @@ fn resolvePeerTypesInner(
3327332208
3327432209 opt_ptr_info = ptr_info;
3327532210 }
33276 return .{ .success = try pt.ptrTypeSema(opt_ptr_info.?) };
32211 return .{ .success = try pt.ptrType(opt_ptr_info.?) };
3327732212 },
3327832213
3327932214 .ptr => {
......@@ -33281,7 +32216,6 @@ fn resolvePeerTypesInner(
3328132216 // if there were no actual slices. Else, we want the slice index to report a conflict.
3328232217 var opt_slice_idx: ?usize = null;
3328332218
33284 var any_abi_aligned = false;
3328532219 var opt_ptr_info: ?InternPool.Key.PtrType = null;
3328632220 var first_idx: usize = undefined;
3328732221 var other_idx: usize = undefined; // We sometimes need a second peer index to report a generic error
......@@ -33325,15 +32259,24 @@ fn resolvePeerTypesInner(
3332532259 .peer_idx_b = i,
3332632260 } };
3332732261
33328 // Note that the align can be always non-zero; Type.ptr will canonicalize it
33329 if (peer_info.flags.alignment == .none) {
33330 any_abi_aligned = true;
33331 } else if (ptr_info.flags.alignment == .none) {
33332 any_abi_aligned = true;
33333 ptr_info.flags.alignment = peer_info.flags.alignment;
33334 } else {
33335 ptr_info.flags.alignment = ptr_info.flags.alignment.minStrict(peer_info.flags.alignment);
33336 }
32262 ptr_info.flags.alignment = a: {
32263 // If both alignments are implicit, the result alignment is implicit.
32264 // e.g. '*u32' + '*c_uint' -> '*u32'
32265 if (ptr_info.flags.alignment == .none and peer_info.flags.alignment == .none) {
32266 break :a .none;
32267 }
32268 // Otherwise (if either alignment is explicit), the result alignment is explicit.
32269 // e.g. '*u32' + '*align(4) c_uint' -> '*align(4) u32'
32270 const cur_align = switch (ptr_info.flags.alignment) {
32271 .none => Type.fromInterned(ptr_info.child).abiAlignment(zcu),
32272 else => ptr_info.flags.alignment,
32273 };
32274 const new_align = switch (peer_info.flags.alignment) {
32275 .none => Type.fromInterned(peer_info.child).abiAlignment(zcu),
32276 else => peer_info.flags.alignment,
32277 };
32278 break :a .minStrict(cur_align, new_align);
32279 };
3333732280
3333832281 if (ptr_info.flags.address_space != peer_info.flags.address_space) {
3333932282 return generic_err;
......@@ -33582,13 +32525,7 @@ fn resolvePeerTypesInner(
3358232525 },
3358332526 }
3358432527
33585 if (any_abi_aligned and opt_ptr_info.?.flags.alignment != .none) {
33586 opt_ptr_info.?.flags.alignment = opt_ptr_info.?.flags.alignment.minStrict(
33587 try Type.fromInterned(pointee).abiAlignmentSema(pt),
33588 );
33589 }
33590
33591 return .{ .success = try pt.ptrTypeSema(opt_ptr_info.?) };
32528 return .{ .success = try pt.ptrType(opt_ptr_info.?) };
3359232529 },
3359332530
3359432531 .func => {
......@@ -33731,7 +32668,7 @@ fn resolvePeerTypesInner(
3373132668 .peer_idx_b = i,
3373232669 } };
3373332670 any_comptime_known = true;
33734 ptr_opt_val.* = try sema.resolveLazyValue(opt_val.?);
32671 ptr_opt_val.* = opt_val.?;
3373532672 continue;
3373632673 },
3373732674 .int => {},
......@@ -33924,7 +32861,6 @@ fn resolvePeerTypesInner(
3392432861 var comptime_val: ?Value = null;
3392532862 for (peer_tys) |opt_ty| {
3392632863 const struct_ty = opt_ty orelse continue;
33927 try struct_ty.resolveStructFieldInits(pt);
3392832864
3392932865 const uncoerced_field_val = try struct_ty.structFieldValueComptime(pt, field_index) orelse {
3393032866 comptime_val = null;
......@@ -33939,2242 +32875,274 @@ fn resolvePeerTypesInner(
3393932875 },
3394032876 else => |e| return e,
3394132877 };
33942 const coerced_val = (try sema.resolveValue(coerced_inst)) orelse continue;
32878 const coerced_val = sema.resolveValue(coerced_inst) orelse continue;
3394332879 const existing = comptime_val orelse {
3394432880 comptime_val = coerced_val;
33945 continue;
33946 };
33947 if (!coerced_val.eql(existing, .fromInterned(field_ty.*), zcu)) {
33948 comptime_val = null;
33949 break;
33950 }
33951 }
33952
33953 field_val.* = if (comptime_val) |v| v.toIntern() else .none;
33954 }
33955
33956 const final_ty = try ip.getTupleType(gpa, io, pt.tid, .{
33957 .types = field_types,
33958 .values = field_vals,
33959 });
33960
33961 return .{ .success = .fromInterned(final_ty) };
33962 },
33963
33964 .exact => {
33965 var expect_ty: ?Type = null;
33966 var first_idx: usize = undefined;
33967 for (peer_tys, 0..) |opt_ty, i| {
33968 const ty = opt_ty orelse continue;
33969 if (expect_ty) |expect| {
33970 if (!ty.eql(expect, zcu)) return .{ .conflict = .{
33971 .peer_idx_a = first_idx,
33972 .peer_idx_b = i,
33973 } };
33974 } else {
33975 expect_ty = ty;
33976 first_idx = i;
33977 }
33978 }
33979 return .{ .success = expect_ty.? };
33980 },
33981 }
33982}
33983
33984fn maybeMergeErrorSets(sema: *Sema, block: *Block, src: LazySrcLoc, e0: Type, e1: Type) !Type {
33985 // e0 -> e1
33986 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, e1, e0, src, src)) {
33987 return e1;
33988 }
33989
33990 // e1 -> e0
33991 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, e0, e1, src, src)) {
33992 return e0;
33993 }
33994
33995 return sema.errorSetMerge(e0, e1);
33996}
33997
33998fn resolvePairInMemoryCoercible(sema: *Sema, block: *Block, src: LazySrcLoc, ty_a: Type, ty_b: Type) !?Type {
33999 const target = sema.pt.zcu.getTarget();
34000
34001 // ty_b -> ty_a
34002 if (.ok == try sema.coerceInMemoryAllowed(block, ty_a, ty_b, false, target, src, src, null)) {
34003 return ty_a;
34004 }
34005
34006 // ty_a -> ty_b
34007 if (.ok == try sema.coerceInMemoryAllowed(block, ty_b, ty_a, false, target, src, src, null)) {
34008 return ty_b;
34009 }
34010
34011 return null;
34012}
34013
34014const ArrayLike = struct {
34015 len: u64,
34016 /// `noreturn` indicates that this type is `struct{}` so can coerce to anything
34017 elem_ty: Type,
34018};
34019fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {
34020 const pt = sema.pt;
34021 const zcu = pt.zcu;
34022 return switch (ty.zigTypeTag(zcu)) {
34023 .array => .{
34024 .len = ty.arrayLen(zcu),
34025 .elem_ty = ty.childType(zcu),
34026 },
34027 .@"struct" => {
34028 const field_count = ty.structFieldCount(zcu);
34029 if (field_count == 0) return .{
34030 .len = 0,
34031 .elem_ty = .noreturn,
34032 };
34033 if (!ty.isTuple(zcu)) return null;
34034 const elem_ty = ty.fieldType(0, zcu);
34035 for (1..field_count) |i| {
34036 if (!ty.fieldType(i, zcu).eql(elem_ty, zcu)) {
34037 return null;
34038 }
34039 }
34040 return .{
34041 .len = field_count,
34042 .elem_ty = elem_ty,
34043 };
34044 },
34045 else => null,
34046 };
34047}
34048
34049pub fn resolveIes(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!void {
34050 const pt = sema.pt;
34051 const zcu = pt.zcu;
34052 const ip = &zcu.intern_pool;
34053
34054 if (sema.fn_ret_ty_ies) |ies| {
34055 try sema.resolveInferredErrorSetPtr(block, src, ies);
34056 assert(ies.resolved != .none);
34057 ip.funcIesResolved(sema.func_index).* = ies.resolved;
34058 }
34059}
34060
34061pub fn resolveFnTypes(sema: *Sema, fn_ty: Type, src: LazySrcLoc) CompileError!void {
34062 const pt = sema.pt;
34063 const zcu = pt.zcu;
34064 const ip = &zcu.intern_pool;
34065 const fn_ty_info = zcu.typeToFunc(fn_ty).?;
34066
34067 try Type.fromInterned(fn_ty_info.return_type).resolveFully(pt);
34068
34069 if (zcu.comp.config.any_error_tracing and
34070 Type.fromInterned(fn_ty_info.return_type).isError(zcu))
34071 {
34072 // Ensure the type exists so that backends can assume that.
34073 _ = try sema.getBuiltinType(src, .StackTrace);
34074 }
34075
34076 for (0..fn_ty_info.param_types.len) |i| {
34077 try Type.fromInterned(fn_ty_info.param_types.get(ip)[i]).resolveFully(pt);
34078 }
34079}
34080
34081fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {
34082 return val.resolveLazy(sema.arena, sema.pt);
34083}
34084
34085/// Resolve a struct's alignment only without triggering resolution of its layout.
34086/// Asserts that the alignment is not yet resolved and the layout is non-packed.
34087pub fn resolveStructAlignment(
34088 sema: *Sema,
34089 ty: InternPool.Index,
34090 struct_type: InternPool.LoadedStructType,
34091) SemaError!void {
34092 const pt = sema.pt;
34093 const zcu = pt.zcu;
34094 const io = zcu.comp.io;
34095 const ip = &zcu.intern_pool;
34096 const target = zcu.getTarget();
34097
34098 assert(sema.owner.unwrap().type == ty);
34099
34100 assert(struct_type.layout != .@"packed");
34101 assert(struct_type.flagsUnordered(ip).alignment == .none);
34102
34103 const ptr_align = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));
34104
34105 // We'll guess "pointer-aligned", if the struct has an
34106 // underaligned pointer field then some allocations
34107 // might require explicit alignment.
34108 if (struct_type.assumePointerAlignedIfFieldTypesWip(ip, io, ptr_align)) return;
34109
34110 try sema.resolveStructFieldTypes(ty, struct_type);
34111
34112 // We'll guess "pointer-aligned", if the struct has an
34113 // underaligned pointer field then some allocations
34114 // might require explicit alignment.
34115 if (struct_type.assumePointerAlignedIfWip(ip, io, ptr_align)) return;
34116 defer struct_type.clearAlignmentWip(ip, io);
34117
34118 // No `zcu.trackUnitSema` calls, since this phase isn't really doing any semantic analysis.
34119 // It's just triggering *other* analysis, alongside a simple loop over already-resolved info.
34120
34121 var alignment: Alignment = .@"1";
34122
34123 for (0..struct_type.field_types.len) |i| {
34124 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]);
34125 if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt))
34126 continue;
34127 const field_align = try field_ty.structFieldAlignmentSema(
34128 struct_type.fieldAlign(ip, i),
34129 struct_type.layout,
34130 pt,
34131 );
34132 alignment = alignment.maxStrict(field_align);
34133 }
34134
34135 struct_type.setAlignment(ip, io, alignment);
34136}
34137
34138pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
34139 const pt = sema.pt;
34140 const zcu = pt.zcu;
34141 const ip = &zcu.intern_pool;
34142 const io = zcu.comp.io;
34143 const struct_type = zcu.typeToStruct(ty) orelse return;
34144
34145 assert(sema.owner.unwrap().type == ty.toIntern());
34146
34147 if (struct_type.haveLayout(ip))
34148 return;
34149
34150 try sema.resolveStructFieldTypes(ty.toIntern(), struct_type);
34151
34152 // No `zcu.trackUnitSema` calls, since this phase isn't really doing any semantic analysis.
34153 // It's just triggering *other* analysis, alongside a simple loop over already-resolved info.
34154
34155 if (struct_type.layout == .@"packed") {
34156 sema.backingIntType(struct_type) catch |err| switch (err) {
34157 error.AnalysisFail, error.OutOfMemory, error.Canceled => |e| return e,
34158 error.ComptimeBreak, error.ComptimeReturn => unreachable,
34159 };
34160 return;
34161 }
34162
34163 if (struct_type.setLayoutWip(ip, io)) {
34164 const msg = try sema.errMsg(
34165 ty.srcLoc(zcu),
34166 "struct '{f}' depends on itself",
34167 .{ty.fmt(pt)},
34168 );
34169 return sema.failWithOwnedErrorMsg(null, msg);
34170 }
34171 defer struct_type.clearLayoutWip(ip, io);
34172
34173 const aligns = try sema.arena.alloc(Alignment, struct_type.field_types.len);
34174 const sizes = try sema.arena.alloc(u64, struct_type.field_types.len);
34175
34176 var big_align: Alignment = .@"1";
34177
34178 for (aligns, sizes, 0..) |*field_align, *field_size, i| {
34179 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]);
34180 if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt)) {
34181 struct_type.offsets.get(ip)[i] = 0;
34182 field_size.* = 0;
34183 field_align.* = .none;
34184 continue;
34185 }
34186
34187 field_size.* = field_ty.abiSizeSema(pt) catch |err| switch (err) {
34188 error.AnalysisFail => {
34189 const msg = sema.err orelse return err;
34190 try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{});
34191 return err;
34192 },
34193 else => return err,
34194 };
34195 field_align.* = try field_ty.structFieldAlignmentSema(
34196 struct_type.fieldAlign(ip, i),
34197 struct_type.layout,
34198 pt,
34199 );
34200 big_align = big_align.maxStrict(field_align.*);
34201 }
34202
34203 if (struct_type.flagsUnordered(ip).assumed_runtime_bits and !(try ty.hasRuntimeBitsSema(pt))) {
34204 const msg = try sema.errMsg(
34205 ty.srcLoc(zcu),
34206 "struct layout depends on it having runtime bits",
34207 .{},
34208 );
34209 return sema.failWithOwnedErrorMsg(null, msg);
34210 }
34211
34212 if (struct_type.flagsUnordered(ip).assumed_pointer_aligned and
34213 big_align.compareStrict(.neq, Alignment.fromByteUnits(@divExact(zcu.getTarget().ptrBitWidth(), 8))))
34214 {
34215 const msg = try sema.errMsg(
34216 ty.srcLoc(zcu),
34217 "struct layout depends on being pointer aligned",
34218 .{},
34219 );
34220 return sema.failWithOwnedErrorMsg(null, msg);
34221 }
34222
34223 if (struct_type.hasReorderedFields()) {
34224 const runtime_order = struct_type.runtime_order.get(ip);
34225
34226 for (runtime_order, 0..) |*ro, i| {
34227 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]);
34228 if (struct_type.fieldIsComptime(ip, i) or try field_ty.comptimeOnlySema(pt)) {
34229 ro.* = .omitted;
34230 } else {
34231 ro.* = @enumFromInt(i);
34232 }
34233 }
34234
34235 const RuntimeOrder = InternPool.LoadedStructType.RuntimeOrder;
34236
34237 const AlignSortContext = struct {
34238 aligns: []const Alignment,
34239
34240 fn lessThan(ctx: @This(), a: RuntimeOrder, b: RuntimeOrder) bool {
34241 if (a == .omitted) return false;
34242 if (b == .omitted) return true;
34243 const a_align = ctx.aligns[@intFromEnum(a)];
34244 const b_align = ctx.aligns[@intFromEnum(b)];
34245 return a_align.compare(.gt, b_align);
34246 }
34247 };
34248 if (!zcu.backendSupportsFeature(.field_reordering)) {
34249 // TODO: we should probably also reorder tuple fields? This is a bit weird because it'll involve
34250 // mutating the `InternPool` for a non-container type.
34251 //
34252 // TODO: implement field reordering support in all the backends!
34253 //
34254 // This logic does not reorder fields; it only moves the omitted ones to the end
34255 // so that logic elsewhere does not need to special-case here.
34256 var i: usize = 0;
34257 var off: usize = 0;
34258 while (i + off < runtime_order.len) {
34259 if (runtime_order[i + off] == .omitted) {
34260 off += 1;
34261 continue;
34262 }
34263 runtime_order[i] = runtime_order[i + off];
34264 i += 1;
34265 }
34266 @memset(runtime_order[i..], .omitted);
34267 } else {
34268 mem.sortUnstable(RuntimeOrder, runtime_order, AlignSortContext{
34269 .aligns = aligns,
34270 }, AlignSortContext.lessThan);
34271 }
34272 }
34273
34274 // Calculate size, alignment, and field offsets.
34275 const offsets = struct_type.offsets.get(ip);
34276 var it = struct_type.iterateRuntimeOrder(ip);
34277 var offset: u64 = 0;
34278 while (it.next()) |i| {
34279 offsets[i] = @intCast(aligns[i].forward(offset));
34280 offset = offsets[i] + sizes[i];
34281 }
34282 const size = std.math.cast(u32, big_align.forward(offset)) orelse {
34283 const msg = try sema.errMsg(
34284 ty.srcLoc(zcu),
34285 "struct layout requires size {d}, this compiler implementation supports up to {d}",
34286 .{ big_align.forward(offset), std.math.maxInt(u32) },
34287 );
34288 return sema.failWithOwnedErrorMsg(null, msg);
34289 };
34290 struct_type.setLayoutResolved(ip, io, size, big_align);
34291 _ = try ty.comptimeOnlySema(pt);
34292}
34293
34294fn backingIntType(
34295 sema: *Sema,
34296 struct_type: InternPool.LoadedStructType,
34297) CompileError!void {
34298 const pt = sema.pt;
34299 const zcu = pt.zcu;
34300 const comp = zcu.comp;
34301 const gpa = comp.gpa;
34302 const io = comp.io;
34303 const ip = &zcu.intern_pool;
34304
34305 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
34306 defer analysis_arena.deinit();
34307
34308 var block: Block = .{
34309 .parent = null,
34310 .sema = sema,
34311 .namespace = struct_type.namespace,
34312 .instructions = .{},
34313 .inlining = null,
34314 .comptime_reason = null, // set below if needed
34315 .src_base_inst = struct_type.zir_index,
34316 .type_name_ctx = struct_type.name,
34317 };
34318 defer assert(block.instructions.items.len == 0);
34319
34320 const fields_bit_sum = blk: {
34321 var accumulator: u64 = 0;
34322 for (0..struct_type.field_types.len) |i| {
34323 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]);
34324 accumulator += try field_ty.bitSizeSema(pt);
34325 }
34326 break :blk accumulator;
34327 };
34328
34329 const zir = zcu.namespacePtr(struct_type.namespace).fileScope(zcu).zir.?;
34330 const zir_index = struct_type.zir_index.resolve(ip) orelse return error.AnalysisFail;
34331 const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;
34332 assert(extended.opcode == .struct_decl);
34333 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
34334
34335 if (small.has_backing_int) {
34336 var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).@"struct".fields.len;
34337 const captures_len = if (small.has_captures_len) blk: {
34338 const captures_len = zir.extra[extra_index];
34339 extra_index += 1;
34340 break :blk captures_len;
34341 } else 0;
34342 extra_index += @intFromBool(small.has_fields_len);
34343 extra_index += @intFromBool(small.has_decls_len);
34344
34345 extra_index += captures_len * 2;
34346
34347 const backing_int_body_len = zir.extra[extra_index];
34348 extra_index += 1;
34349
34350 const backing_int_src: LazySrcLoc = .{
34351 .base_node_inst = struct_type.zir_index,
34352 .offset = .{ .node_offset_container_tag = .zero },
34353 };
34354 block.comptime_reason = .{ .reason = .{
34355 .src = backing_int_src,
34356 .r = .{ .simple = .type },
34357 } };
34358 const backing_int_ty = blk: {
34359 if (backing_int_body_len == 0) {
34360 const backing_int_ref: Zir.Inst.Ref = @enumFromInt(zir.extra[extra_index]);
34361 break :blk try sema.resolveType(&block, backing_int_src, backing_int_ref);
34362 } else {
34363 const body = zir.bodySlice(extra_index, backing_int_body_len);
34364 const ty_ref = try sema.resolveInlineBody(&block, body, zir_index);
34365 break :blk try sema.analyzeAsType(&block, backing_int_src, ty_ref);
34366 }
34367 };
34368
34369 try sema.checkBackingIntType(&block, backing_int_src, backing_int_ty, fields_bit_sum);
34370 struct_type.setBackingIntType(ip, io, backing_int_ty.toIntern());
34371 } else {
34372 if (fields_bit_sum > std.math.maxInt(u16)) {
34373 return sema.fail(&block, block.nodeOffset(.zero), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum});
34374 }
34375 const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum));
34376 struct_type.setBackingIntType(ip, io, backing_int_ty.toIntern());
34377 }
34378
34379 try sema.flushExports();
34380}
34381
34382fn checkBackingIntType(sema: *Sema, block: *Block, src: LazySrcLoc, backing_int_ty: Type, fields_bit_sum: u64) CompileError!void {
34383 const pt = sema.pt;
34384 const zcu = pt.zcu;
34385
34386 if (!backing_int_ty.isInt(zcu)) {
34387 return sema.fail(block, src, "expected backing integer type, found '{f}'", .{backing_int_ty.fmt(pt)});
34388 }
34389 if (backing_int_ty.bitSize(zcu) != fields_bit_sum) {
34390 return sema.fail(
34391 block,
34392 src,
34393 "backing integer type '{f}' has bit size {d} but the struct fields have a total bit size of {d}",
34394 .{ backing_int_ty.fmt(pt), backing_int_ty.bitSize(zcu), fields_bit_sum },
34395 );
34396 }
34397}
34398
34399fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
34400 const pt = sema.pt;
34401 if (!ty.isIndexable(pt.zcu)) {
34402 const msg = msg: {
34403 const msg = try sema.errMsg(src, "type '{f}' does not support indexing", .{ty.fmt(pt)});
34404 errdefer msg.destroy(sema.gpa);
34405 try sema.errNote(src, msg, "operand must be an array, slice, tuple, or vector", .{});
34406 break :msg msg;
34407 };
34408 return sema.failWithOwnedErrorMsg(block, msg);
34409 }
34410}
34411
34412fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
34413 const pt = sema.pt;
34414 const zcu = pt.zcu;
34415 if (ty.zigTypeTag(zcu) == .pointer) {
34416 switch (ty.ptrSize(zcu)) {
34417 .slice, .many, .c => return,
34418 .one => {
34419 const elem_ty = ty.childType(zcu);
34420 if (elem_ty.zigTypeTag(zcu) == .array) return;
34421 // TODO https://github.com/ziglang/zig/issues/15479
34422 // if (elem_ty.isTuple()) return;
34423 },
34424 }
34425 }
34426 const msg = msg: {
34427 const msg = try sema.errMsg(src, "type '{f}' is not an indexable pointer", .{ty.fmt(pt)});
34428 errdefer msg.destroy(sema.gpa);
34429 try sema.errNote(src, msg, "operand must be a slice, a many pointer or a pointer to an array", .{});
34430 break :msg msg;
34431 };
34432 return sema.failWithOwnedErrorMsg(block, msg);
34433}
34434
34435/// Resolve a unions's alignment only without triggering resolution of its layout.
34436/// Asserts that the alignment is not yet resolved.
34437pub fn resolveUnionAlignment(
34438 sema: *Sema,
34439 ty: Type,
34440 union_type: InternPool.LoadedUnionType,
34441) SemaError!void {
34442 const pt = sema.pt;
34443 const zcu = pt.zcu;
34444 const io = zcu.comp.io;
34445 const ip = &zcu.intern_pool;
34446 const target = zcu.getTarget();
34447
34448 assert(sema.owner.unwrap().type == ty.toIntern());
34449
34450 assert(!union_type.haveLayout(ip));
34451
34452 const ptr_align = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));
34453
34454 // We'll guess "pointer-aligned", if the union has an
34455 // underaligned pointer field then some allocations
34456 // might require explicit alignment.
34457 if (union_type.assumePointerAlignedIfFieldTypesWip(ip, io, ptr_align)) return;
34458
34459 try sema.resolveUnionFieldTypes(ty, union_type);
34460
34461 // No `zcu.trackUnitSema` calls, since this phase isn't really doing any semantic analysis.
34462 // It's just triggering *other* analysis, alongside a simple loop over already-resolved info.
34463
34464 var max_align: Alignment = .@"1";
34465 for (0..union_type.field_types.len) |field_index| {
34466 const field_ty: Type = .fromInterned(union_type.field_types.get(ip)[field_index]);
34467 if (!(try field_ty.hasRuntimeBitsSema(pt))) continue;
34468
34469 const explicit_align = union_type.fieldAlign(ip, field_index);
34470 const field_align = if (explicit_align != .none)
34471 explicit_align
34472 else
34473 try field_ty.abiAlignmentSema(sema.pt);
34474
34475 max_align = max_align.max(field_align);
34476 }
34477
34478 union_type.setAlignment(ip, io, max_align);
34479}
34480
34481/// This logic must be kept in sync with `Type.getUnionLayout`.
34482pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
34483 const pt = sema.pt;
34484 const io = pt.zcu.comp.io;
34485 const ip = &pt.zcu.intern_pool;
34486
34487 try sema.resolveUnionFieldTypes(ty, ip.loadUnionType(ty.ip_index));
34488
34489 // Load again, since the tag type might have changed due to resolution.
34490 const union_type = ip.loadUnionType(ty.ip_index);
34491
34492 assert(sema.owner.unwrap().type == ty.toIntern());
34493
34494 const old_flags = union_type.flagsUnordered(ip);
34495 switch (old_flags.status) {
34496 .none, .have_field_types => {},
34497 .field_types_wip, .layout_wip => {
34498 const msg = try sema.errMsg(
34499 ty.srcLoc(pt.zcu),
34500 "union '{f}' depends on itself",
34501 .{ty.fmt(pt)},
34502 );
34503 return sema.failWithOwnedErrorMsg(null, msg);
34504 },
34505 .have_layout, .fully_resolved_wip, .fully_resolved => return,
34506 }
34507
34508 errdefer union_type.setStatusIfLayoutWip(ip, io, old_flags.status);
34509
34510 union_type.setStatus(ip, io, .layout_wip);
34511
34512 // No `zcu.trackUnitSema` calls, since this phase isn't really doing any semantic analysis.
34513 // It's just triggering *other* analysis, alongside a simple loop over already-resolved info.
34514
34515 var max_size: u64 = 0;
34516 var max_align: Alignment = .@"1";
34517 for (0..union_type.field_types.len) |field_index| {
34518 const field_ty: Type = .fromInterned(union_type.field_types.get(ip)[field_index]);
34519 if (field_ty.isNoReturn(pt.zcu)) continue;
34520
34521 // We need to call `hasRuntimeBits` before calling `abiSize` to prevent reachable `unreachable`s,
34522 // but `hasRuntimeBits` only resolves field types and so may infinite recurse on a layout wip type,
34523 // so we must resolve the layout manually first, instead of waiting for `abiSize` to do it for us.
34524 // This is arguably just hacking around bugs in both `abiSize` for not allowing arbitrary types to
34525 // be queried, enabling failures to be handled with the emission of a compile error, and also in
34526 // `hasRuntimeBits` for ever being able to infinite recurse in the first place.
34527 try field_ty.resolveLayout(pt);
34528
34529 if (try field_ty.hasRuntimeBitsSema(pt)) {
34530 max_size = @max(max_size, field_ty.abiSizeSema(pt) catch |err| switch (err) {
34531 error.AnalysisFail => {
34532 const msg = sema.err orelse return err;
34533 try sema.addFieldErrNote(ty, field_index, msg, "while checking this field", .{});
34534 return err;
34535 },
34536 else => return err,
34537 });
34538 }
34539
34540 const explicit_align = union_type.fieldAlign(ip, field_index);
34541 const field_align = if (explicit_align != .none)
34542 explicit_align
34543 else
34544 try field_ty.abiAlignmentSema(pt);
34545 max_align = max_align.max(field_align);
34546 }
34547
34548 const has_runtime_tag = union_type.flagsUnordered(ip).runtime_tag.hasTag() and
34549 try Type.fromInterned(union_type.enum_tag_ty).hasRuntimeBitsSema(pt);
34550 const size, const alignment, const padding = if (has_runtime_tag) layout: {
34551 const enum_tag_type: Type = .fromInterned(union_type.enum_tag_ty);
34552 const tag_align = try enum_tag_type.abiAlignmentSema(pt);
34553 const tag_size = try enum_tag_type.abiSizeSema(pt);
34554
34555 // Put the tag before or after the payload depending on which one's
34556 // alignment is greater.
34557 var size: u64 = 0;
34558 var padding: u32 = 0;
34559 if (tag_align.order(max_align).compare(.gte)) {
34560 // {Tag, Payload}
34561 size += tag_size;
34562 size = max_align.forward(size);
34563 size += max_size;
34564 const prev_size = size;
34565 size = tag_align.forward(size);
34566 padding = @intCast(size - prev_size);
34567 } else {
34568 // {Payload, Tag}
34569 size += max_size;
34570 size = switch (pt.zcu.getTarget().ofmt) {
34571 .c => max_align,
34572 else => tag_align,
34573 }.forward(size);
34574 size += tag_size;
34575 const prev_size = size;
34576 size = max_align.forward(size);
34577 padding = @intCast(size - prev_size);
34578 }
34579
34580 break :layout .{ size, max_align.max(tag_align), padding };
34581 } else .{ max_align.forward(max_size), max_align, 0 };
34582
34583 const casted_size = std.math.cast(u32, size) orelse {
34584 const msg = try sema.errMsg(
34585 ty.srcLoc(pt.zcu),
34586 "union layout requires size {d}, this compiler implementation supports up to {d}",
34587 .{ size, std.math.maxInt(u32) },
34588 );
34589 return sema.failWithOwnedErrorMsg(null, msg);
34590 };
34591 union_type.setHaveLayout(ip, io, casted_size, padding, alignment);
34592
34593 if (union_type.flagsUnordered(ip).assumed_runtime_bits and !(try ty.hasRuntimeBitsSema(pt))) {
34594 const msg = try sema.errMsg(
34595 ty.srcLoc(pt.zcu),
34596 "union layout depends on it having runtime bits",
34597 .{},
34598 );
34599 return sema.failWithOwnedErrorMsg(null, msg);
34600 }
34601
34602 if (union_type.flagsUnordered(ip).assumed_pointer_aligned and
34603 alignment.compareStrict(.neq, Alignment.fromByteUnits(@divExact(pt.zcu.getTarget().ptrBitWidth(), 8))))
34604 {
34605 const msg = try sema.errMsg(
34606 ty.srcLoc(pt.zcu),
34607 "union layout depends on being pointer aligned",
34608 .{},
34609 );
34610 return sema.failWithOwnedErrorMsg(null, msg);
34611 }
34612 _ = try ty.comptimeOnlySema(pt);
34613}
34614
34615/// Returns `error.AnalysisFail` if any of the types (recursively) failed to
34616/// be resolved.
34617pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {
34618 try sema.resolveStructLayout(ty);
34619 try sema.resolveStructFieldInits(ty);
34620
34621 const pt = sema.pt;
34622 const zcu = pt.zcu;
34623 const io = zcu.comp.io;
34624 const ip = &zcu.intern_pool;
34625 const struct_type = zcu.typeToStruct(ty).?;
34626
34627 assert(sema.owner.unwrap().type == ty.toIntern());
34628
34629 if (struct_type.setFullyResolved(ip, io)) return;
34630 errdefer struct_type.clearFullyResolved(ip, io);
34631
34632 // No `zcu.trackUnitSema` calls, since this phase isn't really doing any semantic analysis.
34633 // It's just triggering *other* analysis, alongside a simple loop over already-resolved info.
34634
34635 // After we have resolve struct layout we have to go over the fields again to
34636 // make sure pointer fields get their child types resolved as well.
34637 // See also similar code for unions.
34638
34639 for (0..struct_type.field_types.len) |i| {
34640 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]);
34641 try field_ty.resolveFully(pt);
34642 }
34643}
34644
34645pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {
34646 try sema.resolveUnionLayout(ty);
34647
34648 const pt = sema.pt;
34649 const zcu = pt.zcu;
34650 const io = zcu.comp.io;
34651 const ip = &zcu.intern_pool;
34652 const union_obj = zcu.typeToUnion(ty).?;
34653
34654 assert(sema.owner.unwrap().type == ty.toIntern());
34655
34656 switch (union_obj.flagsUnordered(ip).status) {
34657 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
34658 .fully_resolved_wip, .fully_resolved => return,
34659 }
34660
34661 // No `zcu.trackUnitSema` calls, since this phase isn't really doing any semantic analysis.
34662 // It's just triggering *other* analysis, alongside a simple loop over already-resolved info.
34663
34664 {
34665 // After we have resolve union layout we have to go over the fields again to
34666 // make sure pointer fields get their child types resolved as well.
34667 // See also similar code for structs.
34668 const prev_status = union_obj.flagsUnordered(ip).status;
34669 errdefer union_obj.setStatus(ip, io, prev_status);
34670
34671 union_obj.setStatus(ip, io, .fully_resolved_wip);
34672 for (0..union_obj.field_types.len) |field_index| {
34673 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]);
34674 try field_ty.resolveFully(pt);
34675 }
34676 union_obj.setStatus(ip, io, .fully_resolved);
34677 }
34678
34679 // And let's not forget comptime-only status.
34680 _ = try ty.comptimeOnlySema(pt);
34681}
34682
34683pub fn resolveStructFieldTypes(
34684 sema: *Sema,
34685 ty: InternPool.Index,
34686 struct_type: InternPool.LoadedStructType,
34687) SemaError!void {
34688 const pt = sema.pt;
34689 const zcu = pt.zcu;
34690 const io = zcu.comp.io;
34691 const ip = &zcu.intern_pool;
34692
34693 assert(sema.owner.unwrap().type == ty);
34694
34695 if (struct_type.haveFieldTypes(ip)) return;
34696
34697 if (struct_type.setFieldTypesWip(ip, io)) {
34698 const msg = try sema.errMsg(
34699 Type.fromInterned(ty).srcLoc(zcu),
34700 "struct '{f}' depends on itself",
34701 .{Type.fromInterned(ty).fmt(pt)},
34702 );
34703 return sema.failWithOwnedErrorMsg(null, msg);
34704 }
34705 defer struct_type.clearFieldTypesWip(ip, io);
34706
34707 // can't happen earlier than this because we only want the progress node if not already resolved
34708 const tracked_unit = zcu.trackUnitSema(struct_type.name.toSlice(ip), null);
34709 defer tracked_unit.end(zcu);
34710
34711 sema.structFields(struct_type) catch |err| switch (err) {
34712 error.AnalysisFail, error.OutOfMemory, error.Canceled => |e| return e,
34713 error.ComptimeBreak, error.ComptimeReturn => unreachable,
34714 };
34715}
34716
34717pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
34718 const pt = sema.pt;
34719 const zcu = pt.zcu;
34720 const io = zcu.comp.io;
34721 const ip = &zcu.intern_pool;
34722 const struct_type = zcu.typeToStruct(ty) orelse return;
34723
34724 assert(sema.owner.unwrap().type == ty.toIntern());
34725
34726 // Inits can start as resolved
34727 if (struct_type.haveFieldInits(ip)) return;
34728
34729 try sema.resolveStructLayout(ty);
34730
34731 if (struct_type.setInitsWip(ip, io)) {
34732 const msg = try sema.errMsg(
34733 ty.srcLoc(zcu),
34734 "struct '{f}' depends on itself",
34735 .{ty.fmt(pt)},
34736 );
34737 return sema.failWithOwnedErrorMsg(null, msg);
34738 }
34739 defer struct_type.clearInitsWip(ip, io);
34740
34741 // can't happen earlier than this because we only want the progress node if not already resolved
34742 const tracked_unit = zcu.trackUnitSema(struct_type.name.toSlice(ip), null);
34743 defer tracked_unit.end(zcu);
34744
34745 sema.structFieldInits(struct_type) catch |err| switch (err) {
34746 error.AnalysisFail, error.OutOfMemory, error.Canceled => |e| return e,
34747 error.ComptimeBreak, error.ComptimeReturn => unreachable,
34748 };
34749 struct_type.setHaveFieldInits(ip, io);
34750}
34751
34752pub fn resolveUnionFieldTypes(sema: *Sema, ty: Type, union_type: InternPool.LoadedUnionType) SemaError!void {
34753 const pt = sema.pt;
34754 const zcu = pt.zcu;
34755 const io = zcu.comp.io;
34756 const ip = &zcu.intern_pool;
34757
34758 assert(sema.owner.unwrap().type == ty.toIntern());
34759
34760 switch (union_type.flagsUnordered(ip).status) {
34761 .none => {},
34762 .field_types_wip => {
34763 const msg = try sema.errMsg(ty.srcLoc(zcu), "union '{f}' depends on itself", .{ty.fmt(pt)});
34764 return sema.failWithOwnedErrorMsg(null, msg);
34765 },
34766 .have_field_types,
34767 .have_layout,
34768 .layout_wip,
34769 .fully_resolved_wip,
34770 .fully_resolved,
34771 => return,
34772 }
34773
34774 // can't happen earlier than this because we only want the progress node if not already resolved
34775 const tracked_unit = zcu.trackUnitSema(union_type.name.toSlice(ip), null);
34776 defer tracked_unit.end(zcu);
34777
34778 union_type.setStatus(ip, io, .field_types_wip);
34779 errdefer union_type.setStatus(ip, io, .none);
34780 sema.unionFields(ty.toIntern(), union_type) catch |err| switch (err) {
34781 error.AnalysisFail, error.OutOfMemory, error.Canceled => |e| return e,
34782 error.ComptimeBreak, error.ComptimeReturn => unreachable,
34783 };
34784 union_type.setStatus(ip, io, .have_field_types);
34785}
34786
34787/// Returns a normal error set corresponding to the fully populated inferred
34788/// error set.
34789fn resolveInferredErrorSet(
34790 sema: *Sema,
34791 block: *Block,
34792 src: LazySrcLoc,
34793 ies_index: InternPool.Index,
34794) CompileError!InternPool.Index {
34795 const pt = sema.pt;
34796 const zcu = pt.zcu;
34797 const ip = &zcu.intern_pool;
34798 const func_index = ip.iesFuncIndex(ies_index);
34799 const func = zcu.funcInfo(func_index);
34800
34801 try sema.declareDependency(.{ .interned = func_index }); // resolved IES
34802
34803 try zcu.maybeUnresolveIes(func_index);
34804 const resolved_ty = func.resolvedErrorSetUnordered(ip);
34805 if (resolved_ty != .none) return resolved_ty;
34806
34807 if (zcu.analysis_in_progress.contains(.wrap(.{ .func = func_index }))) {
34808 return sema.fail(block, src, "unable to resolve inferred error set", .{});
34809 }
34810
34811 // In order to ensure that all dependencies are properly added to the set,
34812 // we need to ensure the function body is analyzed of the inferred error
34813 // set. However, in the case of comptime/inline function calls with
34814 // inferred error sets, each call gets an adhoc InferredErrorSet object, which
34815 // has no corresponding function body.
34816 const ies_func_info = zcu.typeToFunc(.fromInterned(func.ty)).?;
34817 // if ies declared by a inline function with generic return type, the return_type should be generic_poison,
34818 // because inline function does not create a new declaration, and the ies has been filled with analyzeCall,
34819 // so here we can simply skip this case.
34820 if (ies_func_info.return_type == .generic_poison_type) {
34821 assert(ies_func_info.cc == .@"inline");
34822 } else if (ip.errorUnionSet(ies_func_info.return_type) == ies_index) {
34823 if (ies_func_info.is_generic) {
34824 return sema.failWithOwnedErrorMsg(block, msg: {
34825 const msg = try sema.errMsg(src, "unable to resolve inferred error set of generic function", .{});
34826 errdefer msg.destroy(sema.gpa);
34827 try sema.errNote(zcu.navSrcLoc(func.owner_nav), msg, "generic function declared here", .{});
34828 break :msg msg;
34829 });
34830 }
34831 // In this case we are dealing with the actual InferredErrorSet object that
34832 // corresponds to the function, not one created to track an inline/comptime call.
34833 const orig_func_index = ip.unwrapCoercedFunc(func_index);
34834 try sema.addReferenceEntry(block, src, .wrap(.{ .func = orig_func_index }));
34835 try pt.ensureFuncBodyUpToDate(orig_func_index);
34836 }
34837
34838 // This will now have been resolved by the logic at the end of `Zcu.analyzeFnBody`
34839 // which calls `resolveInferredErrorSetPtr`.
34840 const final_resolved_ty = func.resolvedErrorSetUnordered(ip);
34841 assert(final_resolved_ty != .none);
34842 return final_resolved_ty;
34843}
34844
34845pub fn resolveInferredErrorSetPtr(
34846 sema: *Sema,
34847 block: *Block,
34848 src: LazySrcLoc,
34849 ies: *InferredErrorSet,
34850) CompileError!void {
34851 const pt = sema.pt;
34852 const ip = &pt.zcu.intern_pool;
34853
34854 if (ies.resolved != .none) return;
34855
34856 const ies_index = ip.errorUnionSet(sema.fn_ret_ty.toIntern());
34857
34858 for (ies.inferred_error_sets.keys()) |other_ies_index| {
34859 if (ies_index == other_ies_index) continue;
34860 switch (try sema.resolveInferredErrorSet(block, src, other_ies_index)) {
34861 .anyerror_type => {
34862 ies.resolved = .anyerror_type;
34863 return;
34864 },
34865 else => |error_set_ty_index| {
34866 const names = ip.indexToKey(error_set_ty_index).error_set_type.names;
34867 for (names.get(ip)) |name| {
34868 try ies.errors.put(sema.arena, name, {});
34869 }
34870 },
34871 }
34872 }
34873
34874 const resolved_error_set_ty = try pt.errorSetFromUnsortedNames(ies.errors.keys());
34875 ies.resolved = resolved_error_set_ty.toIntern();
34876}
34877
34878fn resolveAdHocInferredErrorSet(
34879 sema: *Sema,
34880 block: *Block,
34881 src: LazySrcLoc,
34882 value: InternPool.Index,
34883) CompileError!InternPool.Index {
34884 const pt = sema.pt;
34885 const zcu = pt.zcu;
34886 const comp = zcu.comp;
34887 const gpa = comp.gpa;
34888 const io = comp.io;
34889 const ip = &zcu.intern_pool;
34890
34891 const new_ty = try resolveAdHocInferredErrorSetTy(sema, block, src, ip.typeOf(value));
34892 if (new_ty == .none) return value;
34893 return ip.getCoerced(gpa, io, pt.tid, value, new_ty);
34894}
34895
34896fn resolveAdHocInferredErrorSetTy(
34897 sema: *Sema,
34898 block: *Block,
34899 src: LazySrcLoc,
34900 ty: InternPool.Index,
34901) CompileError!InternPool.Index {
34902 const ies = sema.fn_ret_ty_ies orelse return .none;
34903 const pt = sema.pt;
34904 const zcu = pt.zcu;
34905 const ip = &zcu.intern_pool;
34906 const error_union_info = switch (ip.indexToKey(ty)) {
34907 .error_union_type => |x| x,
34908 else => return .none,
34909 };
34910 if (error_union_info.error_set_type != .adhoc_inferred_error_set_type)
34911 return .none;
34912
34913 try sema.resolveInferredErrorSetPtr(block, src, ies);
34914 const new_ty = try pt.intern(.{ .error_union_type = .{
34915 .error_set_type = ies.resolved,
34916 .payload_type = error_union_info.payload_type,
34917 } });
34918 return new_ty;
34919}
34920
34921fn resolveInferredErrorSetTy(
34922 sema: *Sema,
34923 block: *Block,
34924 src: LazySrcLoc,
34925 ty: InternPool.Index,
34926) CompileError!InternPool.Index {
34927 const pt = sema.pt;
34928 const zcu = pt.zcu;
34929 const ip = &zcu.intern_pool;
34930 if (ty == .anyerror_type) return ty;
34931 switch (ip.indexToKey(ty)) {
34932 .error_set_type => return ty,
34933 .inferred_error_set_type => return sema.resolveInferredErrorSet(block, src, ty),
34934 else => unreachable,
34935 }
34936}
34937
34938fn structZirInfo(zir: Zir, zir_index: Zir.Inst.Index) struct {
34939 /// fields_len
34940 usize,
34941 Zir.Inst.StructDecl.Small,
34942 /// extra_index
34943 usize,
34944} {
34945 const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;
34946 assert(extended.opcode == .struct_decl);
34947 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
34948 var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).@"struct".fields.len;
34949
34950 const captures_len = if (small.has_captures_len) blk: {
34951 const captures_len = zir.extra[extra_index];
34952 extra_index += 1;
34953 break :blk captures_len;
34954 } else 0;
34955
34956 const fields_len = if (small.has_fields_len) blk: {
34957 const fields_len = zir.extra[extra_index];
34958 extra_index += 1;
34959 break :blk fields_len;
34960 } else 0;
34961
34962 const decls_len = if (small.has_decls_len) decls_len: {
34963 const decls_len = zir.extra[extra_index];
34964 extra_index += 1;
34965 break :decls_len decls_len;
34966 } else 0;
34967
34968 extra_index += captures_len * 2;
34969
34970 // The backing integer cannot be handled until `resolveStructLayout()`.
34971 if (small.has_backing_int) {
34972 const backing_int_body_len = zir.extra[extra_index];
34973 extra_index += 1; // backing_int_body_len
34974 if (backing_int_body_len == 0) {
34975 extra_index += 1; // backing_int_ref
34976 } else {
34977 extra_index += backing_int_body_len; // backing_int_body_inst
34978 }
34979 }
34980
34981 // Skip over decls.
34982 extra_index += decls_len;
34983
34984 return .{ fields_len, small, extra_index };
34985}
34986
34987fn structFields(
34988 sema: *Sema,
34989 struct_type: InternPool.LoadedStructType,
34990) CompileError!void {
34991 const pt = sema.pt;
34992 const zcu = pt.zcu;
34993 const comp = zcu.comp;
34994 const gpa = comp.gpa;
34995 const io = comp.io;
34996 const ip = &zcu.intern_pool;
34997
34998 const namespace_index = struct_type.namespace;
34999 const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir.?;
35000 const zir_index = struct_type.zir_index.resolve(ip) orelse return error.AnalysisFail;
35001
35002 const fields_len, _, var extra_index = structZirInfo(zir, zir_index);
35003
35004 if (fields_len == 0) switch (struct_type.layout) {
35005 .@"packed" => {
35006 try sema.backingIntType(struct_type);
35007 return;
35008 },
35009 .auto, .@"extern" => {
35010 struct_type.setLayoutResolved(ip, io, 0, .none);
35011 return;
35012 },
35013 };
35014
35015 var block_scope: Block = .{
35016 .parent = null,
35017 .sema = sema,
35018 .namespace = namespace_index,
35019 .instructions = .{},
35020 .inlining = null,
35021 .comptime_reason = .{ .reason = .{
35022 .src = .{
35023 .base_node_inst = struct_type.zir_index,
35024 .offset = .nodeOffset(.zero),
35025 },
35026 .r = .{ .simple = .type },
35027 } },
35028 .src_base_inst = struct_type.zir_index,
35029 .type_name_ctx = struct_type.name,
35030 };
35031 defer assert(block_scope.instructions.items.len == 0);
35032
35033 const Field = struct {
35034 type_body_len: u32 = 0,
35035 align_body_len: u32 = 0,
35036 init_body_len: u32 = 0,
35037 type_ref: Zir.Inst.Ref = .none,
35038 };
35039 const fields = try sema.arena.alloc(Field, fields_len);
35040
35041 var any_inits = false;
35042 var any_aligned = false;
35043
35044 {
35045 const bits_per_field = 4;
35046 const fields_per_u32 = 32 / bits_per_field;
35047 const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;
35048 const flags_index = extra_index;
35049 var bit_bag_index: usize = flags_index;
35050 extra_index += bit_bags_count;
35051 var cur_bit_bag: u32 = undefined;
35052 var field_i: u32 = 0;
35053 while (field_i < fields_len) : (field_i += 1) {
35054 if (field_i % fields_per_u32 == 0) {
35055 cur_bit_bag = zir.extra[bit_bag_index];
35056 bit_bag_index += 1;
35057 }
35058 const has_align = @as(u1, @truncate(cur_bit_bag)) != 0;
35059 cur_bit_bag >>= 1;
35060 const has_init = @as(u1, @truncate(cur_bit_bag)) != 0;
35061 cur_bit_bag >>= 1;
35062 const is_comptime = @as(u1, @truncate(cur_bit_bag)) != 0;
35063 cur_bit_bag >>= 1;
35064 const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;
35065 cur_bit_bag >>= 1;
35066
35067 if (is_comptime) struct_type.setFieldComptime(ip, field_i);
35068
35069 const field_name_zir: [:0]const u8 = zir.nullTerminatedString(@enumFromInt(zir.extra[extra_index]));
35070 extra_index += 1; // field_name
35071
35072 fields[field_i] = .{};
35073
35074 if (has_type_body) {
35075 fields[field_i].type_body_len = zir.extra[extra_index];
35076 } else {
35077 fields[field_i].type_ref = @enumFromInt(zir.extra[extra_index]);
35078 }
35079 extra_index += 1;
35080
35081 // This string needs to outlive the ZIR code.
35082 const field_name = try ip.getOrPutString(gpa, io, pt.tid, field_name_zir, .no_embedded_nulls);
35083 assert(struct_type.addFieldName(ip, field_name) == null);
35084
35085 if (has_align) {
35086 fields[field_i].align_body_len = zir.extra[extra_index];
35087 extra_index += 1;
35088 any_aligned = true;
35089 }
35090 if (has_init) {
35091 fields[field_i].init_body_len = zir.extra[extra_index];
35092 extra_index += 1;
35093 any_inits = true;
35094 }
35095 }
35096 }
35097
35098 // Next we do only types and alignments, saving the inits for a second pass,
35099 // so that init values may depend on type layout.
35100
35101 for (fields, 0..) |zir_field, field_i| {
35102 const ty_src: LazySrcLoc = .{
35103 .base_node_inst = struct_type.zir_index,
35104 .offset = .{ .container_field_type = @intCast(field_i) },
35105 };
35106 const field_ty: Type = ty: {
35107 if (zir_field.type_ref != .none) {
35108 break :ty try sema.resolveType(&block_scope, ty_src, zir_field.type_ref);
35109 }
35110 assert(zir_field.type_body_len != 0);
35111 const body = zir.bodySlice(extra_index, zir_field.type_body_len);
35112 extra_index += body.len;
35113 const ty_ref = try sema.resolveInlineBody(&block_scope, body, zir_index);
35114 break :ty try sema.analyzeAsType(&block_scope, ty_src, ty_ref);
35115 };
35116
35117 struct_type.field_types.get(ip)[field_i] = field_ty.toIntern();
35118
35119 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
35120 const msg = msg: {
35121 const msg = try sema.errMsg(ty_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
35122 errdefer msg.destroy(sema.gpa);
35123
35124 try sema.addDeclaredHereNote(msg, field_ty);
35125 break :msg msg;
35126 };
35127 return sema.failWithOwnedErrorMsg(&block_scope, msg);
35128 }
35129 if (field_ty.zigTypeTag(zcu) == .noreturn) {
35130 const msg = msg: {
35131 const msg = try sema.errMsg(ty_src, "struct fields cannot be 'noreturn'", .{});
35132 errdefer msg.destroy(sema.gpa);
35133
35134 try sema.addDeclaredHereNote(msg, field_ty);
35135 break :msg msg;
35136 };
35137 return sema.failWithOwnedErrorMsg(&block_scope, msg);
35138 }
35139 switch (struct_type.layout) {
35140 .@"extern" => if (!try sema.validateExternType(field_ty, .struct_field)) {
35141 const msg = msg: {
35142 const msg = try sema.errMsg(ty_src, "extern structs cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
35143 errdefer msg.destroy(sema.gpa);
35144
35145 try sema.explainWhyTypeIsNotExtern(msg, ty_src, field_ty, .struct_field);
35146
35147 try sema.addDeclaredHereNote(msg, field_ty);
35148 break :msg msg;
35149 };
35150 return sema.failWithOwnedErrorMsg(&block_scope, msg);
35151 },
35152 .@"packed" => if (!try sema.validatePackedType(field_ty)) {
35153 const msg = msg: {
35154 const msg = try sema.errMsg(ty_src, "packed structs cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
35155 errdefer msg.destroy(sema.gpa);
35156
35157 try sema.explainWhyTypeIsNotPacked(msg, ty_src, field_ty);
35158
35159 try sema.addDeclaredHereNote(msg, field_ty);
35160 break :msg msg;
35161 };
35162 return sema.failWithOwnedErrorMsg(&block_scope, msg);
35163 },
35164 else => {},
35165 }
35166
35167 if (zir_field.align_body_len > 0) {
35168 const body = zir.bodySlice(extra_index, zir_field.align_body_len);
35169 extra_index += body.len;
35170 const align_ref = try sema.resolveInlineBody(&block_scope, body, zir_index);
35171 const align_src: LazySrcLoc = .{
35172 .base_node_inst = struct_type.zir_index,
35173 .offset = .{ .container_field_align = @intCast(field_i) },
35174 };
35175 const field_align = try sema.analyzeAsAlign(&block_scope, align_src, align_ref);
35176 struct_type.field_aligns.get(ip)[field_i] = field_align;
35177 }
35178
35179 extra_index += zir_field.init_body_len;
35180 }
35181
35182 struct_type.clearFieldTypesWip(ip, io);
35183 if (!any_inits) struct_type.setHaveFieldInits(ip, io);
35184
35185 try sema.flushExports();
35186}
35187
35188// This logic must be kept in sync with `structFields`
35189fn structFieldInits(
35190 sema: *Sema,
35191 struct_type: InternPool.LoadedStructType,
35192) CompileError!void {
35193 const pt = sema.pt;
35194 const zcu = pt.zcu;
35195 const ip = &zcu.intern_pool;
35196
35197 assert(!struct_type.haveFieldInits(ip));
35198
35199 const namespace_index = struct_type.namespace;
35200 const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir.?;
35201 const zir_index = struct_type.zir_index.resolve(ip) orelse return error.AnalysisFail;
35202 const fields_len, _, var extra_index = structZirInfo(zir, zir_index);
35203
35204 var block_scope: Block = .{
35205 .parent = null,
35206 .sema = sema,
35207 .namespace = namespace_index,
35208 .instructions = .{},
35209 .inlining = null,
35210 .comptime_reason = undefined, // set when `block_scope` is used
35211 .src_base_inst = struct_type.zir_index,
35212 .type_name_ctx = struct_type.name,
35213 };
35214 defer assert(block_scope.instructions.items.len == 0);
35215
35216 const Field = struct {
35217 type_body_len: u32 = 0,
35218 align_body_len: u32 = 0,
35219 init_body_len: u32 = 0,
35220 };
35221 const fields = try sema.arena.alloc(Field, fields_len);
35222
35223 var any_inits = false;
35224
35225 {
35226 const bits_per_field = 4;
35227 const fields_per_u32 = 32 / bits_per_field;
35228 const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;
35229 const flags_index = extra_index;
35230 var bit_bag_index: usize = flags_index;
35231 extra_index += bit_bags_count;
35232 var cur_bit_bag: u32 = undefined;
35233 var field_i: u32 = 0;
35234 while (field_i < fields_len) : (field_i += 1) {
35235 if (field_i % fields_per_u32 == 0) {
35236 cur_bit_bag = zir.extra[bit_bag_index];
35237 bit_bag_index += 1;
35238 }
35239 const has_align = @as(u1, @truncate(cur_bit_bag)) != 0;
35240 cur_bit_bag >>= 1;
35241 const has_init = @as(u1, @truncate(cur_bit_bag)) != 0;
35242 cur_bit_bag >>= 2;
35243 const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;
35244 cur_bit_bag >>= 1;
35245
35246 extra_index += 1; // field_name
35247
35248 fields[field_i] = .{};
35249
35250 if (has_type_body) fields[field_i].type_body_len = zir.extra[extra_index];
35251 extra_index += 1;
35252
35253 if (has_align) {
35254 fields[field_i].align_body_len = zir.extra[extra_index];
35255 extra_index += 1;
35256 }
35257 if (has_init) {
35258 fields[field_i].init_body_len = zir.extra[extra_index];
35259 extra_index += 1;
35260 any_inits = true;
35261 }
35262 }
35263 }
35264
35265 if (any_inits) {
35266 for (fields, 0..) |zir_field, field_i| {
35267 extra_index += zir_field.type_body_len;
35268 extra_index += zir_field.align_body_len;
35269 const body = zir.bodySlice(extra_index, zir_field.init_body_len);
35270 extra_index += zir_field.init_body_len;
35271
35272 if (body.len == 0) continue;
35273
35274 // Pre-populate the type mapping the body expects to be there.
35275 // In init bodies, the zir index of the struct itself is used
35276 // to refer to the current field type.
35277
35278 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_i]);
35279 const type_ref = Air.internedToRef(field_ty.toIntern());
35280 try sema.inst_map.ensureSpaceForInstructions(sema.gpa, &.{zir_index});
35281 sema.inst_map.putAssumeCapacity(zir_index, type_ref);
35282
35283 const init_src: LazySrcLoc = .{
35284 .base_node_inst = struct_type.zir_index,
35285 .offset = .{ .container_field_value = @intCast(field_i) },
35286 };
35287
35288 block_scope.comptime_reason = .{ .reason = .{
35289 .src = init_src,
35290 .r = .{ .simple = .struct_field_default_value },
35291 } };
35292 const init = try sema.resolveInlineBody(&block_scope, body, zir_index);
35293 const coerced = try sema.coerce(&block_scope, field_ty, init, init_src);
35294 const default_val = try sema.resolveConstValue(&block_scope, init_src, coerced, null);
35295
35296 if (default_val.canMutateComptimeVarState(zcu)) {
35297 return sema.failWithContainsReferenceToComptimeVar(
35298 &block_scope,
35299 init_src,
35300 struct_type.fieldName(ip, field_i),
35301 "field default value",
35302 default_val,
35303 );
35304 }
35305 struct_type.field_inits.get(ip)[field_i] = default_val.toIntern();
35306 }
35307 }
35308
35309 try sema.flushExports();
35310}
35311
35312fn unionFields(
35313 sema: *Sema,
35314 union_ty: InternPool.Index,
35315 union_type: InternPool.LoadedUnionType,
35316) CompileError!void {
35317 const tracy = trace(@src());
35318 defer tracy.end();
35319
35320 const pt = sema.pt;
35321 const zcu = pt.zcu;
35322 const comp = zcu.comp;
35323 const gpa = comp.gpa;
35324 const io = comp.io;
35325 const ip = &zcu.intern_pool;
35326
35327 const zir = zcu.namespacePtr(union_type.namespace).fileScope(zcu).zir.?;
35328 const zir_index = union_type.zir_index.resolve(ip) orelse return error.AnalysisFail;
35329 const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended;
35330 assert(extended.opcode == .union_decl);
35331 const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small);
35332 const extra = zir.extraData(Zir.Inst.UnionDecl, extended.operand);
35333 var extra_index: usize = extra.end;
35334
35335 const tag_type_ref: Zir.Inst.Ref = if (small.has_tag_type) blk: {
35336 const ty_ref: Zir.Inst.Ref = @enumFromInt(zir.extra[extra_index]);
35337 extra_index += 1;
35338 break :blk ty_ref;
35339 } else .none;
35340
35341 const captures_len = if (small.has_captures_len) blk: {
35342 const captures_len = zir.extra[extra_index];
35343 extra_index += 1;
35344 break :blk captures_len;
35345 } else 0;
35346
35347 const body_len = if (small.has_body_len) blk: {
35348 const body_len = zir.extra[extra_index];
35349 extra_index += 1;
35350 break :blk body_len;
35351 } else 0;
35352
35353 const fields_len = if (small.has_fields_len) blk: {
35354 const fields_len = zir.extra[extra_index];
35355 extra_index += 1;
35356 break :blk fields_len;
35357 } else 0;
35358
35359 const decls_len = if (small.has_decls_len) decls_len: {
35360 const decls_len = zir.extra[extra_index];
35361 extra_index += 1;
35362 break :decls_len decls_len;
35363 } else 0;
35364
35365 // Skip over captures and decls.
35366 extra_index += captures_len * 2 + decls_len;
35367
35368 const body = zir.bodySlice(extra_index, body_len);
35369 extra_index += body.len;
35370
35371 const src: LazySrcLoc = .{
35372 .base_node_inst = union_type.zir_index,
35373 .offset = .nodeOffset(.zero),
35374 };
35375
35376 var block_scope: Block = .{
35377 .parent = null,
35378 .sema = sema,
35379 .namespace = union_type.namespace,
35380 .instructions = .{},
35381 .inlining = null,
35382 .comptime_reason = .{ .reason = .{
35383 .src = src,
35384 .r = .{ .simple = .type },
35385 } },
35386 .src_base_inst = union_type.zir_index,
35387 .type_name_ctx = union_type.name,
35388 };
35389 defer assert(block_scope.instructions.items.len == 0);
35390
35391 if (body.len != 0) {
35392 _ = try sema.analyzeInlineBody(&block_scope, body, zir_index);
35393 }
35394
35395 var int_tag_ty: Type = undefined;
35396 var enum_field_names: []InternPool.NullTerminatedString = &.{};
35397 var enum_field_vals: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .empty;
35398 var explicit_tags_seen: []bool = &.{};
35399 if (tag_type_ref != .none) {
35400 const tag_ty_src: LazySrcLoc = .{
35401 .base_node_inst = union_type.zir_index,
35402 .offset = .{ .node_offset_container_tag = .zero },
35403 };
35404 const provided_ty = try sema.resolveType(&block_scope, tag_ty_src, tag_type_ref);
35405 if (small.auto_enum_tag) {
35406 // The provided type is an integer type and we must construct the enum tag type here.
35407 int_tag_ty = provided_ty;
35408 if (int_tag_ty.zigTypeTag(zcu) != .int and int_tag_ty.zigTypeTag(zcu) != .comptime_int) {
35409 return sema.fail(&block_scope, tag_ty_src, "expected integer tag type, found '{f}'", .{int_tag_ty.fmt(pt)});
35410 }
35411
35412 if (fields_len > 0) {
35413 const field_count_val = try pt.intValue(.comptime_int, fields_len - 1);
35414 if (!(try sema.intFitsInType(field_count_val, int_tag_ty, null))) {
35415 const msg = msg: {
35416 const msg = try sema.errMsg(tag_ty_src, "specified integer tag type cannot represent every field", .{});
35417 errdefer msg.destroy(sema.gpa);
35418 try sema.errNote(tag_ty_src, msg, "type '{f}' cannot fit values in range 0...{d}", .{
35419 int_tag_ty.fmt(pt),
35420 fields_len - 1,
35421 });
35422 break :msg msg;
35423 };
35424 return sema.failWithOwnedErrorMsg(&block_scope, msg);
35425 }
35426 enum_field_names = try sema.arena.alloc(InternPool.NullTerminatedString, fields_len);
35427 try enum_field_vals.ensureTotalCapacity(sema.arena, fields_len);
35428 }
35429 } else {
35430 // The provided type is the enum tag type.
35431 const enum_type = switch (ip.indexToKey(provided_ty.toIntern())) {
35432 .enum_type => ip.loadEnumType(provided_ty.toIntern()),
35433 else => return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{f}'", .{provided_ty.fmt(pt)}),
35434 };
35435 union_type.setTagType(ip, io, provided_ty.toIntern());
35436 // The fields of the union must match the enum exactly.
35437 // A flag per field is used to check for missing and extraneous fields.
35438 explicit_tags_seen = try sema.arena.alloc(bool, enum_type.names.len);
35439 @memset(explicit_tags_seen, false);
35440 }
35441 } else {
35442 // If auto_enum_tag is false, this is an untagged union. However, for semantic analysis
35443 // purposes, we still auto-generate an enum tag type the same way. That the union is
35444 // untagged is represented by the Type tag (union vs union_tagged).
35445 enum_field_names = try sema.arena.alloc(InternPool.NullTerminatedString, fields_len);
35446 }
35447
35448 var field_types: std.ArrayList(InternPool.Index) = .empty;
35449 var field_aligns: std.ArrayList(InternPool.Alignment) = .empty;
35450
35451 try field_types.ensureTotalCapacityPrecise(sema.arena, fields_len);
35452 if (small.any_aligned_fields)
35453 try field_aligns.ensureTotalCapacityPrecise(sema.arena, fields_len);
35454
35455 var max_bits: u64 = 0;
35456 var min_bits: u64 = std.math.maxInt(u64);
35457 var max_bits_src: LazySrcLoc = undefined;
35458 var min_bits_src: LazySrcLoc = undefined;
35459 var max_bits_ty: Type = undefined;
35460 var min_bits_ty: Type = undefined;
35461 const bits_per_field = 4;
35462 const fields_per_u32 = 32 / bits_per_field;
35463 const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;
35464 var bit_bag_index: usize = extra_index;
35465 extra_index += bit_bags_count;
35466 var cur_bit_bag: u32 = undefined;
35467 var field_i: u32 = 0;
35468 var last_tag_val: ?Value = null;
35469 const layout = union_type.flagsUnordered(ip).layout;
35470 while (field_i < fields_len) : (field_i += 1) {
35471 if (field_i % fields_per_u32 == 0) {
35472 cur_bit_bag = zir.extra[bit_bag_index];
35473 bit_bag_index += 1;
35474 }
35475 const has_type = @as(u1, @truncate(cur_bit_bag)) != 0;
35476 cur_bit_bag >>= 1;
35477 const has_align = @as(u1, @truncate(cur_bit_bag)) != 0;
35478 cur_bit_bag >>= 1;
35479 const has_tag = @as(u1, @truncate(cur_bit_bag)) != 0;
35480 cur_bit_bag >>= 1;
35481 const unused = @as(u1, @truncate(cur_bit_bag)) != 0;
35482 cur_bit_bag >>= 1;
35483 _ = unused;
35484
35485 const field_name_index: Zir.NullTerminatedString = @enumFromInt(zir.extra[extra_index]);
35486 const field_name_zir = zir.nullTerminatedString(field_name_index);
35487 extra_index += 1;
35488
35489 const field_type_ref: Zir.Inst.Ref = if (has_type) blk: {
35490 const field_type_ref: Zir.Inst.Ref = @enumFromInt(zir.extra[extra_index]);
35491 extra_index += 1;
35492 break :blk field_type_ref;
35493 } else .none;
32881 continue;
32882 };
32883 if (!coerced_val.eql(existing, .fromInterned(field_ty.*), zcu)) {
32884 comptime_val = null;
32885 break;
32886 }
32887 }
3549432888
35495 const align_ref: Zir.Inst.Ref = if (has_align) blk: {
35496 const align_ref: Zir.Inst.Ref = @enumFromInt(zir.extra[extra_index]);
35497 extra_index += 1;
35498 break :blk align_ref;
35499 } else .none;
32889 field_val.* = if (comptime_val) |v| v.toIntern() else .none;
32890 }
3550032891
35501 const tag_ref: Air.Inst.Ref = if (has_tag) blk: {
35502 const tag_ref: Zir.Inst.Ref = @enumFromInt(zir.extra[extra_index]);
35503 extra_index += 1;
35504 break :blk try sema.resolveInst(tag_ref);
35505 } else .none;
32892 const final_ty = try ip.getTupleType(gpa, io, pt.tid, .{
32893 .types = field_types,
32894 .values = field_vals,
32895 });
3550632896
35507 const name_src: LazySrcLoc = .{
35508 .base_node_inst = union_type.zir_index,
35509 .offset = .{ .container_field_name = field_i },
35510 };
35511 const value_src: LazySrcLoc = .{
35512 .base_node_inst = union_type.zir_index,
35513 .offset = .{ .container_field_value = field_i },
35514 };
35515 const align_src: LazySrcLoc = .{
35516 .base_node_inst = union_type.zir_index,
35517 .offset = .{ .container_field_align = field_i },
35518 };
35519 const type_src: LazySrcLoc = .{
35520 .base_node_inst = union_type.zir_index,
35521 .offset = .{ .container_field_type = field_i },
35522 };
32897 return .{ .success = .fromInterned(final_ty) };
32898 },
3552332899
35524 if (enum_field_vals.capacity() > 0) {
35525 const enum_tag_val = if (tag_ref != .none) blk: {
35526 const coerced = try sema.coerce(&block_scope, int_tag_ty, tag_ref, value_src);
35527 const val = try sema.resolveConstDefinedValue(&block_scope, value_src, coerced, .{ .simple = .enum_field_tag_value });
35528 last_tag_val = val;
35529
35530 break :blk val;
35531 } else blk: {
35532 if (last_tag_val) |last_tag| {
35533 const result = try arith.incrementDefinedInt(sema, int_tag_ty, last_tag);
35534 if (result.overflow) return sema.fail(
35535 &block_scope,
35536 value_src,
35537 "enumeration value '{f}' too large for type '{f}'",
35538 .{ result.val.fmtValueSema(pt, sema), int_tag_ty.fmt(pt) },
35539 );
35540 last_tag_val = result.val;
32900 .exact => {
32901 var expect_ty: ?Type = null;
32902 var first_idx: usize = undefined;
32903 for (peer_tys, 0..) |opt_ty, i| {
32904 const ty = opt_ty orelse continue;
32905 if (expect_ty) |expect| {
32906 if (!ty.eql(expect, zcu)) return .{ .conflict = .{
32907 .peer_idx_a = first_idx,
32908 .peer_idx_b = i,
32909 } };
3554132910 } else {
35542 last_tag_val = try pt.intValue(int_tag_ty, 0);
32911 expect_ty = ty;
32912 first_idx = i;
3554332913 }
35544 break :blk last_tag_val.?;
35545 };
35546 const gop = enum_field_vals.getOrPutAssumeCapacity(enum_tag_val.toIntern());
35547 if (gop.found_existing) {
35548 const other_value_src: LazySrcLoc = .{
35549 .base_node_inst = union_type.zir_index,
35550 .offset = .{ .container_field_value = @intCast(gop.index) },
35551 };
35552 const msg = msg: {
35553 const msg = try sema.errMsg(
35554 value_src,
35555 "enum tag value {f} already taken",
35556 .{enum_tag_val.fmtValueSema(pt, sema)},
35557 );
35558 errdefer msg.destroy(gpa);
35559 try sema.errNote(other_value_src, msg, "other occurrence here", .{});
35560 break :msg msg;
35561 };
35562 return sema.failWithOwnedErrorMsg(&block_scope, msg);
3556332914 }
35564 }
35565
35566 // This string needs to outlive the ZIR code.
35567 const field_name = try ip.getOrPutString(gpa, io, pt.tid, field_name_zir, .no_embedded_nulls);
35568 if (enum_field_names.len != 0) {
35569 enum_field_names[field_i] = field_name;
35570 }
35571
35572 const field_ty: Type = if (!has_type)
35573 .void
35574 else if (field_type_ref == .none)
35575 .noreturn
35576 else
35577 try sema.resolveType(&block_scope, type_src, field_type_ref);
35578
35579 if (explicit_tags_seen.len > 0) {
35580 const tag_ty = union_type.tagTypeUnordered(ip);
35581 const tag_info = ip.loadEnumType(tag_ty);
35582 const enum_index = tag_info.nameIndex(ip, field_name) orelse {
35583 return sema.fail(&block_scope, name_src, "no field named '{f}' in enum '{f}'", .{
35584 field_name.fmt(ip), Type.fromInterned(tag_ty).fmt(pt),
35585 });
35586 };
32915 return .{ .success = expect_ty.? };
32916 },
32917 }
32918}
3558732919
35588 // No check for duplicate because the check already happened in order
35589 // to create the enum type in the first place.
35590 assert(!explicit_tags_seen[enum_index]);
35591 explicit_tags_seen[enum_index] = true;
32920fn maybeMergeErrorSets(sema: *Sema, block: *Block, src: LazySrcLoc, e0: Type, e1: Type) !Type {
32921 // e0 -> e1
32922 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, e1, e0, src, src)) {
32923 return e1;
32924 }
3559232925
35593 // Enforce the enum fields and the union fields being in the same order.
35594 if (enum_index != field_i) {
35595 const msg = msg: {
35596 const enum_field_src: LazySrcLoc = .{
35597 .base_node_inst = Type.fromInterned(tag_ty).typeDeclInstAllowGeneratedTag(zcu).?,
35598 .offset = .{ .container_field_name = enum_index },
35599 };
35600 const msg = try sema.errMsg(name_src, "union field '{f}' ordered differently than corresponding enum field", .{
35601 field_name.fmt(ip),
35602 });
35603 errdefer msg.destroy(sema.gpa);
35604 try sema.errNote(enum_field_src, msg, "enum field here", .{});
35605 break :msg msg;
35606 };
35607 return sema.failWithOwnedErrorMsg(&block_scope, msg);
35608 }
35609 }
32926 // e1 -> e0
32927 if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, e0, e1, src, src)) {
32928 return e0;
32929 }
3561032930
35611 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
35612 const msg = msg: {
35613 const msg = try sema.errMsg(type_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{});
35614 errdefer msg.destroy(sema.gpa);
32931 return sema.errorSetMerge(e0, e1);
32932}
3561532933
35616 try sema.addDeclaredHereNote(msg, field_ty);
35617 break :msg msg;
35618 };
35619 return sema.failWithOwnedErrorMsg(&block_scope, msg);
35620 }
35621 switch (layout) {
35622 .@"extern" => if (!try sema.validateExternType(field_ty, .union_field)) {
35623 const msg = msg: {
35624 const msg = try sema.errMsg(type_src, "extern unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
35625 errdefer msg.destroy(sema.gpa);
32934fn resolvePairInMemoryCoercible(sema: *Sema, block: *Block, src: LazySrcLoc, ty_a: Type, ty_b: Type) !?Type {
32935 const target = sema.pt.zcu.getTarget();
3562632936
35627 try sema.explainWhyTypeIsNotExtern(msg, type_src, field_ty, .union_field);
32937 // ty_b -> ty_a
32938 if (.ok == try sema.coerceInMemoryAllowed(block, ty_a, ty_b, false, target, src, src, null)) {
32939 return ty_a;
32940 }
3562832941
35629 try sema.addDeclaredHereNote(msg, field_ty);
35630 break :msg msg;
35631 };
35632 return sema.failWithOwnedErrorMsg(&block_scope, msg);
35633 },
35634 .@"packed" => {
35635 if (!try sema.validatePackedType(field_ty)) {
35636 const msg = msg: {
35637 const msg = try sema.errMsg(type_src, "packed unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
35638 errdefer msg.destroy(sema.gpa);
32942 // ty_a -> ty_b
32943 if (.ok == try sema.coerceInMemoryAllowed(block, ty_b, ty_a, false, target, src, src, null)) {
32944 return ty_b;
32945 }
3563932946
35640 try sema.explainWhyTypeIsNotPacked(msg, type_src, field_ty);
32947 return null;
32948}
3564132949
35642 try sema.addDeclaredHereNote(msg, field_ty);
35643 break :msg msg;
35644 };
35645 return sema.failWithOwnedErrorMsg(&block_scope, msg);
35646 }
35647 const field_bits = try field_ty.bitSizeSema(pt);
35648 if (field_bits >= max_bits) {
35649 max_bits = field_bits;
35650 max_bits_src = type_src;
35651 max_bits_ty = field_ty;
35652 }
35653 if (field_bits <= min_bits) {
35654 min_bits = field_bits;
35655 min_bits_src = type_src;
35656 min_bits_ty = field_ty;
32950const ArrayLike = struct {
32951 len: u64,
32952 /// `noreturn` indicates that this type is `struct{}` so can coerce to anything
32953 elem_ty: Type,
32954};
32955fn typeIsArrayLike(sema: *Sema, ty: Type) ?ArrayLike {
32956 const pt = sema.pt;
32957 const zcu = pt.zcu;
32958 return switch (ty.zigTypeTag(zcu)) {
32959 .array => .{
32960 .len = ty.arrayLen(zcu),
32961 .elem_ty = ty.childType(zcu),
32962 },
32963 .@"struct" => {
32964 if (!ty.isTuple(zcu)) return null;
32965 const field_count = ty.structFieldCount(zcu);
32966 if (field_count == 0) return .{
32967 .len = 0,
32968 .elem_ty = .noreturn,
32969 };
32970 const elem_ty = ty.fieldType(0, zcu);
32971 for (1..field_count) |i| {
32972 if (!ty.fieldType(i, zcu).eql(elem_ty, zcu)) {
32973 return null;
3565732974 }
35658 },
35659 .auto => {},
35660 }
35661
35662 field_types.appendAssumeCapacity(field_ty.toIntern());
35663
35664 if (small.any_aligned_fields) {
35665 field_aligns.appendAssumeCapacity(if (align_ref != .none)
35666 try sema.resolveAlign(&block_scope, align_src, align_ref)
35667 else
35668 .none);
35669 } else {
35670 assert(align_ref == .none);
35671 }
35672 }
35673
35674 union_type.setFieldTypes(ip, field_types.items);
35675 union_type.setFieldAligns(ip, field_aligns.items);
32975 }
32976 return .{
32977 .len = field_count,
32978 .elem_ty = elem_ty,
32979 };
32980 },
32981 else => null,
32982 };
32983}
3567632984
35677 if (layout == .@"packed" and fields_len != 0 and min_bits != max_bits) {
32985fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
32986 const pt = sema.pt;
32987 if (!ty.isIndexable(pt.zcu)) {
3567832988 const msg = msg: {
35679 const msg = try sema.errMsg(src, "packed union has fields with mismatching bit sizes", .{});
32989 const msg = try sema.errMsg(src, "type '{f}' does not support indexing", .{ty.fmt(pt)});
3568032990 errdefer msg.destroy(sema.gpa);
35681 try sema.errNote(min_bits_src, msg, "{d} bits here", .{min_bits});
35682 try sema.addDeclaredHereNote(msg, min_bits_ty);
35683 try sema.errNote(max_bits_src, msg, "{d} bits here", .{max_bits});
35684 try sema.addDeclaredHereNote(msg, max_bits_ty);
32991 try sema.errNote(src, msg, "operand must be an array, slice, tuple, or vector", .{});
3568532992 break :msg msg;
3568632993 };
35687 return sema.failWithOwnedErrorMsg(&block_scope, msg);
32994 return sema.failWithOwnedErrorMsg(block, msg);
3568832995 }
32996}
3568932997
35690 if (explicit_tags_seen.len > 0) {
35691 const tag_ty = union_type.tagTypeUnordered(ip);
35692 const tag_info = ip.loadEnumType(tag_ty);
35693 if (tag_info.names.len > fields_len) {
35694 const msg = msg: {
35695 const msg = try sema.errMsg(src, "enum field(s) missing in union", .{});
35696 errdefer msg.destroy(sema.gpa);
35697
35698 for (tag_info.names.get(ip), 0..) |field_name, field_index| {
35699 if (explicit_tags_seen[field_index]) continue;
35700 try sema.addFieldErrNote(.fromInterned(tag_ty), field_index, msg, "field '{f}' missing, declared here", .{
35701 field_name.fmt(ip),
35702 });
35703 }
35704 try sema.addDeclaredHereNote(msg, .fromInterned(tag_ty));
35705 break :msg msg;
35706 };
35707 return sema.failWithOwnedErrorMsg(&block_scope, msg);
32998fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
32999 const pt = sema.pt;
33000 const zcu = pt.zcu;
33001 if (ty.zigTypeTag(zcu) == .pointer) {
33002 switch (ty.ptrSize(zcu)) {
33003 .slice, .many, .c => return,
33004 .one => {
33005 const elem_ty = ty.childType(zcu);
33006 if (elem_ty.zigTypeTag(zcu) == .array) return;
33007 // TODO https://github.com/ziglang/zig/issues/15479
33008 // if (elem_ty.isTuple()) return;
33009 },
3570833010 }
35709 } else if (enum_field_vals.count() > 0) {
35710 const enum_ty = try sema.generateUnionTagTypeNumbered(&block_scope, enum_field_names, enum_field_vals.keys(), union_ty, union_type.name);
35711 union_type.setTagType(ip, io, enum_ty);
35712 } else {
35713 const enum_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, union_ty, union_type.name);
35714 union_type.setTagType(ip, io, enum_ty);
3571533011 }
35716
35717 try sema.flushExports();
33012 const msg = msg: {
33013 const msg = try sema.errMsg(src, "type '{f}' is not an indexable pointer", .{ty.fmt(pt)});
33014 errdefer msg.destroy(sema.gpa);
33015 try sema.errNote(src, msg, "operand must be a slice, a many pointer or a pointer to an array", .{});
33016 break :msg msg;
33017 };
33018 return sema.failWithOwnedErrorMsg(block, msg);
3571833019}
3571933020
35720fn generateUnionTagTypeNumbered(
33021/// Resolves the inferred error set of the given function, so that the corresponding concrete error
33022/// set is available by calling `InternPool.funcIesResolvedUnordered` on `func_index`.
33023///
33024/// Asserts that `func_index` is a function. Also asserts that it is not a coerced function, because
33025/// coerced functions do not own inferred error sets.
33026fn ensureFuncIesResolved(
3572133027 sema: *Sema,
3572233028 block: *Block,
35723 enum_field_names: []const InternPool.NullTerminatedString,
35724 enum_field_vals: []const InternPool.Index,
35725 union_type: InternPool.Index,
35726 union_name: InternPool.NullTerminatedString,
35727) !InternPool.Index {
33029 src: LazySrcLoc,
33030 func_index: InternPool.Index,
33031) CompileError!void {
3572833032 const pt = sema.pt;
3572933033 const zcu = pt.zcu;
35730 const comp = zcu.comp;
35731 const gpa = comp.gpa;
35732 const io = comp.io;
3573333034 const ip = &zcu.intern_pool;
3573433035
35735 const name = try ip.getOrPutStringFmt(
35736 gpa,
35737 io,
35738 pt.tid,
35739 "@typeInfo({f}).@\"union\".tag_type.?",
35740 .{union_name.fmt(ip)},
35741 .no_embedded_nulls,
35742 );
35743
35744 const enum_ty = try ip.getGeneratedTagEnumType(gpa, io, pt.tid, .{
35745 .name = name,
35746 .owner_union_ty = union_type,
35747 .tag_ty = if (enum_field_vals.len == 0)
35748 (try pt.intType(.unsigned, 0)).toIntern()
35749 else
35750 ip.typeOf(enum_field_vals[0]),
35751 .names = enum_field_names,
35752 .values = enum_field_vals,
35753 .tag_mode = .explicit,
35754 .parent_namespace = block.namespace,
35755 });
35756
35757 return enum_ty;
35758}
33036 assert(ip.unwrapCoercedFunc(func_index) == func_index);
3575933037
35760fn generateUnionTagTypeSimple(
35761 sema: *Sema,
35762 block: *Block,
35763 enum_field_names: []const InternPool.NullTerminatedString,
35764 union_type: InternPool.Index,
35765 union_name: InternPool.NullTerminatedString,
35766) !InternPool.Index {
35767 const pt = sema.pt;
35768 const zcu = pt.zcu;
35769 const comp = zcu.comp;
35770 const gpa = comp.gpa;
35771 const io = comp.io;
35772 const ip = &zcu.intern_pool;
33038 try sema.declareDependency(.{ .func_ies = func_index });
33039 try sema.addReferenceEntry(block, src, .wrap(.{ .func = func_index }));
3577333040
35774 const name = try ip.getOrPutStringFmt(
35775 gpa,
35776 io,
35777 pt.tid,
35778 "@typeInfo({f}).@\"union\".tag_type.?",
35779 .{union_name.fmt(ip)},
35780 .no_embedded_nulls,
35781 );
33041 const reason: Zcu.DependencyReason = .{ .src = src, .type_layout_reason = undefined };
3578233042
35783 const enum_ty = try ip.getGeneratedTagEnumType(gpa, io, pt.tid, .{
35784 .name = name,
35785 .owner_union_ty = union_type,
35786 .tag_ty = (try pt.smallestUnsignedInt(enum_field_names.len -| 1)).toIntern(),
35787 .names = enum_field_names,
35788 .values = &.{},
35789 .tag_mode = .auto,
35790 .parent_namespace = block.namespace,
35791 });
33043 if (zcu.analysis_in_progress.contains(.wrap(.{ .func = func_index }))) {
33044 return sema.failWithDependencyLoop(.wrap(.{ .func = func_index }), &reason);
33045 }
3579233046
35793 return enum_ty;
33047 try pt.ensureFuncBodyUpToDate(func_index, &reason);
3579433048}
3579533049
35796/// There is another implementation of this in `Type.onePossibleValue`. This one
35797/// in `Sema` is for calling during semantic analysis, and performs field resolution
35798/// to get the answer. The one in `Type` is for calling during codegen and asserts
35799/// that the types are already resolved.
35800/// TODO assert the return value matches `ty.onePossibleValue`
35801pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
33050pub fn resolveInferredErrorSetPtr(
33051 sema: *Sema,
33052 block: *Block,
33053 src: LazySrcLoc,
33054 ies: *InferredErrorSet,
33055) CompileError!void {
3580233056 const pt = sema.pt;
35803 const zcu = pt.zcu;
35804 const comp = zcu.comp;
35805 const gpa = comp.gpa;
35806 const io = comp.io;
35807 const ip = &zcu.intern_pool;
35808
35809 return switch (ty.toIntern()) {
35810 .u0_type,
35811 .i0_type,
35812 => try pt.intValue(ty, 0),
35813 .u1_type,
35814 .u8_type,
35815 .i8_type,
35816 .u16_type,
35817 .i16_type,
35818 .u29_type,
35819 .u32_type,
35820 .i32_type,
35821 .u64_type,
35822 .i64_type,
35823 .u80_type,
35824 .u128_type,
35825 .i128_type,
35826 .u256_type,
35827 .usize_type,
35828 .isize_type,
35829 .c_char_type,
35830 .c_short_type,
35831 .c_ushort_type,
35832 .c_int_type,
35833 .c_uint_type,
35834 .c_long_type,
35835 .c_ulong_type,
35836 .c_longlong_type,
35837 .c_ulonglong_type,
35838 .c_longdouble_type,
35839 .f16_type,
35840 .f32_type,
35841 .f64_type,
35842 .f80_type,
35843 .f128_type,
35844 .anyopaque_type,
35845 .bool_type,
35846 .type_type,
35847 .anyerror_type,
35848 .adhoc_inferred_error_set_type,
35849 .comptime_int_type,
35850 .comptime_float_type,
35851 .enum_literal_type,
35852 .ptr_usize_type,
35853 .ptr_const_comptime_int_type,
35854 .manyptr_u8_type,
35855 .manyptr_const_u8_type,
35856 .manyptr_const_u8_sentinel_0_type,
35857 .manyptr_const_slice_const_u8_type,
35858 .slice_const_u8_type,
35859 .slice_const_u8_sentinel_0_type,
35860 .slice_const_slice_const_u8_type,
35861 .optional_type_type,
35862 .manyptr_const_type_type,
35863 .slice_const_type_type,
35864 .vector_8_i8_type,
35865 .vector_16_i8_type,
35866 .vector_32_i8_type,
35867 .vector_64_i8_type,
35868 .vector_1_u8_type,
35869 .vector_2_u8_type,
35870 .vector_4_u8_type,
35871 .vector_8_u8_type,
35872 .vector_16_u8_type,
35873 .vector_32_u8_type,
35874 .vector_64_u8_type,
35875 .vector_2_i16_type,
35876 .vector_4_i16_type,
35877 .vector_8_i16_type,
35878 .vector_16_i16_type,
35879 .vector_32_i16_type,
35880 .vector_4_u16_type,
35881 .vector_8_u16_type,
35882 .vector_16_u16_type,
35883 .vector_32_u16_type,
35884 .vector_2_i32_type,
35885 .vector_4_i32_type,
35886 .vector_8_i32_type,
35887 .vector_16_i32_type,
35888 .vector_4_u32_type,
35889 .vector_8_u32_type,
35890 .vector_16_u32_type,
35891 .vector_2_i64_type,
35892 .vector_4_i64_type,
35893 .vector_8_i64_type,
35894 .vector_2_u64_type,
35895 .vector_4_u64_type,
35896 .vector_8_u64_type,
35897 .vector_1_u128_type,
35898 .vector_2_u128_type,
35899 .vector_1_u256_type,
35900 .vector_4_f16_type,
35901 .vector_8_f16_type,
35902 .vector_16_f16_type,
35903 .vector_32_f16_type,
35904 .vector_2_f32_type,
35905 .vector_4_f32_type,
35906 .vector_8_f32_type,
35907 .vector_16_f32_type,
35908 .vector_2_f64_type,
35909 .vector_4_f64_type,
35910 .vector_8_f64_type,
35911 .anyerror_void_error_union_type,
35912 => null,
35913 .void_type => Value.void,
35914 .noreturn_type => Value.@"unreachable",
35915 .anyframe_type => unreachable,
35916 .null_type => Value.null,
35917 .undefined_type => Value.undef,
35918 .optional_noreturn_type => try pt.nullValue(ty),
35919 .generic_poison_type => unreachable,
35920 .empty_tuple_type => Value.empty_tuple,
35921 // values, not types
35922 .undef,
35923 .undef_bool,
35924 .undef_usize,
35925 .undef_u1,
35926 .zero,
35927 .zero_usize,
35928 .zero_u1,
35929 .zero_u8,
35930 .one,
35931 .one_usize,
35932 .one_u1,
35933 .one_u8,
35934 .four_u8,
35935 .negative_one,
35936 .void_value,
35937 .unreachable_value,
35938 .null_value,
35939 .bool_true,
35940 .bool_false,
35941 .empty_tuple,
35942 // invalid
35943 .none,
35944 => unreachable,
35945
35946 _ => switch (ty.toIntern().unwrap(ip).getTag(ip)) {
35947 .removed => unreachable,
35948
35949 .type_int_signed, // i0 handled above
35950 .type_int_unsigned, // u0 handled above
35951 .type_pointer,
35952 .type_slice,
35953 .type_anyframe,
35954 .type_error_union,
35955 .type_anyerror_union,
35956 .type_error_set,
35957 .type_inferred_error_set,
35958 .type_opaque,
35959 .type_function,
35960 => null,
35961
35962 .simple_type, // handled above
35963 // values, not types
35964 .undef,
35965 .simple_value,
35966 .ptr_nav,
35967 .ptr_uav,
35968 .ptr_uav_aligned,
35969 .ptr_comptime_alloc,
35970 .ptr_comptime_field,
35971 .ptr_int,
35972 .ptr_eu_payload,
35973 .ptr_opt_payload,
35974 .ptr_elem,
35975 .ptr_field,
35976 .ptr_slice,
35977 .opt_payload,
35978 .opt_null,
35979 .int_u8,
35980 .int_u16,
35981 .int_u32,
35982 .int_i32,
35983 .int_usize,
35984 .int_comptime_int_u32,
35985 .int_comptime_int_i32,
35986 .int_small,
35987 .int_positive,
35988 .int_negative,
35989 .int_lazy_align,
35990 .int_lazy_size,
35991 .error_set_error,
35992 .error_union_error,
35993 .error_union_payload,
35994 .enum_literal,
35995 .enum_tag,
35996 .float_f16,
35997 .float_f32,
35998 .float_f64,
35999 .float_f80,
36000 .float_f128,
36001 .float_c_longdouble_f80,
36002 .float_c_longdouble_f128,
36003 .float_comptime_float,
36004 .variable,
36005 .threadlocal_variable,
36006 .@"extern",
36007 .func_decl,
36008 .func_instance,
36009 .func_coerced,
36010 .only_possible_value,
36011 .union_value,
36012 .bytes,
36013 .aggregate,
36014 .repeated,
36015 // memoized value, not types
36016 .memoized_call,
36017 => unreachable,
36018
36019 .type_array_big,
36020 .type_array_small,
36021 .type_vector,
36022 .type_enum_auto,
36023 .type_enum_explicit,
36024 .type_enum_nonexhaustive,
36025 .type_struct,
36026 .type_struct_packed,
36027 .type_struct_packed_inits,
36028 .type_tuple,
36029 .type_union,
36030 => switch (ip.indexToKey(ty.toIntern())) {
36031 inline .array_type, .vector_type => |seq_type, seq_tag| {
36032 const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none;
36033 if (seq_type.len + @intFromBool(has_sentinel) == 0) return try pt.aggregateValue(ty, &.{});
36034 if (try sema.typeHasOnePossibleValue(.fromInterned(seq_type.child))) |opv| {
36035 return try pt.aggregateSplatValue(ty, opv);
36036 }
36037 return null;
36038 },
36039
36040 .struct_type => {
36041 // Resolving the layout first helps to avoid loops.
36042 // If the type has a coherent layout, we can recurse through fields safely.
36043 try ty.resolveLayout(pt);
36044
36045 const struct_type = ip.loadStructType(ty.toIntern());
36046
36047 if (struct_type.field_types.len == 0) {
36048 // In this case the struct has no fields at all and
36049 // therefore has one possible value.
36050 return try pt.aggregateValue(ty, &.{});
36051 }
36052
36053 const field_vals = try sema.arena.alloc(
36054 InternPool.Index,
36055 struct_type.field_types.len,
36056 );
36057 for (field_vals, 0..) |*field_val, i| {
36058 if (struct_type.fieldIsComptime(ip, i)) {
36059 try ty.resolveStructFieldInits(pt);
36060 field_val.* = struct_type.field_inits.get(ip)[i];
36061 continue;
36062 }
36063 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[i]);
36064 if (try sema.typeHasOnePossibleValue(field_ty)) |field_opv| {
36065 field_val.* = field_opv.toIntern();
36066 } else return null;
36067 }
36068
36069 // In this case the struct has no runtime-known fields and
36070 // therefore has one possible value.
36071 return try pt.aggregateValue(ty, field_vals);
36072 },
36073
36074 .tuple_type => |tuple| {
36075 try ty.resolveLayout(pt);
36076
36077 if (tuple.types.len == 0) {
36078 return try pt.aggregateValue(ty, &.{});
36079 }
33057 const ip = &pt.zcu.intern_pool;
3608033058
36081 const field_vals = try sema.arena.alloc(
36082 InternPool.Index,
36083 tuple.types.len,
36084 );
36085 for (
36086 field_vals,
36087 tuple.types.get(ip),
36088 tuple.values.get(ip),
36089 ) |*field_val, field_ty, field_comptime_val| {
36090 if (field_comptime_val != .none) {
36091 field_val.* = field_comptime_val;
36092 continue;
36093 }
36094 if (try sema.typeHasOnePossibleValue(.fromInterned(field_ty))) |opv| {
36095 field_val.* = opv.toIntern();
36096 } else return null;
36097 }
33059 if (ies.resolved != .none) return;
3609833060
36099 return try pt.aggregateValue(ty, field_vals);
36100 },
33061 const ies_index = ip.errorUnionSet(sema.fn_ret_ty.toIntern());
3610133062
36102 .union_type => {
36103 // Resolving the layout first helps to avoid loops.
36104 // If the type has a coherent layout, we can recurse through fields safely.
36105 try ty.resolveLayout(pt);
36106
36107 const union_obj = ip.loadUnionType(ty.toIntern());
36108 const tag_val = (try sema.typeHasOnePossibleValue(.fromInterned(union_obj.tagTypeUnordered(ip)))) orelse
36109 return null;
36110 if (union_obj.field_types.len == 0) {
36111 const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() });
36112 return Value.fromInterned(only);
36113 }
36114 const only_field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[0]);
36115 const val_val = (try sema.typeHasOnePossibleValue(only_field_ty)) orelse
36116 return null;
36117 const only = try pt.internUnion(.{
36118 .ty = ty.toIntern(),
36119 .tag = tag_val.toIntern(),
36120 .val = val_val.toIntern(),
36121 });
36122 return Value.fromInterned(only);
36123 },
33063 for (ies.inferred_error_sets.keys()) |other_ies_index| {
33064 if (ies_index == other_ies_index) continue;
33065 const other_func_index = ip.iesFuncIndex(other_ies_index);
33066 try sema.ensureFuncIesResolved(block, src, other_func_index);
33067 switch (ip.funcIesResolvedUnordered(other_func_index)) {
33068 .anyerror_type => {
33069 ies.resolved = .anyerror_type;
33070 return;
33071 },
33072 else => |error_set_ty_index| {
33073 const names = ip.indexToKey(error_set_ty_index).error_set_type.names;
33074 for (names.get(ip)) |name| {
33075 try ies.errors.put(sema.arena, name, {});
33076 }
33077 },
33078 }
33079 }
3612433080
36125 .enum_type => {
36126 const enum_type = ip.loadEnumType(ty.toIntern());
36127 switch (enum_type.tag_mode) {
36128 .nonexhaustive => {
36129 if (enum_type.tag_ty == .comptime_int_type) return null;
33081 const resolved_error_set_ty = try pt.errorSetFromUnsortedNames(ies.errors.keys());
33082 ies.resolved = resolved_error_set_ty.toIntern();
33083}
3613033084
36131 if (try sema.typeHasOnePossibleValue(.fromInterned(enum_type.tag_ty))) |int_opv| {
36132 const only = try pt.intern(.{ .enum_tag = .{
36133 .ty = ty.toIntern(),
36134 .int = int_opv.toIntern(),
36135 } });
36136 return Value.fromInterned(only);
36137 }
33085fn resolveAdHocInferredErrorSet(
33086 sema: *Sema,
33087 block: *Block,
33088 src: LazySrcLoc,
33089 value: InternPool.Index,
33090) CompileError!InternPool.Index {
33091 const pt = sema.pt;
33092 const zcu = pt.zcu;
33093 const comp = zcu.comp;
33094 const gpa = comp.gpa;
33095 const io = comp.io;
33096 const ip = &zcu.intern_pool;
3613833097
36139 return null;
36140 },
36141 .auto, .explicit => {
36142 if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(zcu)) return null;
36143
36144 return Value.fromInterned(switch (enum_type.names.len) {
36145 0 => try pt.intern(.{ .empty_enum_value = ty.toIntern() }),
36146 1 => try pt.intern(.{ .enum_tag = .{
36147 .ty = ty.toIntern(),
36148 .int = if (enum_type.values.len == 0)
36149 (try pt.intValue(.fromInterned(enum_type.tag_ty), 0)).toIntern()
36150 else
36151 try ip.getCoercedInts(
36152 gpa,
36153 io,
36154 pt.tid,
36155 ip.indexToKey(enum_type.values.get(ip)[0]).int,
36156 enum_type.tag_ty,
36157 ),
36158 } }),
36159 else => return null,
36160 });
36161 },
36162 }
36163 },
33098 const new_ty = try resolveAdHocInferredErrorSetTy(sema, block, src, ip.typeOf(value));
33099 if (new_ty == .none) return value;
33100 return ip.getCoerced(gpa, io, pt.tid, value, new_ty);
33101}
3616433102
36165 else => unreachable,
36166 },
33103fn resolveAdHocInferredErrorSetTy(
33104 sema: *Sema,
33105 block: *Block,
33106 src: LazySrcLoc,
33107 ty: InternPool.Index,
33108) CompileError!InternPool.Index {
33109 const ies = sema.fn_ret_ty_ies orelse return .none;
33110 const pt = sema.pt;
33111 const zcu = pt.zcu;
33112 const ip = &zcu.intern_pool;
33113 const error_union_info = switch (ip.indexToKey(ty)) {
33114 .error_union_type => |x| x,
33115 else => return .none,
33116 };
33117 if (error_union_info.error_set_type != .adhoc_inferred_error_set_type)
33118 return .none;
3616733119
36168 .type_optional => {
36169 const payload_ip = ip.indexToKey(ty.toIntern()).opt_type;
36170 // Although ?noreturn is handled above, the element type
36171 // can be effectively noreturn for example via an empty
36172 // enum or error set.
36173 if (ip.isNoReturn(payload_ip)) return try pt.nullValue(ty);
36174 return null;
36175 },
33120 try sema.resolveInferredErrorSetPtr(block, src, ies);
33121 const new_ty = try pt.intern(.{ .error_union_type = .{
33122 .error_set_type = ies.resolved,
33123 .payload_type = error_union_info.payload_type,
33124 } });
33125 return new_ty;
33126}
33127
33128fn resolveInferredErrorSetTy(
33129 sema: *Sema,
33130 block: *Block,
33131 src: LazySrcLoc,
33132 ty: InternPool.Index,
33133) CompileError!InternPool.Index {
33134 const pt = sema.pt;
33135 const zcu = pt.zcu;
33136 const ip = &zcu.intern_pool;
33137 if (ty == .anyerror_type) return ty;
33138 switch (ip.indexToKey(ty)) {
33139 .error_set_type => return ty,
33140 .inferred_error_set_type => |func_index| {
33141 try sema.ensureFuncIesResolved(block, src, func_index);
33142 return ip.funcIesResolvedUnordered(func_index);
3617633143 },
36177 };
33144 else => unreachable,
33145 }
3617833146}
3617933147
3618033148/// Returns the type of the AIR instruction.
......@@ -36232,9 +33200,10 @@ fn isComptimeKnown(
3623233200 sema: *Sema,
3623333201 inst: Air.Inst.Ref,
3623433202) !bool {
36235 return (try sema.resolveValue(inst)) != null;
33203 return sema.resolveValue(inst) != null;
3623633204}
3623733205
33206/// Asserts that the layout of `var_type` has already been resolved.
3623833207fn analyzeComptimeAlloc(
3623933208 sema: *Sema,
3624033209 block: *Block,
......@@ -36245,10 +33214,9 @@ fn analyzeComptimeAlloc(
3624533214 const pt = sema.pt;
3624633215 const zcu = pt.zcu;
3624733216
36248 // Needed to make an anon decl with type `var_type` (the `finish()` call below).
36249 _ = try sema.typeHasOnePossibleValue(var_type);
33217 var_type.assertHasLayout(zcu);
3625033218
36251 const ptr_type = try pt.ptrTypeSema(.{
33219 const ptr_type = try pt.ptrType(.{
3625233220 .child = var_type.toIntern(),
3625333221 .flags = .{
3625433222 .alignment = alignment,
......@@ -36256,13 +33224,23 @@ fn analyzeComptimeAlloc(
3625633224 },
3625733225 });
3625833226
36259 const alloc = try sema.newComptimeAlloc(block, src, var_type, alignment);
36260
36261 return Air.internedToRef((try pt.intern(.{ .ptr = .{
36262 .ty = ptr_type.toIntern(),
36263 .base_addr = .{ .comptime_alloc = alloc },
36264 .byte_offset = 0,
36265 } })));
33227 if (try var_type.onePossibleValue(pt)) |opv| {
33228 return .fromIntern(try pt.intern(.{ .ptr = .{
33229 .ty = ptr_type.toIntern(),
33230 .base_addr = .{ .uav = .{
33231 .val = opv.toIntern(),
33232 .orig_ty = ptr_type.toIntern(),
33233 } },
33234 .byte_offset = 0,
33235 } }));
33236 } else {
33237 const alloc = try sema.newComptimeAlloc(block, src, var_type, alignment);
33238 return .fromIntern(try pt.intern(.{ .ptr = .{
33239 .ty = ptr_type.toIntern(),
33240 .base_addr = .{ .comptime_alloc = alloc },
33241 .byte_offset = 0,
33242 } }));
33243 }
3626633244}
3626733245
3626833246fn resolveAddressSpace(
......@@ -36272,7 +33250,7 @@ fn resolveAddressSpace(
3627233250 zir_ref: Zir.Inst.Ref,
3627333251 ctx: std.Target.AddressSpaceContext,
3627433252) !std.builtin.AddressSpace {
36275 const air_ref = try sema.resolveInst(zir_ref);
33253 const air_ref = sema.resolveInst(zir_ref);
3627633254 return sema.analyzeAsAddressSpace(block, src, air_ref, ctx);
3627733255}
3627833256
......@@ -36363,40 +33341,7 @@ fn usizeCast(sema: *Sema, block: *Block, src: LazySrcLoc, int: u64) CompileError
3636333341 return std.math.cast(usize, int) orelse return sema.fail(block, src, "expression produces integer value '{d}' which is too big for this compiler implementation to handle", .{int});
3636433342}
3636533343
36366/// For pointer-like optionals, it returns the pointer type. For pointers,
36367/// the type is returned unmodified.
36368/// This can return `error.AnalysisFail` because it sometimes requires resolving whether
36369/// a type has zero bits, which can cause a "foo depends on itself" compile error.
36370/// This logic must be kept in sync with `Type.isPtrLikeOptional`.
36371fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {
36372 const pt = sema.pt;
36373 const zcu = pt.zcu;
36374 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
36375 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
36376 .one, .many, .c => ty,
36377 .slice => null,
36378 },
36379 .opt_type => |opt_child| switch (zcu.intern_pool.indexToKey(opt_child)) {
36380 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
36381 .slice, .c => null,
36382 .many, .one => {
36383 if (ptr_type.flags.is_allowzero) return null;
36384
36385 // optionals of zero sized types behave like bools, not pointers
36386 const payload_ty: Type = .fromInterned(opt_child);
36387 if ((try sema.typeHasOnePossibleValue(payload_ty)) != null) {
36388 return null;
36389 }
36390
36391 return payload_ty;
36392 },
36393 },
36394 else => null,
36395 },
36396 else => null,
36397 };
36398}
36399
33344/// Asserts that the layout of `union_ty` is already resolved.
3640033345fn unionFieldIndex(
3640133346 sema: *Sema,
3640233347 block: *Block,
......@@ -36407,13 +33352,14 @@ fn unionFieldIndex(
3640733352 const pt = sema.pt;
3640833353 const zcu = pt.zcu;
3640933354 const ip = &zcu.intern_pool;
36410 try union_ty.resolveFields(pt);
3641133355 const union_obj = zcu.typeToUnion(union_ty).?;
36412 const field_index = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse
33356 const enum_obj = ip.loadEnumType(union_obj.enum_tag_type);
33357 const field_index = enum_obj.nameIndex(ip, field_name) orelse
3641333358 return sema.failWithBadUnionFieldAccess(block, union_ty, union_obj, field_src, field_name);
3641433359 return @intCast(field_index);
3641533360}
3641633361
33362/// Asserts that the layout of `struct_ty` is already resolved.
3641733363fn structFieldIndex(
3641833364 sema: *Sema,
3641933365 block: *Block,
......@@ -36424,7 +33370,6 @@ fn structFieldIndex(
3642433370 const pt = sema.pt;
3642533371 const zcu = pt.zcu;
3642633372 const ip = &zcu.intern_pool;
36427 try struct_ty.resolveFields(pt);
3642833373 const struct_type = zcu.typeToStruct(struct_ty).?;
3642933374 return struct_type.nameIndex(ip, field_name) orelse
3643033375 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_src, field_name);
......@@ -36509,102 +33454,25 @@ fn intFromFloatScalar(
3650933454 return pt.getCoerced(cti_result, int_ty);
3651033455}
3651133456
36512/// Asserts the value is an integer, and the destination type is ComptimeInt or Int.
36513/// Vectors are also accepted. Vector results are reduced with AND.
36514///
36515/// If provided, `vector_index` reports the first element that failed the range check.
36516fn intFitsInType(
36517 sema: *Sema,
36518 val: Value,
36519 ty: Type,
36520 vector_index: ?*usize,
36521) CompileError!bool {
36522 const pt = sema.pt;
36523 const zcu = pt.zcu;
36524 if (ty.toIntern() == .comptime_int_type) return true;
36525 const info = ty.intInfo(zcu);
36526 switch (val.toIntern()) {
36527 .zero_usize, .zero_u8 => return true,
36528 else => switch (zcu.intern_pool.indexToKey(val.toIntern())) {
36529 .undef => return true,
36530 .variable, .@"extern", .func, .ptr => {
36531 const target = zcu.getTarget();
36532 const ptr_bits = target.ptrBitWidth();
36533 return switch (info.signedness) {
36534 .signed => info.bits > ptr_bits,
36535 .unsigned => info.bits >= ptr_bits,
36536 };
36537 },
36538 .int => |int| switch (int.storage) {
36539 .u64, .i64, .big_int => {
36540 var buffer: InternPool.Key.Int.Storage.BigIntSpace = undefined;
36541 const big_int = int.storage.toBigInt(&buffer);
36542 return big_int.fitsInTwosComp(info.signedness, info.bits);
36543 },
36544 .lazy_align => |lazy_ty| {
36545 const max_needed_bits = @as(u16, 16) + @intFromBool(info.signedness == .signed);
36546 // If it is u16 or bigger we know the alignment fits without resolving it.
36547 if (info.bits >= max_needed_bits) return true;
36548 const x = try Type.fromInterned(lazy_ty).abiAlignmentSema(pt);
36549 if (x == .none) return true;
36550 const actual_needed_bits = @as(usize, x.toLog2Units()) + 1 + @intFromBool(info.signedness == .signed);
36551 return info.bits >= actual_needed_bits;
36552 },
36553 .lazy_size => |lazy_ty| {
36554 const max_needed_bits = @as(u16, 64) + @intFromBool(info.signedness == .signed);
36555 // If it is u64 or bigger we know the size fits without resolving it.
36556 if (info.bits >= max_needed_bits) return true;
36557 const x = try Type.fromInterned(lazy_ty).abiSizeSema(pt);
36558 if (x == 0) return true;
36559 const actual_needed_bits = std.math.log2(x) + 1 + @intFromBool(info.signedness == .signed);
36560 return info.bits >= actual_needed_bits;
36561 },
36562 },
36563 .aggregate => |aggregate| {
36564 assert(ty.zigTypeTag(zcu) == .vector);
36565 return switch (aggregate.storage) {
36566 .bytes => |bytes| for (bytes.toSlice(ty.vectorLen(zcu), &zcu.intern_pool), 0..) |byte, i| {
36567 if (byte == 0) continue;
36568 const actual_needed_bits = std.math.log2(byte) + 1 + @intFromBool(info.signedness == .signed);
36569 if (info.bits >= actual_needed_bits) continue;
36570 if (vector_index) |vi| vi.* = i;
36571 break false;
36572 } else true,
36573 .elems, .repeated_elem => for (switch (aggregate.storage) {
36574 .bytes => unreachable,
36575 .elems => |elems| elems,
36576 .repeated_elem => |elem| @as(*const [1]InternPool.Index, &elem),
36577 }, 0..) |elem, i| {
36578 if (try sema.intFitsInType(Value.fromInterned(elem), ty.scalarType(zcu), null)) continue;
36579 if (vector_index) |vi| vi.* = i;
36580 break false;
36581 } else true,
36582 };
36583 },
36584 else => unreachable,
36585 },
36586 }
36587}
36588
3658933457fn intInRange(sema: *Sema, tag_ty: Type, int_val: Value, end: usize) !bool {
3659033458 const pt = sema.pt;
36591 if (!(try int_val.compareAllWithZeroSema(.gte, pt))) return false;
33459 if (!int_val.compareAllWithZero(.gte, pt.zcu)) return false;
3659233460 const end_val = try pt.intValue(tag_ty, end);
3659333461 if (!(try sema.compareAll(int_val, .lt, end_val, tag_ty))) return false;
3659433462 return true;
3659533463}
3659633464
36597/// Asserts the type is an enum.
33465/// Asserts the type is an exhaustive enum.
3659833466fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool {
3659933467 const pt = sema.pt;
3660033468 const zcu = pt.zcu;
3660133469 const enum_type = zcu.intern_pool.loadEnumType(ty.toIntern());
36602 assert(enum_type.tag_mode != .nonexhaustive);
33470 assert(!enum_type.nonexhaustive);
3660333471 // The `tagValueIndex` function call below relies on the type being the integer tag type.
3660433472 // `getCoerced` assumes the value will fit the new type.
36605 if (!(try sema.intFitsInType(int, .fromInterned(enum_type.tag_ty), null))) return false;
36606 const int_coerced = try pt.getCoerced(int, .fromInterned(enum_type.tag_ty));
36607
33473 const int_tag_ty: Type = .fromInterned(enum_type.int_tag_type);
33474 if (!int.intFitsInType(int_tag_ty, null, zcu)) return false;
33475 const int_coerced = try pt.getCoerced(int, int_tag_ty);
3660833476 return enum_type.tagValueIndex(&zcu.intern_pool, int_coerced.toIntern()) != null;
3660933477}
3661033478
......@@ -36644,17 +33512,19 @@ fn compareScalar(
3664433512 ty: Type,
3664533513) CompileError!bool {
3664633514 const pt = sema.pt;
33515 const zcu = pt.zcu;
33516
3664733517 const coerced_lhs = try pt.getCoerced(lhs, ty);
3664833518 const coerced_rhs = try pt.getCoerced(rhs, ty);
3664933519
3665033520 // Equality comparisons of signed zero and NaN need to use floating point semantics
36651 if (coerced_lhs.isFloat(pt.zcu) or coerced_rhs.isFloat(pt.zcu))
36652 return Value.compareHeteroSema(coerced_lhs, op, coerced_rhs, pt);
33521 if (coerced_lhs.isFloat(zcu) or coerced_rhs.isFloat(zcu))
33522 return Value.compareHetero(coerced_lhs, op, coerced_rhs, zcu);
3665333523
3665433524 switch (op) {
36655 .eq => return sema.valuesEqual(coerced_lhs, coerced_rhs, ty),
36656 .neq => return !(try sema.valuesEqual(coerced_lhs, coerced_rhs, ty)),
36657 else => return Value.compareHeteroSema(coerced_lhs, op, coerced_rhs, pt),
33525 .eq => return Value.eql(coerced_lhs, coerced_rhs, ty, zcu),
33526 .neq => return !Value.eql(coerced_lhs, coerced_rhs, ty, zcu),
33527 else => return Value.compareHetero(coerced_lhs, op, coerced_rhs, zcu),
3665833528 }
3665933529}
3666033530
......@@ -36716,25 +33586,6 @@ fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {
3671633586 return pt.errorSetFromUnsortedNames(names.keys());
3671733587}
3671833588
36719/// Avoids crashing the compiler when asking if inferred allocations are noreturn.
36720fn isNoReturn(sema: *Sema, ref: Air.Inst.Ref) bool {
36721 if (ref == .unreachable_value) return true;
36722 if (ref.toIndex()) |inst| switch (sema.air_instructions.items(.tag)[@intFromEnum(inst)]) {
36723 .inferred_alloc, .inferred_alloc_comptime => return false,
36724 else => {},
36725 };
36726 return sema.typeOf(ref).isNoReturn(sema.pt.zcu);
36727}
36728
36729/// Avoids crashing the compiler when asking if inferred allocations are known to be a certain zig type.
36730fn isKnownZigType(sema: *Sema, ref: Air.Inst.Ref, tag: std.builtin.TypeId) bool {
36731 if (ref.toIndex()) |inst| switch (sema.air_instructions.items(.tag)[@intFromEnum(inst)]) {
36732 .inferred_alloc, .inferred_alloc_comptime => return false,
36733 else => {},
36734 };
36735 return sema.typeOf(ref).zigTypeTag(sema.pt.zcu) == tag;
36736}
36737
3673833589pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
3673933590 const pt = sema.pt;
3674033591 if (!pt.zcu.comp.config.incremental) return;
......@@ -36742,23 +33593,6 @@ pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
3674233593 const gop = try sema.dependencies.getOrPut(sema.gpa, dependee);
3674333594 if (gop.found_existing) return;
3674433595
36745 // Avoid creating dependencies on ourselves. This situation can arise when we analyze the fields
36746 // of a type and they use `@This()`. This dependency would be unnecessary, and in fact would
36747 // just result in over-analysis since `Zcu.findOutdatedToAnalyze` would never be able to resolve
36748 // the loop.
36749 // Note that this also disallows a `nav_val`
36750 switch (sema.owner.unwrap()) {
36751 .nav_val => |this_nav| switch (dependee) {
36752 .nav_val => |other_nav| if (this_nav == other_nav) return,
36753 else => {},
36754 },
36755 .nav_ty => |this_nav| switch (dependee) {
36756 .nav_ty => |other_nav| if (this_nav == other_nav) return,
36757 else => {},
36758 },
36759 else => {},
36760 }
36761
3676233596 try pt.addDependency(sema.owner, dependee);
3676333597}
3676433598
......@@ -36799,7 +33633,7 @@ fn validateRuntimeValue(sema: *Sema, block: *Block, val_src: LazySrcLoc, val: Ai
3679933633 });
3680033634}
3680133635
36802fn failWithContainsReferenceToComptimeVar(sema: *Sema, block: *Block, src: LazySrcLoc, value_name: InternPool.NullTerminatedString, kind_of_value: []const u8, val: ?Value) CompileError {
33636pub fn failWithContainsReferenceToComptimeVar(sema: *Sema, block: *Block, src: LazySrcLoc, value_name: InternPool.NullTerminatedString, kind_of_value: []const u8, val: ?Value) CompileError {
3680333637 return sema.failWithOwnedErrorMsg(block, msg: {
3680433638 const msg = try sema.errMsg(src, "{s} contains reference to comptime var", .{kind_of_value});
3680533639 errdefer msg.destroy(sema.gpa);
......@@ -36867,11 +33701,7 @@ fn notePathToComptimeAllocPtr(
3686733701 else => {}, // there will be another stage
3686833702 }
3686933703
36870 const derivation = comptime_ptr.pointerDerivationAdvanced(arena, pt, false, sema) catch |err| switch (err) {
36871 error.OutOfMemory => |e| return e,
36872 error.Canceled => @panic("TODO"), // pls don't be cancelable mlugg
36873 error.AnalysisFail => unreachable,
36874 };
33704 const derivation = try comptime_ptr.pointerDerivation(arena, pt, sema);
3687533705
3687633706 var second_path_aw: std.Io.Writer.Allocating = .init(arena);
3687733707 defer second_path_aw.deinit();
......@@ -36983,7 +33813,6 @@ fn anyUndef(sema: *Sema, block: *Block, src: LazySrcLoc, val: Value) !bool {
3698333813 const zcu = pt.zcu;
3698433814 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
3698533815 .undef => true,
36986 .simple_value => |v| v == .undefined,
3698733816 .slice => {
3698833817 // If the slice contents are runtime-known, reification will fail later on with a
3698933818 // specific error message.
......@@ -37058,12 +33887,12 @@ fn maybeDerefSliceAsArray(
3705833887 else => unreachable,
3705933888 };
3706033889 const elem_ty = Type.fromInterned(slice.ty).childType(zcu);
37061 const len = try Value.fromInterned(slice.len).toUnsignedIntSema(pt);
33890 const len = Value.fromInterned(slice.len).toUnsignedInt(zcu);
3706233891 const array_ty = try pt.arrayType(.{
3706333892 .child = elem_ty.toIntern(),
3706433893 .len = len,
3706533894 });
37066 const ptr_ty = try pt.ptrTypeSema(p: {
33895 const ptr_ty = try pt.ptrType(p: {
3706733896 var p = Type.fromInterned(slice.ty).ptrInfo(zcu);
3706833897 p.flags.size = .one;
3706933898 p.child = array_ty.toIntern();
......@@ -37097,19 +33926,9 @@ pub fn flushExports(sema: *Sema) !void {
3709733926 const zcu = sema.pt.zcu;
3709833927 const gpa = zcu.gpa;
3709933928
37100 // There may be existing exports. For instance, a struct may export
37101 // things during both field type resolution and field default resolution.
37102 //
37103 // So, pick up and delete any existing exports. This strategy performs
37104 // redundant work, but that's okay, because this case is exceedingly rare.
37105 if (zcu.single_exports.get(sema.owner)) |export_idx| {
37106 try sema.exports.append(gpa, export_idx.ptr(zcu).*);
37107 } else if (zcu.multi_exports.get(sema.owner)) |info| {
37108 try sema.exports.appendSlice(gpa, zcu.all_exports.items[info.index..][0..info.len]);
37109 }
37110 zcu.deleteUnitExports(sema.owner);
33929 assert(!zcu.single_exports.contains(sema.owner));
33930 assert(!zcu.multi_exports.contains(sema.owner));
3711133931
37112 // `sema.exports` is completed; store the data into the `Zcu`.
3711333932 if (sema.exports.items.len == 1) {
3711433933 try zcu.single_exports.ensureUnusedCapacity(gpa, 1);
3711533934 const export_idx: Zcu.Export.Index = zcu.free_exports.pop() orelse idx: {
......@@ -37129,238 +33948,6 @@ pub fn flushExports(sema: *Sema) !void {
3712933948 }
3713033949}
3713133950
37132/// Called as soon as a `declared` enum type is created.
37133/// Resolves the tag type and field inits.
37134/// Marks the `src_inst` dependency on the enum's declaration, so call sites need not do this.
37135pub fn resolveDeclaredEnum(
37136 pt: Zcu.PerThread,
37137 wip_ty: InternPool.WipEnumType,
37138 inst: Zir.Inst.Index,
37139 tracked_inst: InternPool.TrackedInst.Index,
37140 namespace: InternPool.NamespaceIndex,
37141 type_name: InternPool.NullTerminatedString,
37142 small: Zir.Inst.EnumDecl.Small,
37143 body: []const Zir.Inst.Index,
37144 tag_type_ref: Zir.Inst.Ref,
37145 any_values: bool,
37146 fields_len: u32,
37147 zir: Zir,
37148 body_end: usize,
37149) Zcu.SemaError!void {
37150 const zcu = pt.zcu;
37151 const gpa = zcu.gpa;
37152
37153 const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(.zero) };
37154
37155 var arena: std.heap.ArenaAllocator = .init(gpa);
37156 defer arena.deinit();
37157
37158 var comptime_err_ret_trace: std.array_list.Managed(Zcu.LazySrcLoc) = .init(gpa);
37159 defer comptime_err_ret_trace.deinit();
37160
37161 var sema: Sema = .{
37162 .pt = pt,
37163 .gpa = gpa,
37164 .arena = arena.allocator(),
37165 .code = zir,
37166 .owner = .wrap(.{ .type = wip_ty.index }),
37167 .func_index = .none,
37168 .func_is_naked = false,
37169 .fn_ret_ty = .void,
37170 .fn_ret_ty_ies = null,
37171 .comptime_err_ret_trace = &comptime_err_ret_trace,
37172 };
37173 defer sema.deinit();
37174
37175 if (zcu.comp.debugIncremental()) {
37176 const info = try zcu.incremental_debug_state.getUnitInfo(gpa, sema.owner);
37177 info.last_update_gen = zcu.generation;
37178 }
37179
37180 try sema.declareDependency(.{ .src_hash = tracked_inst });
37181
37182 var block: Block = .{
37183 .parent = null,
37184 .sema = &sema,
37185 .namespace = namespace,
37186 .instructions = .{},
37187 .inlining = null,
37188 .comptime_reason = .{ .reason = .{
37189 .src = src,
37190 .r = .{ .simple = .enum_field_values },
37191 } },
37192 .src_base_inst = tracked_inst,
37193 .type_name_ctx = type_name,
37194 };
37195 defer block.instructions.deinit(gpa);
37196
37197 sema.resolveDeclaredEnumInner(
37198 &block,
37199 wip_ty,
37200 inst,
37201 tracked_inst,
37202 src,
37203 small,
37204 body,
37205 tag_type_ref,
37206 any_values,
37207 fields_len,
37208 zir,
37209 body_end,
37210 ) catch |err| switch (err) {
37211 error.ComptimeBreak => unreachable,
37212 error.ComptimeReturn => unreachable,
37213 error.OutOfMemory, error.Canceled => |e| return e,
37214 error.AnalysisFail => {
37215 if (!zcu.failed_analysis.contains(sema.owner)) {
37216 try zcu.transitive_failed_analysis.put(gpa, sema.owner, {});
37217 }
37218 return error.AnalysisFail;
37219 },
37220 };
37221}
37222
37223fn resolveDeclaredEnumInner(
37224 sema: *Sema,
37225 block: *Block,
37226 wip_ty: InternPool.WipEnumType,
37227 inst: Zir.Inst.Index,
37228 tracked_inst: InternPool.TrackedInst.Index,
37229 src: LazySrcLoc,
37230 small: Zir.Inst.EnumDecl.Small,
37231 body: []const Zir.Inst.Index,
37232 tag_type_ref: Zir.Inst.Ref,
37233 any_values: bool,
37234 fields_len: u32,
37235 zir: Zir,
37236 body_end: usize,
37237) Zcu.CompileError!void {
37238 const pt = sema.pt;
37239 const zcu = pt.zcu;
37240 const comp = zcu.comp;
37241 const gpa = comp.gpa;
37242 const io = comp.io;
37243 const ip = &zcu.intern_pool;
37244
37245 const bit_bags_count = std.math.divCeil(usize, fields_len, 32) catch unreachable;
37246
37247 const tag_ty_src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = .{ .node_offset_container_tag = .zero } };
37248
37249 const int_tag_ty = ty: {
37250 if (body.len != 0) {
37251 _ = try sema.analyzeInlineBody(block, body, inst);
37252 }
37253
37254 if (tag_type_ref != .none) {
37255 const ty = try sema.resolveType(block, tag_ty_src, tag_type_ref);
37256 if (ty.zigTypeTag(zcu) != .int and ty.zigTypeTag(zcu) != .comptime_int) {
37257 return sema.fail(block, tag_ty_src, "expected integer tag type, found '{f}'", .{ty.fmt(pt)});
37258 }
37259 break :ty ty;
37260 } else if (fields_len == 0) {
37261 break :ty try pt.intType(.unsigned, 0);
37262 } else {
37263 const bits = std.math.log2_int_ceil(usize, fields_len);
37264 break :ty try pt.intType(.unsigned, bits);
37265 }
37266 };
37267
37268 wip_ty.setTagTy(ip, int_tag_ty.toIntern());
37269
37270 var extra_index = body_end + bit_bags_count;
37271 var bit_bag_index: usize = body_end;
37272 var cur_bit_bag: u32 = undefined;
37273 var last_tag_val: ?Value = null;
37274 for (0..fields_len) |field_i_usize| {
37275 const field_i: u32 = @intCast(field_i_usize);
37276 if (field_i % 32 == 0) {
37277 cur_bit_bag = zir.extra[bit_bag_index];
37278 bit_bag_index += 1;
37279 }
37280 const has_tag_value = @as(u1, @truncate(cur_bit_bag)) != 0;
37281 cur_bit_bag >>= 1;
37282
37283 const field_name_index: Zir.NullTerminatedString = @enumFromInt(zir.extra[extra_index]);
37284 const field_name_zir = zir.nullTerminatedString(field_name_index);
37285 extra_index += 1; // field name
37286
37287 const field_name = try ip.getOrPutString(gpa, io, pt.tid, field_name_zir, .no_embedded_nulls);
37288
37289 const value_src: LazySrcLoc = .{
37290 .base_node_inst = tracked_inst,
37291 .offset = .{ .container_field_value = field_i },
37292 };
37293
37294 const tag_overflow = if (has_tag_value) overflow: {
37295 const tag_val_ref: Zir.Inst.Ref = @enumFromInt(zir.extra[extra_index]);
37296 extra_index += 1;
37297 const tag_inst = try sema.resolveInst(tag_val_ref);
37298 last_tag_val = try sema.resolveConstDefinedValue(block, .{
37299 .base_node_inst = tracked_inst,
37300 .offset = .{ .container_field_name = field_i },
37301 }, tag_inst, .{ .simple = .enum_field_tag_value });
37302 if (!(try sema.intFitsInType(last_tag_val.?, int_tag_ty, null))) break :overflow true;
37303 last_tag_val = try pt.getCoerced(last_tag_val.?, int_tag_ty);
37304 if (wip_ty.nextField(ip, field_name, last_tag_val.?.toIntern())) |conflict| {
37305 assert(conflict.kind == .value); // AstGen validated names are unique
37306 const other_field_src: LazySrcLoc = .{
37307 .base_node_inst = tracked_inst,
37308 .offset = .{ .container_field_value = conflict.prev_field_idx },
37309 };
37310 const msg = msg: {
37311 const msg = try sema.errMsg(value_src, "enum tag value {f} already taken", .{last_tag_val.?.fmtValueSema(pt, sema)});
37312 errdefer msg.destroy(gpa);
37313 try sema.errNote(other_field_src, msg, "other occurrence here", .{});
37314 break :msg msg;
37315 };
37316 return sema.failWithOwnedErrorMsg(block, msg);
37317 }
37318 break :overflow false;
37319 } else if (any_values) overflow: {
37320 if (last_tag_val) |last_tag| {
37321 const result = try arith.incrementDefinedInt(sema, int_tag_ty, last_tag);
37322 last_tag_val = result.val;
37323 if (result.overflow) break :overflow true;
37324 } else {
37325 last_tag_val = try pt.intValue(int_tag_ty, 0);
37326 }
37327 if (wip_ty.nextField(ip, field_name, last_tag_val.?.toIntern())) |conflict| {
37328 assert(conflict.kind == .value); // AstGen validated names are unique
37329 const other_field_src: LazySrcLoc = .{
37330 .base_node_inst = tracked_inst,
37331 .offset = .{ .container_field_value = conflict.prev_field_idx },
37332 };
37333 const msg = msg: {
37334 const msg = try sema.errMsg(value_src, "enum tag value {f} already taken", .{last_tag_val.?.fmtValueSema(pt, sema)});
37335 errdefer msg.destroy(gpa);
37336 try sema.errNote(other_field_src, msg, "other occurrence here", .{});
37337 break :msg msg;
37338 };
37339 return sema.failWithOwnedErrorMsg(block, msg);
37340 }
37341 break :overflow false;
37342 } else overflow: {
37343 assert(wip_ty.nextField(ip, field_name, .none) == null);
37344 last_tag_val = try pt.intValue(.comptime_int, field_i);
37345 if (!try sema.intFitsInType(last_tag_val.?, int_tag_ty, null)) break :overflow true;
37346 last_tag_val = try pt.getCoerced(last_tag_val.?, int_tag_ty);
37347 break :overflow false;
37348 };
37349
37350 if (tag_overflow) {
37351 const msg = try sema.errMsg(value_src, "enumeration value '{f}' too large for type '{f}'", .{
37352 last_tag_val.?.fmtValueSema(pt, sema), int_tag_ty.fmt(pt),
37353 });
37354 return sema.failWithOwnedErrorMsg(block, msg);
37355 }
37356 }
37357 if (small.nonexhaustive and int_tag_ty.toIntern() != .comptime_int_type) {
37358 if (fields_len >= 1 and std.math.log2_int(u64, fields_len) == int_tag_ty.bitSize(zcu)) {
37359 return sema.fail(block, src, "non-exhaustive enum specifies every value", .{});
37360 }
37361 }
37362}
37363
3736433951pub const bitCastVal = @import("Sema/bitcast.zig").bitCast;
3736533952pub const bitCastSpliceVal = @import("Sema/bitcast.zig").bitCastSplice;
3736633953
......@@ -37369,6 +33956,10 @@ const ComptimeLoadResult = @import("Sema/comptime_ptr_access.zig").ComptimeLoadR
3736933956const storeComptimePtr = @import("Sema/comptime_ptr_access.zig").storeComptimePtr;
3737033957const ComptimeStoreResult = @import("Sema/comptime_ptr_access.zig").ComptimeStoreResult;
3737133958
33959pub const type_resolution = @import("Sema/type_resolution.zig");
33960pub const ensureLayoutResolved = type_resolution.ensureLayoutResolved;
33961pub const ensureStructDefaultsResolved = type_resolution.ensureStructDefaultsResolved;
33962
3737233963pub fn getBuiltinType(sema: *Sema, src: LazySrcLoc, decl: Zcu.BuiltinDecl) SemaError!Type {
3737333964 assert(decl.kind() == .type);
3737433965 try sema.ensureMemoizedStateResolved(src, decl.stage());
......@@ -37448,62 +34039,95 @@ pub fn resolveNavPtrModifiers(
3744834039 };
3744934040}
3745034041
37451pub fn analyzeMemoizedState(sema: *Sema, block: *Block, simple_src: LazySrcLoc, builtin_namespace: InternPool.NamespaceIndex, stage: InternPool.MemoizedStateStage) CompileError!bool {
37452 const pt = sema.pt;
37453 const zcu = pt.zcu;
37454 const comp = zcu.comp;
37455 const gpa = comp.gpa;
37456 const io = comp.io;
37457 const ip = &zcu.intern_pool;
34042pub fn analyzeMemoizedState(sema: *Sema, stage: InternPool.MemoizedStateStage) CompileError!bool {
34043 const pt = sema.pt;
34044 const zcu = pt.zcu;
34045 const comp = zcu.comp;
34046 const gpa = comp.gpa;
34047 const io = comp.io;
34048 const ip = &zcu.intern_pool;
34049
34050 // This `Block` acts kind of like it's evaluating a `comptime` declaration in the root source
34051 // file of the standard library. In particular, its namespace is the root std namespace.
34052 var block: Block = block: {
34053 // Get the main struct type of the root source file of `std`. No need for a reference entry
34054 // because `std` is always an analysis root.
34055 const std_file_index = zcu.module_roots.get(zcu.std_mod).?.unwrap().?;
34056 try pt.ensureFilePopulated(std_file_index);
34057 const std_type: Type = .fromInterned(zcu.fileRootType(std_file_index));
34058 break :block .{
34059 .parent = null,
34060 .sema = sema,
34061 .namespace = std_type.getNamespaceIndex(zcu),
34062 .instructions = .empty,
34063 .inlining = null,
34064 .comptime_reason = null,
34065 .src_base_inst = std_type.typeDeclInst(zcu).?,
34066 .type_name_ctx = .empty,
34067 };
34068 };
34069 defer block.instructions.deinit(gpa);
34070
34071 const std_builtin_ty: Type = ty: {
34072 const std_src = block.nodeOffset(.zero);
34073 const decl_name = try ip.getOrPutString(gpa, io, pt.tid, "builtin", .no_embedded_nulls);
34074 const nav = try sema.namespaceLookup(&block, std_src, block.namespace, decl_name) orelse {
34075 return sema.fail(&block, std_src, "'std' missing 'builtin'", .{});
34076 };
34077 const uncoerced_val = try sema.analyzeNavVal(&block, std_src, nav);
34078 const decl_src: LazySrcLoc = .{
34079 .base_node_inst = ip.getNav(nav).srcInst(ip),
34080 .offset = .nodeOffset(.zero),
34081 };
34082 break :ty try sema.analyzeAsType(&block, decl_src, .std_builtin_decl, uncoerced_val);
34083 };
3745834084
3745934085 var any_changed = false;
3746034086
3746134087 inline for (comptime std.enums.values(Zcu.BuiltinDecl)) |builtin_decl| {
3746234088 if (stage == comptime builtin_decl.stage()) {
37463 const parent_ns: Zcu.Namespace.Index, const parent_name: []const u8, const name: []const u8 = switch (comptime builtin_decl.access()) {
37464 .direct => |name| .{ builtin_namespace, "std.builtin", name },
34089 const parent_ns_ty: Type, const parent_name: []const u8, const name: []const u8 = switch (comptime builtin_decl.access()) {
34090 .direct => |name| .{ std_builtin_ty, "std.builtin", name },
3746534091 .nested => |nested| access: {
37466 const parent_ty: Type = .fromInterned(zcu.builtin_decl_values.get(nested[0]));
37467 const parent_ns = parent_ty.getNamespace(zcu).unwrap() orelse {
37468 return sema.fail(block, simple_src, "std.builtin.{s} is not a container type", .{@tagName(nested[0])});
37469 };
37470 break :access .{ parent_ns, "std.builtin." ++ @tagName(nested[0]), nested[1] };
34092 const parent_decl, const name = nested;
34093 const parent_ty: Type = .fromInterned(zcu.builtin_decl_values.get(parent_decl));
34094 break :access .{ parent_ty, "std.builtin." ++ @tagName(parent_decl), name };
3747134095 },
3747234096 };
3747334097
34098 const parent_ns = parent_ns_ty.getNamespace(zcu).unwrap() orelse {
34099 return sema.fail(&block, block.nodeOffset(.zero), "'{s}' is not a container type", .{parent_name});
34100 };
34101 const parent_ty_src = parent_ns_ty.srcLoc(zcu);
3747434102 const name_nts = try ip.getOrPutString(gpa, io, pt.tid, name, .no_embedded_nulls);
37475 const nav = try sema.namespaceLookup(block, simple_src, parent_ns, name_nts) orelse
37476 return sema.fail(block, simple_src, "{s} missing {s}", .{ parent_name, name });
34103 const nav = try sema.namespaceLookup(&block, parent_ty_src, parent_ns, name_nts) orelse {
34104 return sema.fail(&block, parent_ty_src, "'{s}' missing '{s}'", .{ parent_name, name });
34105 };
34106 const uncoerced_val = try sema.analyzeNavVal(&block, parent_ty_src, nav);
3747734107
37478 const src: LazySrcLoc = .{
34108 const decl_src: LazySrcLoc = .{
3747934109 .base_node_inst = ip.getNav(nav).srcInst(ip),
3748034110 .offset = .nodeOffset(.zero),
3748134111 };
3748234112
37483 const result = try sema.analyzeNavVal(block, src, nav);
37484
37485 const uncoerced_val = try sema.resolveConstDefinedValue(block, src, result, null);
37486 const maybe_lazy_val: Value = switch (builtin_decl.kind()) {
37487 .type => if (uncoerced_val.typeOf(zcu).zigTypeTag(zcu) != .type) {
37488 return sema.fail(block, src, "{s}.{s} is not a type", .{ parent_name, name });
37489 } else val: {
37490 try uncoerced_val.toType().resolveFully(pt);
37491 break :val uncoerced_val;
34113 const val: Value = switch (builtin_decl.kind()) {
34114 .type => val: {
34115 const ty = try sema.analyzeAsType(&block, decl_src, .std_builtin_decl, uncoerced_val);
34116 try sema.ensureLayoutResolved(ty, decl_src, .builtin_type);
34117 break :val ty.toValue();
3749234118 },
3749334119 .func => val: {
3749434120 const func_ty = try sema.getExpectedBuiltinFnType(builtin_decl);
37495 const coerced = try sema.coerce(block, func_ty, Air.internedToRef(uncoerced_val.toIntern()), src);
37496 break :val .fromInterned(coerced.toInterned().?);
34121 const coerced = try sema.coerce(&block, func_ty, uncoerced_val, decl_src);
34122 break :val try sema.resolveConstDefinedValue(&block, decl_src, coerced, .{ .simple = .std_builtin_decl });
3749734123 },
3749834124 .string => val: {
37499 const coerced = try sema.coerce(block, .slice_const_u8, Air.internedToRef(uncoerced_val.toIntern()), src);
37500 break :val .fromInterned(coerced.toInterned().?);
34125 const coerced = try sema.coerce(&block, .slice_const_u8, uncoerced_val, decl_src);
34126 break :val try sema.resolveConstDefinedValue(&block, decl_src, coerced, .{ .simple = .std_builtin_decl });
3750134127 },
3750234128 };
37503 const val = try sema.resolveLazyValue(maybe_lazy_val);
3750434129
37505 const prev = zcu.builtin_decl_values.get(builtin_decl);
37506 if (val.toIntern() != prev) {
34130 if (zcu.builtin_decl_values.get(builtin_decl) != val.toIntern()) {
3750734131 zcu.builtin_decl_values.set(builtin_decl, val.toIntern());
3750834132 any_changed = true;
3750934133 }
......@@ -37539,7 +34163,6 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ
3753934163 => try pt.funcType(.{
3754034164 .param_types = &.{ .generic_poison_type, .generic_poison_type },
3754134165 .return_type = .noreturn_type,
37542 .is_generic = true,
3754334166 }),
3754434167
3754534168 // `fn (anyerror) noreturn`
......@@ -37590,3 +34213,372 @@ fn getExpectedBuiltinFnType(sema: *Sema, decl: Zcu.BuiltinDecl) CompileError!Typ
3759034213 else => unreachable,
3759134214 };
3759234215}
34216
34217pub fn setTypeName(
34218 sema: *Sema,
34219 block: *Block,
34220 wip: *const InternPool.WipContainerType,
34221 name_strategy: Zir.Inst.NameStrategy,
34222 anon_prefix: []const u8,
34223 inst: Zir.Inst.Index,
34224) CompileError!void {
34225 const pt = sema.pt;
34226 const zcu = pt.zcu;
34227 const comp = zcu.comp;
34228 const gpa = comp.gpa;
34229 const io = comp.io;
34230 const ip = &zcu.intern_pool;
34231
34232 strat: switch (name_strategy) {
34233 .anon => {
34234 // It would be neat to have "struct:line:column" but this name has
34235 // to survive incremental updates, where it may have been shifted down
34236 // or up to a different line, but unchanged, and thus not unnecessarily
34237 // semantically analyzed.
34238 // TODO: that would be possible, by detecting line number changes and renaming
34239 // types appropriately. However, `@typeName` becomes a problem then. If we remove
34240 // that builtin from the language, we can consider this.
34241 wip.setName(ip, try ip.getOrPutStringFmt(
34242 gpa,
34243 io,
34244 pt.tid,
34245 "{f}__{s}_{d}",
34246 .{ block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(wip.index) },
34247 .no_embedded_nulls,
34248 ), .none);
34249 },
34250 .parent => wip.setName(ip, block.type_name_ctx, sema.owner.unwrap().nav_val.toOptional()),
34251 .func => {
34252 const fn_info = sema.code.getFnInfo(ip.funcZirBodyInst(sema.func_index).resolve(ip) orelse return error.AnalysisFail);
34253 const zir_tags = sema.code.instructions.items(.tag);
34254
34255 var aw: std.Io.Writer.Allocating = .init(gpa);
34256 defer aw.deinit();
34257 const w = &aw.writer;
34258 w.print("{f}(", .{block.type_name_ctx.fmt(ip)}) catch return error.OutOfMemory;
34259
34260 var arg_i: usize = 0;
34261 for (fn_info.param_body) |zir_inst| switch (zir_tags[@intFromEnum(zir_inst)]) {
34262 .param, .param_comptime, .param_anytype, .param_anytype_comptime => {
34263 const arg = sema.inst_map.get(zir_inst).?;
34264 // If this is being called in a generic function then analyzeCall will
34265 // have already resolved the args and this will work.
34266 // If not then this is a struct type being returned from a non-generic
34267 // function and the name doesn't matter since it will later
34268 // result in a compile error.
34269 const arg_val = sema.resolveValue(arg) orelse {
34270 continue :strat .anon;
34271 };
34272
34273 if (arg_i != 0) w.writeByte(',') catch return error.OutOfMemory;
34274
34275 // Limiting the depth here helps avoid type names getting too long, which
34276 // in turn helps to avoid unreasonably long symbol names for namespaced
34277 // symbols. Such names should ideally be human-readable, and additionally,
34278 // some tooling may not support very long symbol names.
34279 w.print("{f}", .{Value.fmtValueSemaFull(.{
34280 .val = arg_val,
34281 .pt = pt,
34282 .opt_sema = sema,
34283 .depth = 1,
34284 })}) catch return error.OutOfMemory;
34285
34286 arg_i += 1;
34287 continue;
34288 },
34289 else => continue,
34290 };
34291
34292 w.writeByte(')') catch return error.OutOfMemory;
34293 const name = try ip.getOrPutString(gpa, io, pt.tid, aw.written(), .no_embedded_nulls);
34294 wip.setName(ip, name, .none);
34295 },
34296 .dbg_var => {
34297 // TODO: this logic is questionable. We ideally should be traversing the `Block` rather than relying on the order of AstGen instructions.
34298 const ref = inst.toRef();
34299 const zir_tags = sema.code.instructions.items(.tag);
34300 const zir_data = sema.code.instructions.items(.data);
34301 const var_name = for (@intFromEnum(inst)..zir_tags.len) |i| switch (zir_tags[i]) {
34302 .dbg_var_ptr, .dbg_var_val => if (zir_data[i].str_op.operand == ref) {
34303 break zir_data[i].str_op.getStr(sema.code);
34304 },
34305 else => {},
34306 } else {
34307 continue :strat .anon;
34308 };
34309 const name = try ip.getOrPutStringFmt(gpa, io, pt.tid, "{f}.{s}", .{
34310 block.type_name_ctx.fmt(ip), var_name,
34311 }, .no_embedded_nulls);
34312 wip.setName(ip, name, .none);
34313 },
34314 }
34315}
34316
34317fn zirStructDecl(
34318 sema: *Sema,
34319 block: *Block,
34320 inst: Zir.Inst.Index,
34321) CompileError!Air.Inst.Ref {
34322 const pt = sema.pt;
34323 const zcu = pt.zcu;
34324 const comp = zcu.comp;
34325 const gpa = comp.gpa;
34326 const io = comp.io;
34327 const ip = &zcu.intern_pool;
34328
34329 const tracked_inst = try block.trackZir(inst);
34330
34331 const src: LazySrcLoc = .{
34332 .base_node_inst = tracked_inst,
34333 .offset = .nodeOffset(.zero),
34334 };
34335
34336 const struct_decl = sema.code.getStructDecl(inst);
34337
34338 const captures = try sema.getCaptures(block, src, struct_decl.captures, struct_decl.capture_names);
34339
34340 const ty: Type = switch (try ip.getDeclaredStructType(gpa, io, pt.tid, .{
34341 .zir_index = tracked_inst,
34342 .captures = captures,
34343 .fields_len = @intCast(struct_decl.field_names.len),
34344 .layout = struct_decl.layout,
34345 .any_comptime_fields = struct_decl.field_comptime_bits != null,
34346 .any_field_defaults = struct_decl.field_default_body_lens != null,
34347 .any_field_aligns = struct_decl.field_align_body_lens != null,
34348 .packed_backing_mode = if (struct_decl.backing_int_type_body != null) .explicit else .auto,
34349 })) {
34350 .existing => |ty| .fromInterned(ty),
34351 .wip => |wip| ty: {
34352 errdefer wip.cancel(ip, pt.tid);
34353 try sema.setTypeName(block, &wip, struct_decl.name_strategy, "struct", inst);
34354 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
34355 .parent = block.namespace.toOptional(),
34356 .owner_type = wip.index,
34357 .file_scope = block.getFileScopeIndex(zcu),
34358 .generation = zcu.generation,
34359 });
34360 errdefer pt.destroyNamespace(new_namespace_index);
34361 try pt.scanNamespace(new_namespace_index, struct_decl.decls);
34362 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
34363 break :ty .fromInterned(wip.finish(ip, new_namespace_index));
34364 },
34365 };
34366
34367 try sema.addTypeReferenceEntry(src, ty);
34368 try pt.ensureNamespaceUpToDate(ty.getNamespaceIndex(zcu));
34369
34370 return .fromType(ty);
34371}
34372fn zirUnionDecl(
34373 sema: *Sema,
34374 block: *Block,
34375 inst: Zir.Inst.Index,
34376) CompileError!Air.Inst.Ref {
34377 const pt = sema.pt;
34378 const zcu = pt.zcu;
34379 const comp = zcu.comp;
34380 const gpa = comp.gpa;
34381 const io = comp.io;
34382 const ip = &zcu.intern_pool;
34383
34384 const tracked_inst = try block.trackZir(inst);
34385
34386 const src: LazySrcLoc = .{
34387 .base_node_inst = tracked_inst,
34388 .offset = .nodeOffset(.zero),
34389 };
34390
34391 const union_decl = sema.code.getUnionDecl(inst);
34392
34393 const captures = try sema.getCaptures(block, src, union_decl.captures, union_decl.capture_names);
34394
34395 const ty: Type = switch (try ip.getDeclaredUnionType(gpa, io, pt.tid, .{
34396 .zir_index = tracked_inst,
34397 .captures = captures,
34398 .fields_len = @intCast(union_decl.field_names.len),
34399 .layout = union_decl.kind.layout(),
34400 .any_field_aligns = union_decl.field_align_body_lens != null,
34401 .tag_usage = switch (union_decl.kind) {
34402 .auto => if (block.wantSafeTypes()) .safety else .none,
34403
34404 .tagged_explicit,
34405 .tagged_enum,
34406 .tagged_enum_explicit,
34407 => .tagged,
34408
34409 .@"extern",
34410 .@"packed",
34411 .packed_explicit,
34412 => .none,
34413 },
34414 .enum_tag_mode = switch (union_decl.kind) {
34415 .tagged_explicit => .explicit,
34416 else => .auto,
34417 },
34418 .packed_backing_mode = switch (union_decl.kind) {
34419 .packed_explicit => .explicit,
34420 else => .auto,
34421 },
34422 })) {
34423 .existing => |ty| .fromInterned(ty),
34424 .wip => |wip| ty: {
34425 errdefer wip.cancel(ip, pt.tid);
34426 try sema.setTypeName(block, &wip, union_decl.name_strategy, "union", inst);
34427 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
34428 .parent = block.namespace.toOptional(),
34429 .owner_type = wip.index,
34430 .file_scope = block.getFileScopeIndex(zcu),
34431 .generation = zcu.generation,
34432 });
34433 errdefer pt.destroyNamespace(new_namespace_index);
34434 try pt.scanNamespace(new_namespace_index, union_decl.decls);
34435 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
34436 break :ty .fromInterned(wip.finish(ip, new_namespace_index));
34437 },
34438 };
34439
34440 try sema.addTypeReferenceEntry(src, ty);
34441 try pt.ensureNamespaceUpToDate(ty.getNamespaceIndex(zcu));
34442
34443 return .fromType(ty);
34444}
34445fn zirEnumDecl(
34446 sema: *Sema,
34447 block: *Block,
34448 inst: Zir.Inst.Index,
34449) CompileError!Air.Inst.Ref {
34450 const pt = sema.pt;
34451 const zcu = pt.zcu;
34452 const comp = zcu.comp;
34453 const gpa = comp.gpa;
34454 const io = comp.io;
34455 const ip = &zcu.intern_pool;
34456
34457 const tracked_inst = try block.trackZir(inst);
34458
34459 const src: LazySrcLoc = .{
34460 .base_node_inst = tracked_inst,
34461 .offset = .nodeOffset(.zero),
34462 };
34463
34464 const enum_decl = sema.code.getEnumDecl(inst);
34465
34466 const captures = try sema.getCaptures(block, src, enum_decl.captures, enum_decl.capture_names);
34467
34468 const ty: Type = switch (try ip.getDeclaredEnumType(gpa, io, pt.tid, .{
34469 .zir_index = tracked_inst,
34470 .captures = captures,
34471 .fields_len = @intCast(enum_decl.field_names.len),
34472 .nonexhaustive = enum_decl.nonexhaustive,
34473 .int_tag_mode = if (enum_decl.tag_type_body != null) .explicit else .auto,
34474 })) {
34475 .existing => |ty| .fromInterned(ty),
34476 .wip => |wip| ty: {
34477 errdefer wip.cancel(ip, pt.tid);
34478 try sema.setTypeName(block, &wip, enum_decl.name_strategy, "enum", inst);
34479 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
34480 .parent = block.namespace.toOptional(),
34481 .owner_type = wip.index,
34482 .file_scope = block.getFileScopeIndex(zcu),
34483 .generation = zcu.generation,
34484 });
34485 errdefer pt.destroyNamespace(new_namespace_index);
34486 try pt.scanNamespace(new_namespace_index, enum_decl.decls);
34487 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
34488 break :ty .fromInterned(wip.finish(ip, new_namespace_index));
34489 },
34490 };
34491
34492 try sema.addTypeReferenceEntry(src, ty);
34493 try pt.ensureNamespaceUpToDate(ty.getNamespaceIndex(zcu));
34494
34495 return .fromType(ty);
34496}
34497fn zirOpaqueDecl(
34498 sema: *Sema,
34499 block: *Block,
34500 inst: Zir.Inst.Index,
34501) CompileError!Air.Inst.Ref {
34502 const pt = sema.pt;
34503 const zcu = pt.zcu;
34504 const comp = zcu.comp;
34505 const gpa = comp.gpa;
34506 const io = comp.io;
34507 const ip = &zcu.intern_pool;
34508
34509 const tracked_inst = try block.trackZir(inst);
34510
34511 const src: LazySrcLoc = .{
34512 .base_node_inst = tracked_inst,
34513 .offset = .nodeOffset(.zero),
34514 };
34515
34516 const opaque_decl = sema.code.getOpaqueDecl(inst);
34517
34518 const captures = try sema.getCaptures(block, src, opaque_decl.captures, opaque_decl.capture_names);
34519
34520 const ty: Type = switch (try ip.getDeclaredOpaqueType(gpa, io, pt.tid, .{
34521 .zir_index = tracked_inst,
34522 .captures = captures,
34523 })) {
34524 .existing => |ty| .fromInterned(ty),
34525 .wip => |wip| ty: {
34526 errdefer wip.cancel(ip, pt.tid);
34527 try sema.setTypeName(block, &wip, opaque_decl.name_strategy, "opaque", inst);
34528 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
34529 .parent = block.namespace.toOptional(),
34530 .owner_type = wip.index,
34531 .file_scope = block.getFileScopeIndex(zcu),
34532 .generation = zcu.generation,
34533 });
34534 errdefer pt.destroyNamespace(new_namespace_index);
34535 try pt.scanNamespace(new_namespace_index, opaque_decl.decls);
34536 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
34537 break :ty .fromInterned(wip.finish(ip, new_namespace_index));
34538 },
34539 };
34540
34541 try sema.addTypeReferenceEntry(src, ty);
34542 try pt.ensureNamespaceUpToDate(ty.getNamespaceIndex(zcu));
34543
34544 return .fromType(ty);
34545}
34546
34547/// Registers an error indicating a dependency loop: we have introduced a dependency on `want` (with
34548/// reason `want_reason`) but have learnt that `want` is already in `zcu.analysis_in_progress`.
34549pub fn failWithDependencyLoop(
34550 sema: *Sema,
34551 want: AnalUnit,
34552 want_reason: *const Zcu.DependencyReason,
34553) SemaError {
34554 const pt = sema.pt;
34555 const zcu = pt.zcu;
34556 const gpa = zcu.comp.gpa;
34557
34558 const in_progress_len = zcu.analysis_in_progress.count();
34559 var index = zcu.analysis_in_progress.getIndex(want).? + 1;
34560
34561 try zcu.dependency_loops.ensureUnusedCapacity(gpa, 1);
34562 try zcu.dependency_loop_nodes.ensureUnusedCapacity(gpa, in_progress_len - index + 1);
34563
34564 zcu.dependency_loops.putAssumeCapacityNoClobber(want, {});
34565
34566 while (index <= in_progress_len) : (index += 1) {
34567 const parent_unit = zcu.analysis_in_progress.keys()[index - 1];
34568 const unit, const reason = if (index == in_progress_len) .{
34569 want,
34570 want_reason,
34571 } else .{
34572 zcu.analysis_in_progress.keys()[index],
34573 zcu.analysis_in_progress.values()[index],
34574 };
34575
34576 zcu.dependency_loop_nodes.putAssumeCapacityNoClobber(parent_unit, .{
34577 .unit = unit,
34578 .reason = reason.?.*,
34579 });
34580 }
34581
34582 // A dependency loop error will be reported. Mark us all as transitive failures.
34583 return error.AnalysisFail;
34584}
src/Sema/LowerZon.zig+61-71
......@@ -129,84 +129,73 @@ fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!Inter
129129 for (0..init.names.len) |i| {
130130 elems[i] = try self.lowerExprAnonResTy(init.vals.at(@intCast(i)));
131131 }
132 const struct_ty = switch (try ip.getStructType(
133 gpa,
134 io,
135 pt.tid,
136 .{
137 .layout = .auto,
138 .fields_len = @intCast(init.names.len),
139 .known_non_opv = false,
140 .requires_comptime = .no,
141 .any_comptime_fields = true,
142 .any_default_inits = true,
143 .inits_resolved = true,
144 .any_aligned_fields = false,
145 .key = .{ .reified = .{
146 .zir_index = self.base_node_inst,
147 .type_hash = hash: {
148 var hasher: std.hash.Wyhash = .init(0);
149 hasher.update(std.mem.asBytes(&node));
150 hasher.update(std.mem.sliceAsBytes(elems));
151 hasher.update(std.mem.sliceAsBytes(init.names));
152 break :hash hasher.final();
153 },
154 } },
132 const struct_ty: Type = switch (try ip.getReifiedStructType(gpa, io, pt.tid, .{
133 .zir_index = self.base_node_inst,
134 .type_hash = hash: {
135 var hasher: std.hash.Wyhash = .init(0);
136 hasher.update(std.mem.asBytes(&node));
137 hasher.update(std.mem.sliceAsBytes(elems));
138 hasher.update(std.mem.sliceAsBytes(init.names));
139 break :hash hasher.final();
155140 },
156 false,
157 )) {
141 .fields_len = @intCast(init.names.len),
142 .layout = .auto,
143 .any_comptime_fields = true,
144 .any_field_defaults = true,
145 .any_field_aligns = false,
146 .packed_backing_int_type = .none,
147 })) {
148 .existing => |ty| .fromInterned(ty),
158149 .wip => |wip| ty: {
159150 errdefer wip.cancel(ip, pt.tid);
160 const type_name = try self.sema.createTypeName(
161 self.block,
162 .anon,
163 "struct",
164 self.base_node_inst.resolve(ip),
165 wip.index,
166 );
167 wip.setName(ip, type_name.name, type_name.nav);
168
169 const struct_type = ip.loadStructType(wip.index);
170
171 for (init.names, 0..) |name, field_idx| {
172 const name_interned = try ip.getOrPutString(
151 const block = self.block;
152 const zcu = pt.zcu;
153 try self.sema.setTypeName(block, &wip, .anon, "struct", self.base_node_inst.resolve(ip).?);
154
155 // Reified structs have field information populated immediately.
156 @memcpy(wip.field_values.get(ip), elems);
157 if (init.names.len > 0) {
158 // All fields are comptime, but unused bits remain zeroed.
159 const unused_bits = switch (init.names.len % 32) {
160 0 => 0,
161 else => |n| 32 - n,
162 };
163 const comptime_bits = wip.field_is_comptime_bits.getAll(ip);
164 @memset(comptime_bits[0 .. comptime_bits.len - 1], std.math.maxInt(u32));
165 comptime_bits[comptime_bits.len - 1] = @as(u32, std.math.maxInt(u32)) >> @intCast(unused_bits);
166 }
167 for (
168 init.names,
169 wip.field_names.get(ip),
170 wip.field_types.get(ip),
171 wip.field_values.get(ip),
172 ) |zoir_name, *field_name, *field_ty, field_val| {
173 field_name.* = try ip.getOrPutString(
173174 gpa,
174175 io,
175176 pt.tid,
176 name.get(self.file.zoir.?),
177 zoir_name.get(self.file.zoir.?),
177178 .no_embedded_nulls,
178179 );
179 assert(struct_type.addFieldName(ip, name_interned) == null);
180 struct_type.setFieldComptime(ip, field_idx);
181 }
182
183 @memcpy(struct_type.field_inits.get(ip), elems);
184 const types = struct_type.field_types.get(ip);
185 for (0..init.names.len) |i| {
186 types[i] = Value.fromInterned(elems[i]).typeOf(pt.zcu).toIntern();
180 field_ty.* = ip.typeOf(field_val);
187181 }
188182
189183 const new_namespace_index = try pt.createNamespace(.{
190 .parent = self.block.namespace.toOptional(),
184 .parent = block.namespace.toOptional(),
191185 .owner_type = wip.index,
192 .file_scope = self.block.getFileScopeIndex(pt.zcu),
193 .generation = pt.zcu.generation,
186 .file_scope = block.getFileScopeIndex(zcu),
187 .generation = zcu.generation,
194188 });
195 try pt.zcu.comp.queueJob(.{ .resolve_type_fully = wip.index });
196 codegen_type: {
197 if (pt.zcu.comp.config.use_llvm) break :codegen_type;
198 if (self.block.ownerModule().strip) break :codegen_type;
199 pt.zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
200 try pt.zcu.comp.queueJob(.{ .link_type = wip.index });
201 }
202 break :ty wip.finish(ip, new_namespace_index);
189 errdefer pt.destroyNamespace(new_namespace_index);
190 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
191 break :ty .fromInterned(wip.finish(ip, new_namespace_index));
203192 },
204 .existing => |ty| ty,
205193 };
206 try self.sema.declareDependency(.{ .interned = struct_ty });
207194 try self.sema.addTypeReferenceEntry(self.nodeSrc(node), struct_ty);
195 // No need for `ensureNamespaceUpToDate` because this type's namespace is always empty.
196 try self.sema.ensureLayoutResolved(struct_ty, self.nodeSrc(node), .init);
208197
209 return (try pt.aggregateValue(.fromInterned(struct_ty), elems)).toIntern();
198 return (try pt.aggregateValue(struct_ty, elems)).toIntern();
210199 },
211200 }
212201}
......@@ -299,7 +288,7 @@ fn checkTypeInner(
299288 } else {
300289 const gop = try visited.getOrPut(sema.arena, ty.toIntern());
301290 if (gop.found_existing) return;
302 try ty.resolveFields(pt);
291 try sema.ensureLayoutResolved(ty, self.import_loc, .init);
303292 const struct_info = zcu.typeToStruct(ty).?;
304293 for (struct_info.field_types.get(ip)) |field_type| {
305294 try self.checkTypeInner(.fromInterned(field_type), null, visited);
......@@ -308,7 +297,7 @@ fn checkTypeInner(
308297 .@"union" => {
309298 const gop = try visited.getOrPut(sema.arena, ty.toIntern());
310299 if (gop.found_existing) return;
311 try ty.resolveFields(pt);
300 try sema.ensureLayoutResolved(ty, self.import_loc, .init);
312301 const union_info = zcu.typeToUnion(ty).?;
313302 for (union_info.field_types.get(ip)) |field_type| {
314303 if (field_type != .void_type) {
......@@ -645,6 +634,7 @@ fn lowerEnum(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.I
645634 const gpa = comp.gpa;
646635 const io = comp.io;
647636 const ip = &pt.zcu.intern_pool;
637 try self.sema.ensureLayoutResolved(res_ty, self.import_loc, .init);
648638 switch (node.get(self.file.zoir.?)) {
649639 .enum_literal => |field_name| {
650640 const field_name_interned = try ip.getOrPutString(
......@@ -767,8 +757,8 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
767757 const io = comp.io;
768758 const ip = &pt.zcu.intern_pool;
769759
770 try res_ty.resolveFields(self.sema.pt);
771 try res_ty.resolveStructFieldInits(self.sema.pt);
760 try self.sema.ensureLayoutResolved(res_ty, self.import_loc, .init);
761 try self.sema.ensureStructDefaultsResolved(res_ty, self.import_loc);
772762 const struct_info = self.sema.pt.zcu.typeToStruct(res_ty).?;
773763
774764 const fields: @FieldType(Zoir.Node, "struct_literal") = switch (node.get(self.file.zoir.?)) {
......@@ -779,7 +769,7 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
779769
780770 const field_values = try self.sema.arena.alloc(InternPool.Index, struct_info.field_names.len);
781771
782 const field_defaults = struct_info.field_inits.get(ip);
772 const field_defaults = struct_info.field_defaults.get(ip);
783773 if (field_defaults.len > 0) {
784774 @memcpy(field_values, field_defaults);
785775 } else {
......@@ -803,7 +793,7 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
803793 const field_type: Type = .fromInterned(struct_info.field_types.get(ip)[name_index]);
804794 field_values[name_index] = try self.lowerExprKnownResTy(field_node, field_type);
805795
806 if (struct_info.comptime_bits.getBit(ip, name_index)) {
796 if (struct_info.field_is_comptime_bits.get(ip, name_index)) {
807797 const val = ip.indexToKey(field_values[name_index]);
808798 const default = ip.indexToKey(field_defaults[name_index]);
809799 if (!val.eql(default, ip)) {
......@@ -918,9 +908,9 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
918908 const gpa = comp.gpa;
919909 const io = comp.io;
920910 const ip = &pt.zcu.intern_pool;
921 try res_ty.resolveFields(self.sema.pt);
922 const union_info = self.sema.pt.zcu.typeToUnion(res_ty).?;
923 const enum_tag_info = union_info.loadTagType(ip);
911 try self.sema.ensureLayoutResolved(res_ty, self.import_loc, .init);
912 const union_info = pt.zcu.typeToUnion(res_ty).?;
913 const enum_tag_info = ip.loadEnumType(union_info.enum_tag_type);
924914
925915 const field_name, const maybe_field_node = switch (node.get(self.file.zoir.?)) {
926916 .enum_literal => |name| b: {
......@@ -956,7 +946,7 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
956946 const name_index = enum_tag_info.nameIndex(ip, field_name) orelse {
957947 return error.WrongType;
958948 };
959 const tag = try self.sema.pt.enumValueFieldIndex(.fromInterned(union_info.enum_tag_ty), name_index);
949 const tag = try self.sema.pt.enumValueFieldIndex(.fromInterned(union_info.enum_tag_type), name_index);
960950 const field_type: Type = .fromInterned(union_info.field_types.get(ip)[name_index]);
961951 const val = if (maybe_field_node) |field_node| b: {
962952 if (field_type.toIntern() == .void_type) {
src/Sema/arith.zig+23-19
......@@ -20,6 +20,9 @@ pub fn incrementDefinedInt(
2020 const zcu = pt.zcu;
2121 assert(prev_val.typeOf(zcu).toIntern() == ty.toIntern());
2222 assert(!prev_val.isUndef(zcu));
23 if (ty.intInfo(zcu).bits == 0) {
24 return .{ .overflow = true, .val = try comptimeIntAdd(sema, prev_val, .one_comptime_int) };
25 }
2326 const res = try intAdd(sema, prev_val, try pt.intValue(ty, 1), ty);
2427 return .{ .overflow = res.overflow, .val = res.val };
2528}
......@@ -1053,7 +1056,7 @@ fn shlScalar(
10531056 if (rhs_val.isUndef(zcu)) return rhs_val;
10541057 },
10551058 }
1056 switch (try rhs_val.orderAgainstZeroSema(pt)) {
1059 switch (Value.order(rhs_val, .zero_comptime_int, zcu)) {
10571060 .gt => {},
10581061 .eq => return lhs_val,
10591062 .lt => return sema.failWithNegativeShiftAmount(block, rhs_src, rhs_val, vec_idx),
......@@ -1090,7 +1093,7 @@ fn shlWithOverflowScalar(
10901093 if (lhs_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, lhs_src, vec_idx);
10911094 if (rhs_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, rhs_src, vec_idx);
10921095
1093 switch (try rhs_val.orderAgainstZeroSema(pt)) {
1096 switch (Value.order(rhs_val, .zero_comptime_int, zcu)) {
10941097 .gt => {},
10951098 .eq => return .{ .overflow_bit = .zero_u1, .wrapped_result = lhs_val },
10961099 .lt => return sema.failWithNegativeShiftAmount(block, rhs_src, rhs_val, vec_idx),
......@@ -1169,7 +1172,7 @@ fn shrScalar(
11691172 if (lhs_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, lhs_src, vec_idx);
11701173 if (rhs_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, rhs_src, vec_idx);
11711174
1172 switch (try rhs_val.orderAgainstZeroSema(pt)) {
1175 switch (Value.order(rhs_val, .zero_comptime_int, zcu)) {
11731176 .gt => {},
11741177 .eq => return lhs_val,
11751178 .lt => return sema.failWithNegativeShiftAmount(block, rhs_src, rhs_val, vec_idx),
......@@ -1430,8 +1433,8 @@ fn intAddWithOverflowInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value
14301433 const info = ty.intInfo(zcu);
14311434 var lhs_space: Value.BigIntSpace = undefined;
14321435 var rhs_space: Value.BigIntSpace = undefined;
1433 const lhs_bigint = try lhs.toBigIntSema(&lhs_space, pt);
1434 const rhs_bigint = try rhs.toBigIntSema(&rhs_space, pt);
1436 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);
1437 const rhs_bigint = rhs.toBigInt(&rhs_space, zcu);
14351438 const limbs = try sema.arena.alloc(
14361439 std.math.big.Limb,
14371440 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -1512,8 +1515,8 @@ fn intSubWithOverflowInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value
15121515 const info = ty.intInfo(zcu);
15131516 var lhs_space: Value.BigIntSpace = undefined;
15141517 var rhs_space: Value.BigIntSpace = undefined;
1515 const lhs_bigint = try lhs.toBigIntSema(&lhs_space, pt);
1516 const rhs_bigint = try rhs.toBigIntSema(&rhs_space, pt);
1518 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);
1519 const rhs_bigint = rhs.toBigInt(&rhs_space, zcu);
15171520 const limbs = try sema.arena.alloc(
15181521 std.math.big.Limb,
15191522 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -1597,8 +1600,8 @@ fn intMulWithOverflowInner(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value
15971600 const info = ty.intInfo(zcu);
15981601 var lhs_space: Value.BigIntSpace = undefined;
15991602 var rhs_space: Value.BigIntSpace = undefined;
1600 const lhs_bigint = try lhs.toBigIntSema(&lhs_space, pt);
1601 const rhs_bigint = try rhs.toBigIntSema(&rhs_space, pt);
1603 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);
1604 const rhs_bigint = rhs.toBigInt(&rhs_space, zcu);
16021605 const limbs = try sema.arena.alloc(
16031606 std.math.big.Limb,
16041607 lhs_bigint.limbs.len + rhs_bigint.limbs.len,
......@@ -1840,7 +1843,7 @@ fn intShl(
18401843 var lhs_space: Value.BigIntSpace = undefined;
18411844 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);
18421845
1843 const shift_amt: usize = @intCast(try rhs.toUnsignedIntSema(pt));
1846 const shift_amt: usize = @intCast(rhs.toUnsignedInt(zcu));
18441847 if (shift_amt >= info.bits) {
18451848 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs, rhs_src, vec_idx);
18461849 }
......@@ -1862,7 +1865,7 @@ fn intShlSat(
18621865 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);
18631866
18641867 const shift_amt: usize = amt: {
1865 if (try rhs.getUnsignedIntSema(pt)) |shift_amt_u64| {
1868 if (rhs.getUnsignedInt(zcu)) |shift_amt_u64| {
18661869 if (std.math.cast(usize, shift_amt_u64)) |shift_amt| break :amt shift_amt;
18671870 }
18681871 // We only support ints with up to 2^16 - 1 bits, so this
......@@ -1895,9 +1898,9 @@ fn intShlWithOverflow(
18951898 const info = lhs_ty.intInfo(zcu);
18961899
18971900 var lhs_space: Value.BigIntSpace = undefined;
1898 const lhs_bigint = try lhs.toBigIntSema(&lhs_space, pt);
1901 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);
18991902
1900 const shift_amt: usize = @intCast(try rhs.toUnsignedIntSema(pt));
1903 const shift_amt: usize = @intCast(rhs.toUnsignedInt(zcu));
19011904 if (shift_amt >= info.bits) {
19021905 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs, rhs_src, vec_idx);
19031906 }
......@@ -1924,9 +1927,10 @@ fn comptimeIntShl(
19241927 vec_idx: ?usize,
19251928) !Value {
19261929 const pt = sema.pt;
1930 const zcu = pt.zcu;
19271931 var lhs_space: Value.BigIntSpace = undefined;
1928 const lhs_bigint = try lhs.toBigIntSema(&lhs_space, pt);
1929 if (try rhs.getUnsignedIntSema(pt)) |shift_amt_u64| {
1932 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);
1933 if (rhs.getUnsignedInt(zcu)) |shift_amt_u64| {
19301934 if (std.math.cast(usize, shift_amt_u64)) |shift_amt| {
19311935 const result_bigint = try intShlInner(sema, lhs_bigint, shift_amt);
19321936 return pt.intValue_big(.comptime_int, result_bigint.toConst());
......@@ -1963,15 +1967,15 @@ fn intShr(
19631967 const lhs_bigint = lhs.toBigInt(&lhs_space, zcu);
19641968
19651969 const shift_amt: usize = if (rhs_ty.toIntern() == .comptime_int_type) amt: {
1966 if (try rhs.getUnsignedIntSema(pt)) |shift_amt_u64| {
1970 if (rhs.getUnsignedInt(zcu)) |shift_amt_u64| {
19671971 if (std.math.cast(usize, shift_amt_u64)) |shift_amt| break :amt shift_amt;
19681972 }
1969 if (try rhs.compareAllWithZeroSema(.lt, pt)) {
1973 if (rhs.compareAllWithZero(.lt, zcu)) {
19701974 return sema.failWithNegativeShiftAmount(block, rhs_src, rhs, vec_idx);
19711975 } else {
19721976 return sema.failWithUnsupportedComptimeShiftAmount(block, rhs_src, vec_idx);
19731977 }
1974 } else @intCast(try rhs.toUnsignedIntSema(pt));
1978 } else @intCast(rhs.toUnsignedInt(zcu));
19751979
19761980 if (lhs_ty.toIntern() != .comptime_int_type and shift_amt >= lhs_ty.intInfo(zcu).bits) {
19771981 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs, rhs_src, vec_idx);
......@@ -2006,7 +2010,7 @@ fn intBitReverse(sema: *Sema, val: Value, ty: Type) !Value {
20062010 const info = ty.intInfo(zcu);
20072011
20082012 var val_space: Value.BigIntSpace = undefined;
2009 const val_bigint = try val.toBigIntSema(&val_space, pt);
2013 const val_bigint = val.toBigInt(&val_space, zcu);
20102014
20112015 const limbs = try sema.arena.alloc(
20122016 std.math.big.Limb,
src/Sema/bitcast.zig+94-90
......@@ -79,8 +79,8 @@ fn bitCastInner(
7979
8080 const val_ty = val.typeOf(zcu);
8181
82 try val_ty.resolveLayout(pt);
83 try dest_ty.resolveLayout(pt);
82 val_ty.assertHasLayout(zcu);
83 dest_ty.assertHasLayout(zcu);
8484
8585 assert(val_ty.hasWellDefinedLayout(zcu));
8686
......@@ -138,8 +138,8 @@ fn bitCastSpliceInner(
138138 const val_ty = val.typeOf(zcu);
139139 const splice_val_ty = splice_val.typeOf(zcu);
140140
141 try val_ty.resolveLayout(pt);
142 try splice_val_ty.resolveLayout(pt);
141 val_ty.assertHasLayout(zcu);
142 splice_val_ty.assertHasLayout(zcu);
143143
144144 const splice_bits = splice_val_ty.bitSize(zcu);
145145
......@@ -267,12 +267,13 @@ const UnpackValueBits = struct {
267267 .int,
268268 .enum_tag,
269269 .simple_value,
270 .empty_enum_value,
271270 .float,
272271 .ptr,
273272 .opt,
274273 => try unpack.primitive(val),
275274
275 .bitpack => |bitpack| try unpack.primitive(.fromInterned(bitpack.backing_int_val)),
276
276277 .aggregate => switch (ty.zigTypeTag(zcu)) {
277278 .vector => {
278279 const len: usize = @intCast(ty.arrayLen(zcu));
......@@ -443,7 +444,7 @@ const UnpackValueBits = struct {
443444 // This @intCast is okay because no primitive can exceed the size of a u16.
444445 const int_ty = try unpack.pt.intType(.unsigned, @intCast(bit_count));
445446 const buf = try unpack.arena.alloc(u8, @intCast((val_bits + 7) / 8));
446 try val.writeToPackedMemory(ty, unpack.pt, buf, 0);
447 try val.writeToPackedMemory(unpack.pt, buf, 0);
447448 const sub_val = try Value.readFromPackedMemory(int_ty, unpack.pt, buf, @intCast(bit_offset), unpack.arena);
448449 try unpack.primitive(sub_val);
449450 },
......@@ -451,7 +452,6 @@ const UnpackValueBits = struct {
451452 // The only values here with runtime bits are `true` and `false.
452453 // These are both 1 bit, so will never need truncating.
453454 .simple_value => unreachable,
454 .empty_enum_value => unreachable, // zero-bit
455455 else => unreachable, // zero-bit or not primitives
456456 }
457457 }
......@@ -565,102 +565,103 @@ const PackValueBits = struct {
565565 return pt.aggregateValue(ty, elems);
566566 },
567567 .@"packed" => {
568 // All fields are in order with no padding.
569 // This is identical between LE and BE targets.
570 const elems = try arena.alloc(InternPool.Index, ty.structFieldCount(zcu));
571 for (elems, 0..) |*elem, i| {
572 const field_ty = ty.fieldType(i, zcu);
573 elem.* = (try pack.get(field_ty)).toIntern();
574 }
575 return pt.aggregateValue(ty, elems);
568 const backing_int_val = try pack.primitive(ty.bitpackBackingInt(zcu));
569 return pt.bitpackValue(ty, backing_int_val);
576570 },
577571 },
578 .@"union" => {
579 // We will attempt to read as the backing representation. If this emits
580 // `error.ReinterpretDeclRef`, we will try each union field, preferring larger ones.
581 // We will also attempt smaller fields when we get `undefined`, as if some bits are
582 // defined we want to include them.
583 // TODO: this is very very bad. We need a more sophisticated union representation.
584
585 const prev_unpacked = pack.unpacked;
586 const prev_bit_offset = pack.bit_offset;
587
588 const backing_ty = try ty.unionBackingType(pt);
589
590 backing: {
591 const backing_val = pack.get(backing_ty) catch |err| switch (err) {
592 error.ReinterpretDeclRef => {
572 .@"union" => switch (ty.containerLayout(zcu)) {
573 .auto => unreachable, // ill-defined layout
574 .@"extern" => {
575 // We will attempt to read as the backing representation. If this emits
576 // `error.ReinterpretDeclRef`, we will try each union field, preferring larger ones.
577 // We will also attempt smaller fields when we get `undefined`, as if some bits are
578 // defined we want to include them.
579 // TODO: this is very very bad. We need a more sophisticated union representation.
580
581 const prev_unpacked = pack.unpacked;
582 const prev_bit_offset = pack.bit_offset;
583
584 const backing_ty = try ty.externUnionBackingType(pt);
585
586 backing: {
587 const backing_val = pack.get(backing_ty) catch |err| switch (err) {
588 error.ReinterpretDeclRef => {
589 pack.unpacked = prev_unpacked;
590 pack.bit_offset = prev_bit_offset;
591 break :backing;
592 },
593 else => |e| return e,
594 };
595 if (backing_val.isUndef(zcu)) {
593596 pack.unpacked = prev_unpacked;
594597 pack.bit_offset = prev_bit_offset;
595598 break :backing;
596 },
597 else => |e| return e,
598 };
599 if (backing_val.isUndef(zcu)) {
600 pack.unpacked = prev_unpacked;
601 pack.bit_offset = prev_bit_offset;
602 break :backing;
599 }
600 return Value.fromInterned(try pt.internUnion(.{
601 .ty = ty.toIntern(),
602 .tag = .none,
603 .val = backing_val.toIntern(),
604 }));
603605 }
604 return Value.fromInterned(try pt.internUnion(.{
605 .ty = ty.toIntern(),
606 .tag = .none,
607 .val = backing_val.toIntern(),
608 }));
609 }
610606
611 const field_order = try pack.arena.alloc(u32, ty.unionTagTypeHypothetical(zcu).enumFieldCount(zcu));
612 for (field_order, 0..) |*f, i| f.* = @intCast(i);
613 // Sort `field_order` to put the fields with the largest bit sizes first.
614 const SizeSortCtx = struct {
615 zcu: *Zcu,
616 field_types: []const InternPool.Index,
617 fn lessThan(ctx: @This(), a_idx: u32, b_idx: u32) bool {
618 const a_ty = Type.fromInterned(ctx.field_types[a_idx]);
619 const b_ty = Type.fromInterned(ctx.field_types[b_idx]);
620 return a_ty.bitSize(ctx.zcu) > b_ty.bitSize(ctx.zcu);
621 }
622 };
623 std.mem.sortUnstable(u32, field_order, SizeSortCtx{
624 .zcu = zcu,
625 .field_types = zcu.typeToUnion(ty).?.field_types.get(ip),
626 }, SizeSortCtx.lessThan);
627
628 const padding_after = endian == .little or ty.containerLayout(zcu) == .@"packed";
629
630 for (field_order) |field_idx| {
631 const field_ty = Type.fromInterned(zcu.typeToUnion(ty).?.field_types.get(ip)[field_idx]);
632 const pad_bits = ty.bitSize(zcu) - field_ty.bitSize(zcu);
633 if (!padding_after) try pack.padding(pad_bits);
634 const field_val = pack.get(field_ty) catch |err| switch (err) {
635 error.ReinterpretDeclRef => {
607 const field_order = try pack.arena.alloc(u32, ty.unionTagTypeHypothetical(zcu).enumFieldCount(zcu));
608 for (field_order, 0..) |*f, i| f.* = @intCast(i);
609 // Sort `field_order` to put the fields with the largest bit sizes first.
610 const SizeSortCtx = struct {
611 zcu: *Zcu,
612 field_types: []const InternPool.Index,
613 fn lessThan(ctx: @This(), a_idx: u32, b_idx: u32) bool {
614 const a_ty = Type.fromInterned(ctx.field_types[a_idx]);
615 const b_ty = Type.fromInterned(ctx.field_types[b_idx]);
616 return a_ty.bitSize(ctx.zcu) > b_ty.bitSize(ctx.zcu);
617 }
618 };
619 std.mem.sortUnstable(u32, field_order, SizeSortCtx{
620 .zcu = zcu,
621 .field_types = zcu.typeToUnion(ty).?.field_types.get(ip),
622 }, SizeSortCtx.lessThan);
623
624 const padding_after = endian == .little or ty.containerLayout(zcu) == .@"packed";
625
626 for (field_order) |field_idx| {
627 const field_ty = Type.fromInterned(zcu.typeToUnion(ty).?.field_types.get(ip)[field_idx]);
628 const pad_bits = ty.bitSize(zcu) - field_ty.bitSize(zcu);
629 if (!padding_after) try pack.padding(pad_bits);
630 const field_val = pack.get(field_ty) catch |err| switch (err) {
631 error.ReinterpretDeclRef => {
632 pack.unpacked = prev_unpacked;
633 pack.bit_offset = prev_bit_offset;
634 continue;
635 },
636 else => |e| return e,
637 };
638 if (padding_after) try pack.padding(pad_bits);
639 if (field_val.isUndef(zcu)) {
636640 pack.unpacked = prev_unpacked;
637641 pack.bit_offset = prev_bit_offset;
638642 continue;
639 },
640 else => |e| return e,
641 };
642 if (padding_after) try pack.padding(pad_bits);
643 if (field_val.isUndef(zcu)) {
644 pack.unpacked = prev_unpacked;
645 pack.bit_offset = prev_bit_offset;
646 continue;
643 }
644 const tag_val = try pt.enumValueFieldIndex(ty.unionTagTypeHypothetical(zcu), field_idx);
645 return Value.fromInterned(try pt.internUnion(.{
646 .ty = ty.toIntern(),
647 .tag = tag_val.toIntern(),
648 .val = field_val.toIntern(),
649 }));
647650 }
648 const tag_val = try pt.enumValueFieldIndex(ty.unionTagTypeHypothetical(zcu), field_idx);
651
652 // No field could represent the value. Just do whatever happens when we try to read
653 // the backing type - either `undefined` or `error.ReinterpretDeclRef`.
654 const backing_val = try pack.get(backing_ty);
649655 return Value.fromInterned(try pt.internUnion(.{
650656 .ty = ty.toIntern(),
651 .tag = tag_val.toIntern(),
652 .val = field_val.toIntern(),
657 .tag = .none,
658 .val = backing_val.toIntern(),
653659 }));
654 }
655
656 // No field could represent the value. Just do whatever happens when we try to read
657 // the backing type - either `undefined` or `error.ReinterpretDeclRef`.
658 const backing_val = try pack.get(backing_ty);
659 return Value.fromInterned(try pt.internUnion(.{
660 .ty = ty.toIntern(),
661 .tag = .none,
662 .val = backing_val.toIntern(),
663 }));
660 },
661 .@"packed" => {
662 const backing_int_val = try pack.primitive(ty.bitpackBackingInt(zcu));
663 return pt.bitpackValue(ty, backing_int_val);
664 },
664665 },
665666 else => return pack.primitive(ty),
666667 }
......@@ -673,6 +674,9 @@ const PackValueBits = struct {
673674 fn primitive(pack: *PackValueBits, want_ty: Type) BitCastError!Value {
674675 const pt = pack.pt;
675676 const zcu = pt.zcu;
677
678 if (try want_ty.onePossibleValue(pt)) |opv| return opv;
679
676680 const vals, const bit_offset = pack.prepareBits(want_ty.bitSize(zcu));
677681
678682 for (vals) |val| {
......@@ -719,7 +723,7 @@ const PackValueBits = struct {
719723 const val = Value.fromInterned(ip_val);
720724 const ty = val.typeOf(zcu);
721725 if (!val.isUndef(zcu)) {
722 try val.writeToPackedMemory(ty, pt, buf, cur_bit_off);
726 try val.writeToPackedMemory(pt, buf, cur_bit_off);
723727 }
724728 cur_bit_off += @intCast(ty.bitSize(zcu));
725729 }
src/Sema/comptime_ptr_access.zig+19-19
......@@ -67,7 +67,7 @@ pub fn storeComptimePtr(
6767
6868 {
6969 const store_ty: Type = .fromInterned(ptr_info.child);
70 if (!try store_ty.comptimeOnlySema(pt) and !try store_ty.hasRuntimeBitsIgnoreComptimeSema(pt)) {
70 if (!store_ty.comptimeOnly(zcu) and !store_ty.hasRuntimeBits(zcu)) {
7171 // zero-bit store; nothing to do
7272 return .success;
7373 }
......@@ -354,8 +354,8 @@ fn loadComptimePtrInner(
354354 const load_one_ty, const load_count = load_ty.arrayBase(zcu);
355355
356356 const extra_base_index: u64 = if (ptr.byte_offset == 0) 0 else idx: {
357 if (try load_one_ty.comptimeOnlySema(pt)) break :restructure_array;
358 const elem_len = try load_one_ty.abiSizeSema(pt);
357 if (load_one_ty.comptimeOnly(zcu)) break :restructure_array;
358 const elem_len = load_one_ty.abiSize(zcu);
359359 if (ptr.byte_offset % elem_len != 0) break :restructure_array;
360360 break :idx @divExact(ptr.byte_offset, elem_len);
361361 };
......@@ -401,12 +401,12 @@ fn loadComptimePtrInner(
401401 var cur_offset = ptr.byte_offset;
402402
403403 if (load_ty.zigTypeTag(zcu) == .array and array_offset > 0) {
404 cur_offset += try load_ty.childType(zcu).abiSizeSema(pt) * array_offset;
404 cur_offset += load_ty.childType(zcu).abiSize(zcu) * array_offset;
405405 }
406406
407 const need_bytes = if (host_bits > 0) (host_bits + 7) / 8 else try load_ty.abiSizeSema(pt);
407 const need_bytes = if (host_bits > 0) (host_bits + 7) / 8 else load_ty.abiSize(zcu);
408408
409 if (cur_offset + need_bytes > try cur_val.typeOf(zcu).abiSizeSema(pt)) {
409 if (cur_offset + need_bytes > cur_val.typeOf(zcu).abiSize(zcu)) {
410410 return .{ .out_of_bounds = cur_val.typeOf(zcu) };
411411 }
412412
......@@ -441,7 +441,7 @@ fn loadComptimePtrInner(
441441 .optional => break, // this can only be a pointer-like optional so is terminal
442442 .array => {
443443 const elem_ty = cur_ty.childType(zcu);
444 const elem_size = try elem_ty.abiSizeSema(pt);
444 const elem_size = elem_ty.abiSize(zcu);
445445 const elem_idx = cur_offset / elem_size;
446446 const next_elem_off = elem_size * (elem_idx + 1);
447447 if (cur_offset + need_bytes <= next_elem_off) {
......@@ -457,7 +457,7 @@ fn loadComptimePtrInner(
457457 .@"packed" => break, // let the bitcast logic handle this
458458 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {
459459 const start_off = cur_ty.structFieldOffset(field_idx, zcu);
460 const end_off = start_off + try cur_ty.fieldType(field_idx, zcu).abiSizeSema(pt);
460 const end_off = start_off + cur_ty.fieldType(field_idx, zcu).abiSize(zcu);
461461 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {
462462 cur_val = try cur_val.getElem(sema.pt, field_idx);
463463 cur_offset -= start_off;
......@@ -484,7 +484,7 @@ fn loadComptimePtrInner(
484484 };
485485 // The payload always has offset 0. If it's big enough
486486 // to represent the whole load type, we can use it.
487 if (try payload.typeOf(zcu).abiSizeSema(pt) >= need_bytes) {
487 if (payload.typeOf(zcu).abiSize(zcu) >= need_bytes) {
488488 cur_val = payload;
489489 } else {
490490 break;
......@@ -753,8 +753,8 @@ fn prepareComptimePtrStore(
753753
754754 const store_one_ty, const store_count = store_ty.arrayBase(zcu);
755755 const extra_base_index: u64 = if (ptr.byte_offset == 0) 0 else idx: {
756 if (try store_one_ty.comptimeOnlySema(pt)) break :restructure_array;
757 const elem_len = try store_one_ty.abiSizeSema(pt);
756 if (store_one_ty.comptimeOnly(zcu)) break :restructure_array;
757 const elem_len = store_one_ty.abiSize(zcu);
758758 if (ptr.byte_offset % elem_len != 0) break :restructure_array;
759759 break :idx @divExact(ptr.byte_offset, elem_len);
760760 };
......@@ -807,11 +807,11 @@ fn prepareComptimePtrStore(
807807 var cur_val: *MutableValue, var cur_offset: u64 = switch (base_strat) {
808808 .direct => |direct| .{ direct.val, 0 },
809809 // It's okay to do `abiSize` - the comptime-only case will be caught below.
810 .index => |index| .{ index.val, index.elem_index * try index.val.typeOf(zcu).childType(zcu).abiSizeSema(pt) },
810 .index => |index| .{ index.val, index.elem_index * index.val.typeOf(zcu).childType(zcu).abiSize(zcu) },
811811 .flat_index => |flat_index| .{
812812 flat_index.val,
813813 // It's okay to do `abiSize` - the comptime-only case will be caught below.
814 flat_index.flat_elem_index * try flat_index.val.typeOf(zcu).arrayBase(zcu)[0].abiSizeSema(pt),
814 flat_index.flat_elem_index * flat_index.val.typeOf(zcu).arrayBase(zcu)[0].abiSize(zcu),
815815 },
816816 .reinterpret => |r| .{ r.val, r.byte_offset },
817817 else => unreachable,
......@@ -823,12 +823,12 @@ fn prepareComptimePtrStore(
823823 }
824824
825825 if (store_ty.zigTypeTag(zcu) == .array and array_offset > 0) {
826 cur_offset += try store_ty.childType(zcu).abiSizeSema(pt) * array_offset;
826 cur_offset += store_ty.childType(zcu).abiSize(zcu) * array_offset;
827827 }
828828
829 const need_bytes = try store_ty.abiSizeSema(pt);
829 const need_bytes = store_ty.abiSize(zcu);
830830
831 if (cur_offset + need_bytes > try cur_val.typeOf(zcu).abiSizeSema(pt)) {
831 if (cur_offset + need_bytes > cur_val.typeOf(zcu).abiSize(zcu)) {
832832 return .{ .out_of_bounds = cur_val.typeOf(zcu) };
833833 }
834834
......@@ -863,7 +863,7 @@ fn prepareComptimePtrStore(
863863 .optional => break, // this can only be a pointer-like optional so is terminal
864864 .array => {
865865 const elem_ty = cur_ty.childType(zcu);
866 const elem_size = try elem_ty.abiSizeSema(pt);
866 const elem_size = elem_ty.abiSize(zcu);
867867 const elem_idx = cur_offset / elem_size;
868868 const next_elem_off = elem_size * (elem_idx + 1);
869869 if (cur_offset + need_bytes <= next_elem_off) {
......@@ -879,7 +879,7 @@ fn prepareComptimePtrStore(
879879 .@"packed" => break, // let the bitcast logic handle this
880880 .@"extern" => for (0..cur_ty.structFieldCount(zcu)) |field_idx| {
881881 const start_off = cur_ty.structFieldOffset(field_idx, zcu);
882 const end_off = start_off + try cur_ty.fieldType(field_idx, zcu).abiSizeSema(pt);
882 const end_off = start_off + cur_ty.fieldType(field_idx, zcu).abiSize(zcu);
883883 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {
884884 cur_val = try cur_val.elem(pt, sema.arena, field_idx);
885885 cur_offset -= start_off;
......@@ -902,7 +902,7 @@ fn prepareComptimePtrStore(
902902 };
903903 // The payload always has offset 0. If it's big enough
904904 // to represent the whole load type, we can use it.
905 if (try payload.typeOf(zcu).abiSizeSema(pt) >= need_bytes) {
905 if (payload.typeOf(zcu).abiSize(zcu) >= need_bytes) {
906906 cur_val = payload;
907907 } else {
908908 break;
src/Sema/type_resolution.zig created+1398
......@@ -0,0 +1,1398 @@
1const std = @import("std");
2const assert = std.debug.assert;
3const mem = std.mem;
4
5const Sema = @import("../Sema.zig");
6const Block = Sema.Block;
7const Type = @import("../Type.zig");
8const Value = @import("../Value.zig");
9const Zcu = @import("../Zcu.zig");
10const CompileError = Zcu.CompileError;
11const SemaError = Zcu.SemaError;
12const LazySrcLoc = Zcu.LazySrcLoc;
13const InternPool = @import("../InternPool.zig");
14const Alignment = InternPool.Alignment;
15const arith = @import("arith.zig");
16
17pub const LayoutResolveReason = enum {
18 variable,
19 constant,
20 parameter,
21 return_type,
22 field,
23 backing_enum,
24 init,
25 coerce,
26 ptr_access,
27 ptr_offset,
28 field_used,
29 field_queried,
30 size_of,
31 align_of,
32 type_info,
33 align_check,
34 bit_ptr_child,
35 @"export",
36 @"extern",
37 builtin_type,
38
39 /// Written after string: "while resolving type 'T' "
40 /// e.g. "while resolving type 'MyStruct' for variable declared here"
41 pub fn msg(r: LayoutResolveReason) []const u8 {
42 return switch (r) {
43 // zig fmt: off
44 .variable => "for variable declared here",
45 .constant => "for constant declared here",
46 .parameter => "for function parameter declared here",
47 .return_type => "for function return type declared here",
48 .field => "for field declared here",
49 .backing_enum => "for backing enum type declared here",
50 .init => "for initialization performed here",
51 .coerce => "for coercion performed here",
52 .ptr_access => "for pointer access here",
53 .ptr_offset => "for pointer offset here",
54 .field_used => "for field usage here",
55 .field_queried => "for field query here",
56 .size_of => "for size query here",
57 .align_of => "for alignment query here",
58 .type_info => "for type information query here",
59 .align_check => "for alignment check here",
60 .bit_ptr_child => "for bit size check here",
61 .@"export" => "for export here",
62 .@"extern" => "for extern declaration here",
63 .builtin_type => "from 'std.builtin'",
64 // zig fmt: on
65 };
66 }
67};
68
69/// Ensures that `ty` has known layout, including alignment, size, and (where relevant) field offsets.
70/// `ty` may be any type; its layout is resolved *recursively* if necessary.
71/// Adds incremental dependencies tracking any required type resolution.
72pub fn ensureLayoutResolved(sema: *Sema, ty: Type, src: LazySrcLoc, reason: LayoutResolveReason) SemaError!void {
73 return ensureLayoutResolvedInner(sema, ty, ty, &.{
74 .src = src,
75 .type_layout_reason = reason,
76 });
77}
78fn ensureLayoutResolvedInner(sema: *Sema, ty: Type, orig_ty: Type, reason: *const Zcu.DependencyReason) SemaError!void {
79 const pt = sema.pt;
80 const zcu = pt.zcu;
81 const ip = &zcu.intern_pool;
82 switch (ip.indexToKey(ty.toIntern())) {
83 .int_type,
84 .ptr_type,
85 .anyframe_type,
86 .simple_type,
87 .opaque_type,
88 .error_set_type,
89 .inferred_error_set_type,
90 => {},
91
92 .func_type => |func_type| {
93 for (func_type.param_types.get(ip)) |param_ty| {
94 try ensureLayoutResolvedInner(sema, .fromInterned(param_ty), orig_ty, reason);
95 }
96 try ensureLayoutResolvedInner(sema, .fromInterned(func_type.return_type), orig_ty, reason);
97 },
98
99 .array_type => |arr| return ensureLayoutResolvedInner(sema, .fromInterned(arr.child), orig_ty, reason),
100 .vector_type => |vec| return ensureLayoutResolvedInner(sema, .fromInterned(vec.child), orig_ty, reason),
101 .opt_type => |child| return ensureLayoutResolvedInner(sema, .fromInterned(child), orig_ty, reason),
102 .error_union_type => |eu| return ensureLayoutResolvedInner(sema, .fromInterned(eu.payload_type), orig_ty, reason),
103 .tuple_type => |tuple| for (tuple.types.get(ip)) |field_ty| {
104 try ensureLayoutResolvedInner(sema, .fromInterned(field_ty), orig_ty, reason);
105 },
106 .struct_type, .union_type, .enum_type => {
107 try sema.declareDependency(.{ .type_layout = ty.toIntern() });
108 try sema.addReferenceEntry(null, reason.src, .wrap(.{ .type_layout = ty.toIntern() }));
109 if (zcu.analysis_in_progress.contains(.wrap(.{ .type_layout = ty.toIntern() }))) {
110 return sema.failWithDependencyLoop(.wrap(.{ .type_layout = ty.toIntern() }), reason);
111 }
112 try pt.ensureTypeLayoutUpToDate(ty, reason);
113 },
114
115 // values, not types
116 .undef,
117 .simple_value,
118 .variable,
119 .@"extern",
120 .func,
121 .int,
122 .err,
123 .error_union,
124 .enum_literal,
125 .enum_tag,
126 .float,
127 .ptr,
128 .slice,
129 .opt,
130 .aggregate,
131 .un,
132 .bitpack,
133 // memoization, not types
134 .memoized_call,
135 => unreachable,
136 }
137}
138
139/// Asserts that `ty` is a non-tuple `struct` type, and ensures that its fields' default values
140/// are resolved. Adds incremental dependencies tracking the required type resolution.
141///
142/// It is not necessary to call this function to query the values of comptime fields: those values
143/// are available from type *layout* resolution, see `ensureLayoutResolved`.
144///
145/// Asserts that the *layout* of `ty` has already been resolved---see `ensureLayoutResolved`.
146pub fn ensureStructDefaultsResolved(sema: *Sema, ty: Type, src: LazySrcLoc) SemaError!void {
147 const pt = sema.pt;
148 const zcu = pt.zcu;
149 const ip = &zcu.intern_pool;
150
151 assert(ip.indexToKey(ty.toIntern()) == .struct_type);
152 ty.assertHasLayout(zcu);
153
154 try sema.declareDependency(.{ .struct_defaults = ty.toIntern() });
155 try sema.addReferenceEntry(null, src, .wrap(.{ .struct_defaults = ty.toIntern() }));
156
157 const reason: Zcu.DependencyReason = .{ .src = src, .type_layout_reason = undefined };
158
159 if (zcu.analysis_in_progress.contains(.wrap(.{ .struct_defaults = ty.toIntern() }))) {
160 return sema.failWithDependencyLoop(.wrap(.{ .struct_defaults = ty.toIntern() }), &reason);
161 }
162
163 try pt.ensureStructDefaultsUpToDate(ty, &reason);
164}
165
166/// Asserts that `struct_ty` is a non-packed non-tuple struct, and that `sema.owner` is that type.
167/// This function *does* register the `src_hash` dependency on the struct.
168pub fn resolveStructLayout(sema: *Sema, struct_ty: Type) CompileError!void {
169 const pt = sema.pt;
170 const zcu = pt.zcu;
171 const comp = zcu.comp;
172 const io = comp.io;
173 const gpa = comp.gpa;
174 const ip = &zcu.intern_pool;
175
176 assert(sema.owner.unwrap().type_layout == struct_ty.toIntern());
177
178 const struct_obj = ip.loadStructType(struct_ty.toIntern());
179 assert(struct_obj.want_layout);
180 const zir_index = struct_obj.zir_index.resolve(ip) orelse return error.AnalysisFail;
181
182 var block: Block = .{
183 .parent = null,
184 .sema = sema,
185 .namespace = struct_obj.namespace,
186 .instructions = .empty,
187 .inlining = null,
188 .comptime_reason = undefined, // always set before using `block`
189 .src_base_inst = struct_obj.zir_index,
190 .type_name_ctx = struct_obj.name,
191 };
192 defer block.instructions.deinit(gpa);
193
194 // There may be old field names in here from a previous update.
195 struct_obj.field_name_map.get(ip).clearRetainingCapacity();
196
197 if (struct_obj.is_reified) {
198 // The field names are populated, but we haven't checked for duplicates (nor populated the map) yet.
199 for (0..struct_obj.field_names.len) |field_index| {
200 const name = struct_obj.field_names.get(ip)[field_index];
201 if (ip.addFieldName(struct_obj.field_names, struct_obj.field_name_map, name)) |prev_field_index| {
202 return sema.failWithOwnedErrorMsg(&block, msg: {
203 const src = block.builtinCallArgSrc(.zero, 2);
204 const msg = try sema.errMsg(src, "duplicate struct field '{f}' at index '{d}", .{ name.fmt(ip), field_index });
205 errdefer msg.destroy(gpa);
206 try sema.errNote(src, msg, "previous field at index '{d}'", .{prev_field_index});
207 break :msg msg;
208 });
209 }
210 }
211 } else {
212 // Declared structs do not yet have field information populated:
213 // * field names
214 // * field comptime-ness
215 // * field types
216 // * field aligns
217 // It's our job to populate these now.
218 try sema.declareDependency(.{ .src_hash = struct_obj.zir_index });
219
220 // Likewise, comptime bits may be set. We clear them all first because it avoids needing
221 // "unset bit with AND" logic below (instead we only need the "set bit with OR" case).
222 @memset(struct_obj.field_is_comptime_bits.getAll(ip), 0);
223
224 const zir_struct = sema.code.getStructDecl(zir_index);
225 var field_it = zir_struct.iterateFields();
226 var any_comptime_fields = false;
227 while (field_it.next()) |zir_field| {
228 {
229 const name_slice = sema.code.nullTerminatedString(zir_field.name);
230 const name = try ip.getOrPutString(gpa, io, pt.tid, name_slice, .no_embedded_nulls);
231 assert(ip.addFieldName(struct_obj.field_names, struct_obj.field_name_map, name) == null); // AstGen validated this for us
232 }
233
234 if (zir_field.is_comptime) {
235 const bit_bag_index = zir_field.idx / 32;
236 const mask = @as(u32, 1) << @intCast(zir_field.idx % 32);
237 struct_obj.field_is_comptime_bits.getAll(ip)[bit_bag_index] |= mask;
238 any_comptime_fields = true;
239 }
240
241 {
242 const field_ty_src = block.src(.{ .container_field_type = zir_field.idx });
243 const field_ty: Type = field_ty: {
244 block.comptime_reason = .{ .reason = .{
245 .src = field_ty_src,
246 .r = .{ .simple = .struct_field_types },
247 } };
248 const type_ref = try sema.resolveInlineBody(&block, zir_field.type_body, zir_index);
249 break :field_ty try sema.analyzeAsType(&block, field_ty_src, .struct_field_types, type_ref);
250 };
251 struct_obj.field_types.get(ip)[zir_field.idx] = field_ty.toIntern();
252 }
253
254 if (struct_obj.field_aligns.len == 0) {
255 assert(zir_field.align_body == null);
256 } else {
257 const field_align_src = block.src(.{ .container_field_align = zir_field.idx });
258 const field_align: Alignment = a: {
259 block.comptime_reason = .{ .reason = .{
260 .src = field_align_src,
261 .r = .{ .simple = .struct_field_attrs },
262 } };
263 const align_body = zir_field.align_body orelse break :a .none;
264 const align_ref = try sema.resolveInlineBody(&block, align_body, zir_index);
265 break :a try sema.analyzeAsAlign(&block, field_align_src, align_ref);
266 };
267 struct_obj.field_aligns.get(ip)[zir_field.idx] = field_align;
268 }
269 }
270
271 // We also resolve the default values of any `comptime` fields now. This is not necessary in
272 // the case of a reified struct because the the default values were already poulated and
273 // validated by `Sema.zirReifyStruct`.
274 if (any_comptime_fields) {
275 try resolveStructDefaultsInner(sema, &block, &struct_obj, .comptime_fields);
276 }
277 }
278
279 if (struct_obj.layout == .@"packed") {
280 return resolvePackedStructLayout(sema, &block, struct_ty, &struct_obj);
281 }
282
283 // Resolve the layout of all fields, and check their types are allowed.
284 for (struct_obj.field_types.get(ip), 0..) |field_ty_ip, field_index| {
285 const field_ty: Type = .fromInterned(field_ty_ip);
286 assert(!field_ty.isGenericPoison());
287 const field_ty_src = block.src(.{ .container_field_type = @intCast(field_index) });
288 try sema.ensureLayoutResolved(field_ty, field_ty_src, .field);
289 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
290 return sema.failWithOwnedErrorMsg(&block, msg: {
291 const msg = try sema.errMsg(field_ty_src, "cannot directly embed opaque type '{f}' in struct", .{field_ty.fmt(pt)});
292 errdefer msg.destroy(gpa);
293 try sema.errNote(field_ty_src, msg, "opaque types have unknown size", .{});
294 try sema.addDeclaredHereNote(msg, field_ty);
295 break :msg msg;
296 });
297 }
298 if (struct_obj.layout == .@"extern" and !field_ty.validateExtern(.struct_field, zcu)) {
299 return sema.failWithOwnedErrorMsg(&block, msg: {
300 const msg = try sema.errMsg(field_ty_src, "extern structs cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
301 errdefer msg.destroy(gpa);
302 try sema.explainWhyTypeIsNotExtern(msg, field_ty_src, field_ty, .struct_field);
303 try sema.addDeclaredHereNote(msg, field_ty);
304 break :msg msg;
305 });
306 }
307 }
308
309 // Fields are okay. Now we need to resolve the struct's overall layout (size, field offsets, etc).
310
311 var any_comptime_fields = false;
312 var struct_align: Alignment = .@"1";
313 var has_no_possible_value = false;
314 var has_runtime_state = false;
315 var has_comptime_state = false;
316 // Unlike `struct_obj.field_aligns`, these are not `.none`.
317 const resolved_field_aligns = try sema.arena.alloc(Alignment, struct_obj.field_names.len);
318 for (resolved_field_aligns, 0..) |*align_out, field_idx| {
319 const field_ty: Type = .fromInterned(struct_obj.field_types.get(ip)[field_idx]);
320 const field_align: Alignment = a: {
321 if (struct_obj.field_aligns.len != 0) {
322 const a = struct_obj.field_aligns.get(ip)[field_idx];
323 if (a != .none) break :a a;
324 }
325 break :a field_ty.defaultStructFieldAlignment(struct_obj.layout, zcu);
326 };
327 align_out.* = field_align;
328 if (struct_obj.field_is_comptime_bits.get(ip, field_idx)) {
329 assert(struct_obj.layout == .auto); // comptime fields not allowed in extern or packed structs
330 struct_obj.field_runtime_order.get(ip)[field_idx] = .omitted; // comptime fields are not in the runtime order
331 any_comptime_fields = true;
332 continue; // `comptime` fields do not contribute to the struct layout
333 }
334 struct_align = struct_align.maxStrict(field_align);
335 if (struct_obj.layout == .auto) {
336 struct_obj.field_runtime_order.get(ip)[field_idx] = @enumFromInt(field_idx);
337 }
338 switch (field_ty.classify(zcu)) {
339 .one_possible_value => {},
340 .no_possible_value => has_no_possible_value = true,
341 .runtime => has_runtime_state = true,
342 .fully_comptime => has_comptime_state = true,
343 .partially_comptime => {
344 has_runtime_state = true;
345 has_comptime_state = true;
346 },
347 }
348 }
349 const class: Type.Class = class: {
350 if (has_no_possible_value) break :class .no_possible_value;
351 if (has_comptime_state) {
352 break :class if (has_runtime_state) .partially_comptime else .fully_comptime;
353 } else {
354 break :class if (has_runtime_state) .runtime else .one_possible_value;
355 }
356 };
357
358 switch (struct_obj.layout) {
359 .auto => {},
360 .@"extern" => assert(class != .no_possible_value), // field types are all extern, so are not NPV
361 .@"packed" => unreachable,
362 }
363
364 if (struct_obj.layout == .auto) {
365 const runtime_order = struct_obj.field_runtime_order.get(ip);
366 // This logic does not reorder fields; it only moves the omitted ones to the end so that logic
367 // elsewhere does not need to special-case. TODO: support field reordering in all the backends!
368 if (!zcu.backendSupportsFeature(.field_reordering)) {
369 var i: usize = 0;
370 var off: usize = 0;
371 while (i + off < runtime_order.len) {
372 if (runtime_order[i + off] == .omitted) {
373 off += 1;
374 } else {
375 runtime_order[i] = runtime_order[i + off];
376 i += 1;
377 }
378 }
379 } else {
380 // Sort by descending alignment to minimize padding.
381 const RuntimeOrder = InternPool.LoadedStructType.RuntimeOrder;
382 const AlignSortCtx = struct {
383 aligns: []const Alignment,
384 fn lessThan(ctx: @This(), a: RuntimeOrder, b: RuntimeOrder) bool {
385 assert(a != .unresolved);
386 assert(b != .unresolved);
387 if (a == .omitted) return false;
388 if (b == .omitted) return true;
389 const a_align = ctx.aligns[@intFromEnum(a)];
390 const b_align = ctx.aligns[@intFromEnum(b)];
391 return a_align.compare(.gt, b_align);
392 }
393 };
394 mem.sortUnstable(
395 RuntimeOrder,
396 runtime_order,
397 @as(AlignSortCtx, .{ .aligns = resolved_field_aligns }),
398 AlignSortCtx.lessThan,
399 );
400 }
401 }
402
403 var runtime_order_it = struct_obj.iterateRuntimeOrder(ip);
404 var cur_offset: u64 = 0;
405 while (runtime_order_it.next()) |field_idx| {
406 const field_ty: Type = .fromInterned(struct_obj.field_types.get(ip)[field_idx]);
407 const offset = resolved_field_aligns[field_idx].forward(cur_offset);
408 struct_obj.field_offsets.get(ip)[field_idx] = @truncate(offset); // truncate because the overflow is handled below
409 cur_offset = offset + field_ty.abiSize(zcu);
410 }
411 const struct_size: u32 = switch (class) {
412 .no_possible_value => 0,
413 else => std.math.cast(u32, struct_align.forward(cur_offset)) orelse return sema.fail(
414 &block,
415 struct_ty.srcLoc(zcu),
416 "struct layout requires size {d}, this compiler implementation supports up to {d}",
417 .{ struct_align.forward(cur_offset), std.math.maxInt(u32) },
418 ),
419 };
420 ip.resolveStructLayout(
421 io,
422 struct_ty.toIntern(),
423 struct_size,
424 struct_align,
425 class,
426 );
427}
428
429/// Asserts that `struct_ty` is a packed struct, and that `sema.owner` is that type.
430/// This function *does* register the `src_hash` dependency on the struct.
431fn resolvePackedStructLayout(
432 sema: *Sema,
433 block: *Block,
434 struct_ty: Type,
435 struct_obj: *const InternPool.LoadedStructType,
436) CompileError!void {
437 const pt = sema.pt;
438 const zcu = pt.zcu;
439 const comp = zcu.comp;
440 const io = comp.io;
441 const gpa = comp.gpa;
442 const ip = &zcu.intern_pool;
443
444 // Resolve the layout of all fields, and check their types are allowed.
445 // Also count the number of bits while we're at it.
446 var field_bits: u64 = 0;
447 for (struct_obj.field_types.get(ip), 0..) |field_ty_ip, field_index| {
448 const field_ty: Type = .fromInterned(field_ty_ip);
449 assert(!field_ty.isGenericPoison());
450 const field_ty_src = block.src(.{ .container_field_type = @intCast(field_index) });
451 try sema.ensureLayoutResolved(field_ty, field_ty_src, .field);
452 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
453 return sema.failWithOwnedErrorMsg(block, msg: {
454 const msg = try sema.errMsg(field_ty_src, "cannot directly embed opaque type '{f}' in struct", .{field_ty.fmt(pt)});
455 errdefer msg.destroy(gpa);
456 try sema.errNote(field_ty_src, msg, "opaque types have unknown size", .{});
457 try sema.addDeclaredHereNote(msg, field_ty);
458 break :msg msg;
459 });
460 }
461 if (field_ty.unpackable(zcu)) |reason| return sema.failWithOwnedErrorMsg(block, msg: {
462 const msg = try sema.errMsg(field_ty_src, "packed structs cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
463 errdefer msg.destroy(gpa);
464 try sema.explainWhyTypeIsUnpackable(msg, field_ty_src, reason);
465 break :msg msg;
466 });
467 switch (field_ty.classify(zcu)) {
468 .one_possible_value, .runtime => {},
469 .no_possible_value => unreachable, // packable types are not NPV
470 .partially_comptime => unreachable, // packable types are not comptime-only
471 .fully_comptime => unreachable, // packable types are not comptime-only
472 }
473 field_bits += field_ty.bitSize(zcu);
474 }
475
476 const explicit_backing_int_ty: ?Type = if (struct_obj.is_reified) ty: {
477 break :ty switch (struct_obj.packed_backing_mode) {
478 .explicit => .fromInterned(struct_obj.packed_backing_int_type),
479 .auto => null,
480 };
481 } else ty: {
482 const zir_index = struct_obj.zir_index.resolve(ip).?;
483 const zir_struct = sema.code.getStructDecl(zir_index);
484 const backing_int_type_body = zir_struct.backing_int_type_body orelse {
485 break :ty null; // inferred backing type
486 };
487 // Explicitly specified, so evaluate the backing int type expression.
488 const backing_int_type_src = block.src(.container_arg);
489 block.comptime_reason = .{ .reason = .{
490 .src = backing_int_type_src,
491 .r = .{ .simple = .packed_struct_backing_int_type },
492 } };
493 const type_ref = try sema.resolveInlineBody(block, backing_int_type_body, zir_index);
494 break :ty try sema.analyzeAsType(block, backing_int_type_src, .packed_struct_backing_int_type, type_ref);
495 };
496
497 // Finally, either validate or infer the backing int type.
498 const backing_int_ty: Type = if (explicit_backing_int_ty) |backing_ty| ty: {
499 if (backing_ty.zigTypeTag(zcu) != .int) return sema.fail(
500 block,
501 block.src(.container_arg),
502 "expected backing integer type, found '{f}'",
503 .{backing_ty.fmt(pt)},
504 );
505 if (field_bits != backing_ty.intInfo(zcu).bits) return sema.failWithOwnedErrorMsg(block, msg: {
506 const src = struct_ty.srcLoc(zcu);
507 const msg = try sema.errMsg(src, "backing integer bit width does not match total bit width of fields", .{});
508 errdefer msg.destroy(gpa);
509 try sema.errNote(
510 block.src(.container_arg),
511 msg,
512 "backing integer '{f}' has bit width '{d}'",
513 .{ backing_ty.fmt(pt), backing_ty.bitSize(zcu) },
514 );
515 try sema.errNote(src, msg, "struct fields have total bit width '{d}'", .{field_bits});
516 break :msg msg;
517 });
518 break :ty backing_ty;
519 } else ty: {
520 // We need to generate the inferred tag.
521 const backing_int_bits = std.math.cast(u16, field_bits) orelse return sema.fail(
522 block,
523 struct_ty.srcLoc(zcu),
524 "packed struct bit width '{d}' exceeds maximum bit width of 65535",
525 .{field_bits},
526 );
527 break :ty try pt.intType(.unsigned, backing_int_bits);
528 };
529 ip.resolvePackedStructLayout(
530 io,
531 struct_ty.toIntern(),
532 backing_int_ty.toIntern(),
533 );
534}
535
536/// Asserts that `struct_ty` is a non-tuple struct, and that `sema.owner` is that type.
537///
538/// Also asserts that the layout of `struct_ty` has *already* been resolved (though it is okay for
539/// that resolution to have failed). This requirement exists to ensure better error messages in the
540/// event of a dependency loop.
541///
542/// This function *does* register the `src_hash` dependency on the struct.
543pub fn resolveStructDefaults(sema: *Sema, struct_ty: Type) CompileError!void {
544 const pt = sema.pt;
545 const zcu = pt.zcu;
546 const comp = zcu.comp;
547 const gpa = comp.gpa;
548 const ip = &zcu.intern_pool;
549
550 assert(sema.owner.unwrap().struct_defaults == struct_ty.toIntern());
551
552 // We always depend on the layout of `struct_ty`. However, we don't actually need to resolve it
553 // now, because the caller has done so for us. Just mark the dependency so that the incremental
554 // compilation handling understands the dependency graph.
555 try sema.declareDependency(.{ .type_layout = struct_ty.toIntern() });
556 struct_ty.assertHasLayout(zcu);
557 const layout_unit: InternPool.AnalUnit = .wrap(.{ .type_layout = struct_ty.toIntern() });
558 if (zcu.failed_analysis.contains(layout_unit) or zcu.transitive_failed_analysis.contains(layout_unit)) {
559 return error.AnalysisFail;
560 }
561
562 const struct_obj = ip.loadStructType(struct_ty.toIntern());
563 assert(struct_obj.want_layout);
564
565 if (struct_obj.is_reified) {
566 // `Sema.zirReifyStruct` has already populated the default field values *and* (by loading
567 // the default values from pointers) validated their types, so we have nothing to do.
568 return;
569 }
570
571 try sema.declareDependency(.{ .src_hash = struct_obj.zir_index });
572
573 if (struct_obj.field_defaults.len == 0) {
574 // The struct has no default field values, so the slice has been omitted.
575 return;
576 }
577
578 var block: Block = .{
579 .parent = null,
580 .sema = sema,
581 .namespace = struct_obj.namespace,
582 .instructions = .empty,
583 .inlining = null,
584 .comptime_reason = undefined, // always set before using `block`
585 .src_base_inst = struct_obj.zir_index,
586 .type_name_ctx = struct_obj.name,
587 };
588 defer block.instructions.deinit(gpa);
589
590 return resolveStructDefaultsInner(sema, &block, &struct_obj, .normal_fields);
591}
592
593/// Asserts that the struct is not reified, and that `struct_obj.field_defaults.len` is non-zero.
594fn resolveStructDefaultsInner(
595 sema: *Sema,
596 block: *Block,
597 struct_obj: *const InternPool.LoadedStructType,
598 mode: enum { comptime_fields, normal_fields },
599) CompileError!void {
600 const pt = sema.pt;
601 const zcu = pt.zcu;
602 const comp = zcu.comp;
603 const gpa = comp.gpa;
604 const ip = &zcu.intern_pool;
605
606 assert(struct_obj.field_defaults.len > 0);
607
608 // We'll need to map the struct decl instruction to provide result types
609 const zir_index = struct_obj.zir_index.resolve(ip) orelse return error.AnalysisFail;
610 try sema.inst_map.ensureSpaceForInstructions(gpa, &.{zir_index});
611
612 const field_types = struct_obj.field_types.get(ip);
613
614 const zir_struct = sema.code.getStructDecl(zir_index);
615 var field_it = zir_struct.iterateFields();
616 while (field_it.next()) |zir_field| {
617 switch (mode) {
618 .comptime_fields => if (!zir_field.is_comptime) continue,
619 .normal_fields => if (zir_field.is_comptime) continue,
620 }
621
622 const default_val_src = block.src(.{ .container_field_value = zir_field.idx });
623 block.comptime_reason = .{ .reason = .{
624 .src = default_val_src,
625 .r = .{ .simple = .struct_field_default_value },
626 } };
627 const default_body = zir_field.default_body orelse {
628 struct_obj.field_defaults.get(ip)[zir_field.idx] = .none;
629 continue;
630 };
631 const field_ty: Type = .fromInterned(field_types[zir_field.idx]);
632 const uncoerced = ref: {
633 // Provide the result type
634 sema.inst_map.putAssumeCapacity(zir_index, .fromIntern(field_ty.toIntern()));
635 defer assert(sema.inst_map.remove(zir_index));
636 break :ref try sema.resolveInlineBody(block, default_body, zir_index);
637 };
638 const coerced = try sema.coerce(block, field_ty, uncoerced, default_val_src);
639 const default_val = try sema.resolveConstValue(block, default_val_src, coerced, null);
640 if (default_val.canMutateComptimeVarState(zcu)) {
641 const field_name = struct_obj.field_names.get(ip)[zir_field.idx];
642 return sema.failWithContainsReferenceToComptimeVar(block, default_val_src, field_name, "field default value", default_val);
643 }
644 struct_obj.field_defaults.get(ip)[zir_field.idx] = default_val.toIntern();
645 }
646}
647
648/// This logic must be kept in sync with `Type.getUnionLayout`.
649pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void {
650 const pt = sema.pt;
651 const zcu = pt.zcu;
652 const comp = zcu.comp;
653 const io = comp.io;
654 const gpa = comp.gpa;
655 const ip = &zcu.intern_pool;
656
657 assert(sema.owner.unwrap().type_layout == union_ty.toIntern());
658
659 const union_obj = ip.loadUnionType(union_ty.toIntern());
660 assert(union_obj.want_layout);
661 const zir_index = union_obj.zir_index.resolve(ip) orelse return error.AnalysisFail;
662
663 var block: Block = .{
664 .parent = null,
665 .sema = sema,
666 .namespace = union_obj.namespace,
667 .instructions = .empty,
668 .inlining = null,
669 .comptime_reason = undefined, // always set before using `block`
670 .src_base_inst = union_obj.zir_index,
671 .type_name_ctx = union_obj.name,
672 };
673 defer block.instructions.deinit(gpa);
674
675 const enum_tag_ty: Type = switch (union_obj.enum_tag_mode) {
676 .explicit => validated_tag_ty: {
677 // If the union is reified, its enum tag type is already populated. If the union is
678 // declared, we need to evaluate the enum tag type expression (the `E` in `union(E)`).
679 const tag_ty: Type = switch (union_obj.is_reified) {
680 true => .fromInterned(union_obj.enum_tag_type),
681 false => tag_ty: {
682 const zir_union = sema.code.getUnionDecl(zir_index);
683 assert(zir_union.kind == .tagged_explicit); // `Zcu.mapOldZirToNew` guarantees that the ZIR mapping preserves `kind`
684 const tag_type_body = zir_union.arg_type_body.?;
685 const tag_type_src = block.src(.container_arg);
686 block.comptime_reason = .{ .reason = .{
687 .src = tag_type_src,
688 .r = .{ .simple = .union_enum_tag_type },
689 } };
690 const type_ref = try sema.resolveInlineBody(&block, tag_type_body, zir_index);
691 break :tag_ty try sema.analyzeAsType(&block, tag_type_src, .union_enum_tag_type, type_ref);
692 },
693 };
694 // Because the type is explicitly specified, we need to validate it.
695 if (tag_ty.zigTypeTag(zcu) != .@"enum") return sema.fail(
696 &block,
697 block.src(.container_arg),
698 "expected enum tag type, found '{f}'",
699 .{tag_ty.fmt(pt)},
700 );
701 break :validated_tag_ty tag_ty;
702 },
703 // If no tag type was specified, we generate one keyed on this union type.
704 .auto => switch (try ip.getGeneratedEnumTagType(gpa, io, pt.tid, .{
705 .union_type = union_ty.toIntern(),
706 // The int tag for this enum is usually inferred---the exception is `union(enum(T))`.
707 .int_tag_mode = switch (union_obj.is_reified) {
708 true => .auto,
709 false => switch (sema.code.getUnionDecl(zir_index).kind) {
710 .tagged_enum_explicit => .explicit,
711 else => .auto,
712 },
713 },
714 .fields_len = @intCast(union_obj.field_types.len),
715 })) {
716 .existing => |tag_ty| .fromInterned(tag_ty),
717 .wip => |wip| tag_ty: {
718 errdefer wip.cancel(ip, pt.tid);
719 _ = wip.setName(ip, try ip.getOrPutStringFmt(
720 gpa,
721 io,
722 pt.tid,
723 "@typeInfo({f}).@\"union\".tag_type.?",
724 .{union_obj.name.fmt(ip)},
725 .no_embedded_nulls,
726 ), .none);
727 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
728 .parent = union_obj.namespace.toOptional(),
729 .owner_type = wip.index,
730 .file_scope = zcu.namespacePtr(union_obj.namespace).file_scope,
731 .generation = zcu.generation,
732 });
733 if (comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
734 break :tag_ty .fromInterned(wip.finish(ip, new_namespace_index));
735 },
736 },
737 };
738
739 try sema.ensureLayoutResolved(enum_tag_ty, block.src(.container_arg), .backing_enum);
740 const enum_obj = ip.loadEnumType(enum_tag_ty.toIntern());
741
742 if (union_obj.is_reified) {
743 // We have field names in `union_obj.reified_field_names`, but we haven't
744 // checked them against the backing type yet.
745 const union_field_names = union_obj.reified_field_names.get(ip);
746 match_fields: {
747 // We can efficiently *check* if the fields match...
748 if (union_field_names.len == enum_obj.field_names.len) {
749 for (union_field_names, enum_obj.field_names.get(ip)) |union_field_name, enum_field_name| {
750 if (!std.mem.eql(u8, union_field_name.toSlice(ip), enum_field_name.toSlice(ip))) break;
751 } else {
752 break :match_fields;
753 }
754 }
755 // ...but if they don't, reporting a nice error is a little more involved. If some field
756 // is present in the enum but not the union, or vice versa, we will report that instead
757 // of a generic "field order mismatch" error. Of course, this error is impossible for a
758 // generated tag type, because we populated that from the union ZIR!
759 assert(enum_obj.owner_union != union_ty.toIntern());
760 return failUnionFieldMismatch(sema, &block, union_field_names, enum_tag_ty, &enum_obj);
761 }
762 } else {
763 // Declared unions do not have field types or aligns populated yet.
764 // We also need to check the field names match the backing enum.
765 try sema.declareDependency(.{ .src_hash = union_obj.zir_index });
766 const zir_union = sema.code.getUnionDecl(zir_index);
767
768 // We'll first check the field names against the backing enum, and only analyze the types
769 // once we know the fields match one-to-one.
770 match_fields: {
771 // We can efficiently *check* if the fields match...
772 if (zir_union.field_names.len == enum_obj.field_names.len) {
773 for (zir_union.field_names, enum_obj.field_names.get(ip)) |union_field_name_zir, enum_field_name| {
774 const union_field_name_slice = sema.code.nullTerminatedString(union_field_name_zir);
775 if (!std.mem.eql(u8, union_field_name_slice, enum_field_name.toSlice(ip))) break;
776 } else {
777 break :match_fields;
778 }
779 }
780 // ...but if they don't, reporting a nice error is a little more involved. If some field
781 // is present in the enum but not the union, or vice versa, we will report that instead
782 // of a generic "field order mismatch" error. Of course, this error is impossible for a
783 // generated tag type, because we populated that from the union ZIR!
784 assert(enum_obj.owner_union != union_ty.toIntern());
785 const union_field_names = try sema.arena.alloc(InternPool.NullTerminatedString, zir_union.field_names.len);
786 for (zir_union.field_names, union_field_names) |name_zir, *name| {
787 name.* = try ip.getOrPutString(gpa, io, pt.tid, sema.code.nullTerminatedString(name_zir), .no_embedded_nulls);
788 }
789 return failUnionFieldMismatch(sema, &block, union_field_names, enum_tag_ty, &enum_obj);
790 }
791
792 // Field names okay; populate types and aligns.
793 var field_it = zir_union.iterateFields();
794 while (field_it.next()) |zir_field| {
795 const field_ty_src = block.src(.{ .container_field_type = zir_field.idx });
796 const field_ty: Type = field_ty: {
797 block.comptime_reason = .{ .reason = .{
798 .src = field_ty_src,
799 .r = .{ .simple = .union_field_types },
800 } };
801 const type_body = zir_field.type_body orelse break :field_ty .void;
802 const type_ref = try sema.resolveInlineBody(&block, type_body, zir_index);
803 break :field_ty try sema.analyzeAsType(&block, field_ty_src, .union_field_types, type_ref);
804 };
805 union_obj.field_types.get(ip)[zir_field.idx] = field_ty.toIntern();
806
807 const field_align_src = block.src(.{ .container_field_align = zir_field.idx });
808 const explicit_field_align: Alignment = a: {
809 block.comptime_reason = .{ .reason = .{
810 .src = field_align_src,
811 .r = .{ .simple = .union_field_attrs },
812 } };
813 const align_body = zir_field.align_body orelse break :a .none;
814 const align_ref = try sema.resolveInlineBody(&block, align_body, zir_index);
815 break :a try sema.analyzeAsAlign(&block, field_align_src, align_ref);
816 };
817 if (union_obj.field_aligns.len != 0) {
818 union_obj.field_aligns.get(ip)[zir_field.idx] = explicit_field_align;
819 } else {
820 assert(explicit_field_align == .none);
821 }
822 }
823 }
824
825 if (union_obj.layout == .@"packed") {
826 return resolvePackedUnionLayout(sema, &block, union_ty, &union_obj, enum_tag_ty);
827 }
828
829 // Resolve the layout of all fields, and check their types are allowed.
830 for (union_obj.field_types.get(ip), 0..) |field_ty_ip, field_index| {
831 const field_ty: Type = .fromInterned(field_ty_ip);
832 assert(!field_ty.isGenericPoison());
833 const field_ty_src = block.src(.{ .container_field_type = @intCast(field_index) });
834 try sema.ensureLayoutResolved(field_ty, field_ty_src, .field);
835 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
836 return sema.failWithOwnedErrorMsg(&block, msg: {
837 const msg = try sema.errMsg(field_ty_src, "cannot directly embed opaque type '{f}' in union", .{field_ty.fmt(pt)});
838 errdefer msg.destroy(gpa);
839 try sema.errNote(field_ty_src, msg, "opaque types have unknown size", .{});
840 try sema.addDeclaredHereNote(msg, field_ty);
841 break :msg msg;
842 });
843 }
844 if (union_obj.layout == .@"extern" and !field_ty.validateExtern(.union_field, zcu)) {
845 return sema.failWithOwnedErrorMsg(&block, msg: {
846 const msg = try sema.errMsg(field_ty_src, "extern unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
847 errdefer msg.destroy(gpa);
848 try sema.explainWhyTypeIsNotExtern(msg, field_ty_src, field_ty, .union_field);
849 try sema.addDeclaredHereNote(msg, field_ty);
850 break :msg msg;
851 });
852 }
853 }
854
855 // Fields are okay. Now we need to resolve the union's overall layout (size, alignment, etc).
856 var payload_align: Alignment = .@"1";
857 var payload_size: u64 = 0;
858 var possible_tags: u32 = 0;
859 var payload_has_comptime_state = false;
860 for (0..union_obj.field_types.len) |field_idx| {
861 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_idx]);
862 const field_align: Alignment = a: {
863 if (union_obj.field_aligns.len != 0) {
864 const a = union_obj.field_aligns.get(ip)[field_idx];
865 if (a != .none) break :a a;
866 }
867 break :a field_ty.abiAlignment(zcu);
868 };
869 payload_align = payload_align.maxStrict(field_align);
870 payload_size = @max(payload_size, field_ty.abiSize(zcu));
871
872 switch (field_ty.classify(zcu)) {
873 .no_possible_value => {}, // uninstantiable field has no effect
874 .one_possible_value, .runtime => {
875 possible_tags += 1;
876 },
877 .partially_comptime, .fully_comptime => {
878 possible_tags += 1;
879 payload_has_comptime_state = true;
880 },
881 }
882 }
883
884 // Uninstantiable `extern union`s don't make sense; disallow them.
885 if (possible_tags == 0 and union_obj.layout != .auto) {
886 // Field types are all extern, so not NPV; thus zero possible tags means no tags at all.
887 assert(union_obj.field_types.len == 0);
888 return sema.fail(&block, union_ty.srcLoc(zcu), "extern union has no fields", .{});
889 }
890
891 // We only need a runtime tag if there are multiple possible active fields *and* the union is
892 // not going to be comptime-only. Even if there are still runtime bits in the payload, the tag
893 // does not require runtime bits in a comptime-only union, because it is impossible to get a
894 // pointer to a union's tag.
895 const has_runtime_tag = switch (possible_tags) {
896 0, 1 => false,
897 else => union_obj.tag_usage != .none and !payload_has_comptime_state,
898 };
899
900 const class: Type.Class = class: {
901 if (possible_tags == 0) {
902 break :class .no_possible_value;
903 }
904 if (payload_has_comptime_state) {
905 break :class if (payload_size > 0) .partially_comptime else .fully_comptime;
906 }
907 const have_runtime_bits = has_runtime_tag or payload_size > 0;
908 break :class if (have_runtime_bits) .runtime else .one_possible_value;
909 };
910
911 const size: u64, const padding: u64, const alignment: Alignment = layout: {
912 if (!has_runtime_tag) {
913 break :layout .{ payload_align.forward(payload_size), 0, payload_align };
914 }
915 const tag_align = enum_tag_ty.abiAlignment(zcu);
916 const tag_size = enum_tag_ty.abiSize(zcu);
917 // The layout will either be (tag, payload, padding) or (payload, tag, padding) depending on
918 // which has larger alignment. So the overall size is just the tag and payload sizes, added,
919 // and padded to the larger alignment.
920 const alignment = tag_align.maxStrict(payload_align);
921 const unpadded_size = tag_size + payload_size;
922 const size = alignment.forward(unpadded_size);
923 break :layout .{ size, size - unpadded_size, alignment };
924 };
925
926 if (class == .no_possible_value or class == .one_possible_value) {
927 assert(size == 0);
928 assert(padding == 0);
929 }
930
931 const casted_size = std.math.cast(u32, size) orelse return sema.fail(
932 &block,
933 union_ty.srcLoc(zcu),
934 "union layout requires size {d}, this compiler implementation supports up to {d}",
935 .{ size, std.math.maxInt(u32) },
936 );
937 ip.resolveUnionLayout(
938 io,
939 union_ty.toIntern(),
940 enum_tag_ty.toIntern(),
941 class,
942 has_runtime_tag,
943 casted_size,
944 @intCast(padding), // okay because padding is no greater than size
945 alignment,
946 );
947}
948fn failUnionFieldMismatch(sema: *Sema, block: *Block, union_field_names: []const InternPool.NullTerminatedString, enum_tag_ty: Type, enum_obj: *const InternPool.LoadedEnumType) CompileError {
949 const pt = sema.pt;
950 const zcu = pt.zcu;
951 const comp = zcu.comp;
952 const gpa = comp.gpa;
953 const ip = &zcu.intern_pool;
954 const enum_to_union_map = try sema.arena.alloc(?u32, enum_obj.field_names.len);
955 @memset(enum_to_union_map, null);
956 for (union_field_names, 0..) |field_name, union_field_index| {
957 if (enum_obj.nameIndex(ip, field_name)) |enum_field_index| {
958 enum_to_union_map[enum_field_index] = @intCast(union_field_index);
959 continue;
960 }
961 const union_field_src = block.src(.{ .container_field_name = @intCast(union_field_index) });
962 return sema.failWithOwnedErrorMsg(block, msg: {
963 const msg = try sema.errMsg(union_field_src, "no field named '{f}' in enum '{f}'", .{ field_name.fmt(ip), enum_tag_ty.fmt(pt) });
964 errdefer msg.destroy(gpa);
965 try sema.addDeclaredHereNote(msg, enum_tag_ty);
966 break :msg msg;
967 });
968 }
969 for (enum_to_union_map, 0..) |union_field_index, enum_field_index| {
970 if (union_field_index != null) continue;
971 const field_name_ip = enum_obj.field_names.get(ip)[enum_field_index];
972 const enum_field_src: LazySrcLoc = .{
973 .base_node_inst = enum_tag_ty.typeDeclInstAllowGeneratedTag(zcu).?,
974 .offset = .{ .container_field_name = @intCast(enum_field_index) },
975 };
976 return sema.failWithOwnedErrorMsg(block, msg: {
977 const msg = try sema.errMsg(block.nodeOffset(.zero), "enum field '{f}' missing from union", .{field_name_ip.fmt(ip)});
978 errdefer msg.destroy(gpa);
979 try sema.errNote(enum_field_src, msg, "enum field here", .{});
980 break :msg msg;
981 });
982 }
983 // The only problem is the field ordering.
984 for (enum_to_union_map, 0..) |union_field_index, enum_field_index| {
985 if (union_field_index.? == enum_field_index) continue;
986 const field_name = enum_obj.field_names.get(ip)[enum_field_index];
987 const union_field_src = block.src(.{ .container_field_name = union_field_index.? });
988 const enum_field_src: LazySrcLoc = .{
989 .base_node_inst = enum_tag_ty.typeDeclInstAllowGeneratedTag(zcu).?,
990 .offset = .{ .container_field_name = @intCast(enum_field_index) },
991 };
992 return sema.failWithOwnedErrorMsg(block, msg: {
993 const msg = try sema.errMsg(block.nodeOffset(.zero), "union field order does not match tag enum field order", .{});
994 errdefer msg.destroy(gpa);
995 try sema.errNote(union_field_src, msg, "union field '{f}' is index {d}", .{ field_name.fmt(ip), union_field_index.? });
996 try sema.errNote(enum_field_src, msg, "enum field '{f}' is index {d}", .{ field_name.fmt(ip), enum_field_index });
997 break :msg msg;
998 });
999 }
1000 unreachable; // we already determined that *something* is wrong
1001}
1002fn resolvePackedUnionLayout(
1003 sema: *Sema,
1004 block: *Block,
1005 union_ty: Type,
1006 union_obj: *const InternPool.LoadedUnionType,
1007 enum_tag_ty: Type,
1008) CompileError!void {
1009 const pt = sema.pt;
1010 const zcu = pt.zcu;
1011 const comp = zcu.comp;
1012 const io = comp.io;
1013 const gpa = comp.gpa;
1014 const ip = &zcu.intern_pool;
1015
1016 // Uninstantiable `packed union`s don't make sense; disallow them.
1017 if (union_obj.field_types.len == 0) {
1018 return sema.fail(block, union_ty.srcLoc(zcu), "packed union has no fields", .{});
1019 }
1020
1021 // Resolve the layout of all fields, and check their types are allowed.
1022 for (union_obj.field_types.get(ip), 0..) |field_ty_ip, field_index| {
1023 const field_ty: Type = .fromInterned(field_ty_ip);
1024 assert(!field_ty.isGenericPoison());
1025 const field_ty_src = block.src(.{ .container_field_type = @intCast(field_index) });
1026 try sema.ensureLayoutResolved(field_ty, field_ty_src, .field);
1027 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
1028 return sema.failWithOwnedErrorMsg(block, msg: {
1029 const msg = try sema.errMsg(field_ty_src, "cannot directly embed opaque type '{f}' in union", .{field_ty.fmt(pt)});
1030 errdefer msg.destroy(gpa);
1031 try sema.errNote(field_ty_src, msg, "opaque types have unknown size", .{});
1032 try sema.addDeclaredHereNote(msg, field_ty);
1033 break :msg msg;
1034 });
1035 }
1036 if (field_ty.unpackable(zcu)) |reason| return sema.failWithOwnedErrorMsg(block, msg: {
1037 const msg = try sema.errMsg(field_ty_src, "packed unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
1038 errdefer msg.destroy(gpa);
1039 try sema.explainWhyTypeIsUnpackable(msg, field_ty_src, reason);
1040 break :msg msg;
1041 });
1042 assert(!field_ty.comptimeOnly(zcu)); // packable types are not comptime-only
1043 }
1044
1045 const explicit_backing_int_ty: ?Type = if (union_obj.is_reified) ty: {
1046 switch (union_obj.packed_backing_mode) {
1047 .explicit => break :ty .fromInterned(union_obj.packed_backing_int_type),
1048 .auto => break :ty null,
1049 }
1050 } else ty: {
1051 const zir_index = union_obj.zir_index.resolve(ip).?;
1052 const zir_union = sema.code.getUnionDecl(zir_index);
1053 const backing_int_type_body = zir_union.arg_type_body orelse {
1054 break :ty null; // inferred backing type
1055 };
1056 // Explicitly specified, so evaluate the backing int type expression.
1057 const backing_int_type_src = block.src(.container_arg);
1058 block.comptime_reason = .{ .reason = .{
1059 .src = backing_int_type_src,
1060 .r = .{ .simple = .packed_union_backing_int_type },
1061 } };
1062 const type_ref = try sema.resolveInlineBody(block, backing_int_type_body, zir_index);
1063 break :ty try sema.analyzeAsType(block, backing_int_type_src, .packed_union_backing_int_type, type_ref);
1064 };
1065
1066 // Finally, either validate or infer the backing int type.
1067 const backing_int_ty: Type = if (explicit_backing_int_ty) |backing_ty| ty: {
1068 if (backing_ty.zigTypeTag(zcu) != .int) return sema.fail(
1069 block,
1070 block.src(.container_arg),
1071 "expected backing integer type, found '{f}'",
1072 .{backing_ty.fmt(pt)},
1073 );
1074 const backing_int_bits = backing_ty.intInfo(zcu).bits;
1075 for (union_obj.field_types.get(ip), 0..) |field_type_ip, field_idx| {
1076 const field_type: Type = .fromInterned(field_type_ip);
1077 const field_bits = field_type.bitSize(zcu);
1078 if (field_bits != backing_int_bits) return sema.failWithOwnedErrorMsg(block, msg: {
1079 const field_ty_src = block.src(.{ .container_field_type = @intCast(field_idx) });
1080 const msg = try sema.errMsg(field_ty_src, "field bit width does not match backing integer", .{});
1081 errdefer msg.destroy(gpa);
1082 try sema.errNote(field_ty_src, msg, "field type '{f}' has bit width '{d}'", .{ field_type.fmt(pt), field_bits });
1083 try sema.errNote(
1084 block.src(.container_arg),
1085 msg,
1086 "backing integer '{f}' has bit width '{d}'",
1087 .{ backing_ty.fmt(pt), backing_int_bits },
1088 );
1089 try sema.errNote(field_ty_src, msg, "all fields in a packed union must have the same bit width", .{});
1090 break :msg msg;
1091 });
1092 }
1093 break :ty backing_ty;
1094 } else ty: {
1095 const field_types = union_obj.field_types.get(ip);
1096 const first_field_type: Type = .fromInterned(field_types[0]);
1097 const first_field_bits = first_field_type.bitSize(zcu);
1098 for (field_types[1..], 1..) |field_type_ip, field_idx| {
1099 const field_type: Type = .fromInterned(field_type_ip);
1100 const field_bits = field_type.bitSize(zcu);
1101 if (field_bits != first_field_bits) return sema.failWithOwnedErrorMsg(block, msg: {
1102 const first_field_ty_src = block.src(.{ .container_field_type = 0 });
1103 const field_ty_src = block.src(.{ .container_field_type = @intCast(field_idx) });
1104 const msg = try sema.errMsg(field_ty_src, "field bit width does not match earlier field", .{});
1105 errdefer msg.destroy(gpa);
1106 try sema.errNote(field_ty_src, msg, "field type '{f}' has bit width '{d}'", .{ field_type.fmt(pt), field_bits });
1107 try sema.errNote(first_field_ty_src, msg, "other field type '{f}' has bit width '{d}'", .{ first_field_type.fmt(pt), first_field_bits });
1108 try sema.errNote(field_ty_src, msg, "all fields in a packed union must have the same bit width", .{});
1109 break :msg msg;
1110 });
1111 }
1112 const backing_int_bits = std.math.cast(u16, first_field_bits) orelse return sema.fail(
1113 block,
1114 union_ty.srcLoc(zcu),
1115 "packed union bit width '{d}' exceeds maximum bit width of 65535",
1116 .{first_field_bits},
1117 );
1118 break :ty try pt.intType(.unsigned, backing_int_bits);
1119 };
1120 ip.resolvePackedUnionLayout(
1121 io,
1122 union_ty.toIntern(),
1123 enum_tag_ty.toIntern(),
1124 backing_int_ty.toIntern(),
1125 );
1126}
1127
1128pub fn resolveEnumLayout(sema: *Sema, enum_ty: Type) CompileError!void {
1129 const pt = sema.pt;
1130 const zcu = pt.zcu;
1131 const comp = zcu.comp;
1132 const io = comp.io;
1133 const gpa = comp.gpa;
1134 const ip = &zcu.intern_pool;
1135
1136 assert(sema.owner.unwrap().type_layout == enum_ty.toIntern());
1137
1138 const enum_obj = ip.loadEnumType(enum_ty.toIntern());
1139 assert(enum_obj.want_layout);
1140
1141 const maybe_parent_union_obj: ?InternPool.LoadedUnionType = un: {
1142 if (enum_obj.owner_union == .none) break :un null;
1143 break :un ip.loadUnionType(enum_obj.owner_union);
1144 };
1145
1146 const tracked_inst = enum_obj.zir_index.unwrap() orelse maybe_parent_union_obj.?.zir_index;
1147 const zir_index = tracked_inst.resolve(ip) orelse return error.AnalysisFail;
1148
1149 var block: Block = .{
1150 .parent = null,
1151 .sema = sema,
1152 .namespace = enum_obj.namespace,
1153 .instructions = .empty,
1154 .inlining = null,
1155 .comptime_reason = undefined, // always set before using `block`
1156 .src_base_inst = tracked_inst,
1157 .type_name_ctx = enum_obj.name,
1158 };
1159 defer block.instructions.deinit(gpa);
1160
1161 // There may be old field names in the map from a previous update.
1162 enum_obj.field_name_map.get(ip).clearRetainingCapacity();
1163
1164 if (maybe_parent_union_obj) |*union_obj| {
1165 if (union_obj.is_reified) {
1166 // In the case of reification, the union stores the field names, just for us to copy.
1167 @memcpy(enum_obj.field_names.get(ip), union_obj.reified_field_names.get(ip));
1168 // The list of field names is now populated, but we haven't checked for duplicates yet,
1169 // nor have we populated the hash map.
1170 for (0..enum_obj.field_names.len) |field_index| {
1171 const name = enum_obj.field_names.get(ip)[field_index];
1172 if (ip.addFieldName(enum_obj.field_names, enum_obj.field_name_map, name)) |prev_field_index| {
1173 return sema.failWithOwnedErrorMsg(&block, msg: {
1174 const src = block.builtinCallArgSrc(.zero, 2);
1175 const msg = try sema.errMsg(src, "duplicate union field '{f}' at index '{d}", .{ name.fmt(ip), field_index });
1176 errdefer msg.destroy(gpa);
1177 try sema.errNote(src, msg, "previous field at index '{d}'", .{prev_field_index});
1178 break :msg msg;
1179 });
1180 }
1181 }
1182 } else {
1183 // Generated tag enums for declared unions do not yet have field names populated. It is
1184 // our job to populate them now.
1185 try sema.declareDependency(.{ .src_hash = union_obj.zir_index });
1186 const zir_union = sema.code.getUnionDecl(zir_index);
1187 for (zir_union.field_names) |zir_field_name| {
1188 const name_slice = sema.code.nullTerminatedString(zir_field_name);
1189 const name = try ip.getOrPutString(gpa, io, pt.tid, name_slice, .no_embedded_nulls);
1190 assert(ip.addFieldName(enum_obj.field_names, enum_obj.field_name_map, name) == null); // AstGen validated this for us
1191 }
1192 }
1193 } else {
1194 if (enum_obj.is_reified) {
1195 // The field names are populated, but we haven't checked for duplicates (nor populated the map) yet.
1196 for (0..enum_obj.field_names.len) |field_index| {
1197 const name = enum_obj.field_names.get(ip)[field_index];
1198 if (ip.addFieldName(enum_obj.field_names, enum_obj.field_name_map, name)) |prev_field_index| {
1199 return sema.failWithOwnedErrorMsg(&block, msg: {
1200 const src = block.builtinCallArgSrc(.zero, 2);
1201 const msg = try sema.errMsg(src, "duplicate enum field '{f}' at index '{d}'", .{ name.fmt(ip), field_index });
1202 errdefer msg.destroy(gpa);
1203 try sema.errNote(src, msg, "previous field at index '{d}'", .{prev_field_index});
1204 break :msg msg;
1205 });
1206 }
1207 }
1208 } else {
1209 // Declared enums do not yet have field names populated. It is our job to populate them now.
1210 try sema.declareDependency(.{ .src_hash = enum_obj.zir_index.unwrap().? });
1211 const zir_enum = sema.code.getEnumDecl(zir_index);
1212 for (zir_enum.field_names) |zir_field_name| {
1213 const name_slice = sema.code.nullTerminatedString(zir_field_name);
1214 const name = try ip.getOrPutString(gpa, io, pt.tid, name_slice, .no_embedded_nulls);
1215 assert(ip.addFieldName(enum_obj.field_names, enum_obj.field_name_map, name) == null); // AstGen validated this for us
1216 }
1217 }
1218 }
1219
1220 // Field names populated; now deal with the backing integer type. If explicitly provided,
1221 // validate it; otherwise, infer it.
1222
1223 const explicit_int_tag_ty: ?Type = if (enum_obj.is_reified) ty: {
1224 break :ty switch (enum_obj.int_tag_mode) {
1225 .explicit => .fromInterned(enum_obj.int_tag_type),
1226 .auto => null,
1227 };
1228 } else if (maybe_parent_union_obj) |*union_obj| ty: {
1229 if (union_obj.is_reified) {
1230 // Reification has no equivalent of 'union(enum(T))'.
1231 break :ty null;
1232 }
1233 const zir_union = sema.code.getUnionDecl(zir_index);
1234 if (zir_union.kind != .tagged_enum_explicit) {
1235 break :ty null; // int tag type will be inferred
1236 }
1237 // Explicitly specified, so evaluate the int tag type expression.
1238 const tag_type_body = zir_union.arg_type_body.?;
1239 const tag_type_src = block.src(.container_arg);
1240 block.comptime_reason = .{ .reason = .{
1241 .src = tag_type_src,
1242 .r = .{ .simple = .enum_int_tag_type },
1243 } };
1244 const type_ref = try sema.resolveInlineBody(&block, tag_type_body, zir_index);
1245 break :ty try sema.analyzeAsType(&block, tag_type_src, .enum_int_tag_type, type_ref);
1246 } else ty: {
1247 const zir_enum = sema.code.getEnumDecl(zir_index);
1248 const tag_type_body = zir_enum.tag_type_body orelse {
1249 break :ty null; // int tag type will be inferred
1250 };
1251 // Explicitly specified, so evaluate the int tag type expression.
1252 const tag_type_src = block.src(.container_arg);
1253 block.comptime_reason = .{ .reason = .{
1254 .src = tag_type_src,
1255 .r = .{ .simple = .enum_int_tag_type },
1256 } };
1257 const type_ref = try sema.resolveInlineBody(&block, tag_type_body, zir_index);
1258 break :ty try sema.analyzeAsType(&block, tag_type_src, .enum_int_tag_type, type_ref);
1259 };
1260 const int_tag_ty: Type = if (explicit_int_tag_ty) |int_tag_ty| ty: {
1261 if (int_tag_ty.zigTypeTag(zcu) != .int) return sema.fail(
1262 &block,
1263 block.src(.container_arg),
1264 "expected integer tag type, found '{f}'",
1265 .{int_tag_ty.fmt(pt)},
1266 );
1267 break :ty int_tag_ty;
1268 } else ty: {
1269 // Infer the int tag type from the field count
1270 const bits = Type.smallestUnsignedBits(enum_obj.field_names.len -| 1);
1271 break :ty try pt.intType(.unsigned, bits);
1272 };
1273
1274 ip.resolveEnumLayout(io, enum_ty.toIntern(), int_tag_ty.toIntern());
1275
1276 // Finally, deal with field values. For declared types we need to analyze the expressions, while
1277 // reified types already have them populated; but either way, we need to populate the hash map
1278 // (and validate the values along the way).
1279
1280 // We'll populate this map.
1281 const field_value_map = enum_obj.field_value_map.unwrap() orelse {
1282 // The enum is auto-numbered with an inferred tag type. We know that the tag type generated
1283 // earlier is sufficient for the number of fields, so we have nothing more to do.
1284 assert(enum_obj.int_tag_mode == .auto);
1285 return;
1286 };
1287
1288 // There may be old field values in here from a previous update.
1289 field_value_map.get(ip).clearRetainingCapacity();
1290
1291 // Map the enum (or union) decl instruction to provide the tag type as the result type
1292 try sema.inst_map.ensureSpaceForInstructions(gpa, &.{zir_index});
1293 sema.inst_map.putAssumeCapacity(zir_index, .fromIntern(int_tag_ty.toIntern()));
1294 defer assert(sema.inst_map.remove(zir_index));
1295
1296 // First, populate any explicitly provided values. This is the part that actually depends on
1297 // the ZIR, and hence depends on whether this is a declared or generated enum. If any explicit
1298 // value is straight-up invalid, we'll emit an error here.
1299 if (maybe_parent_union_obj) |union_obj| {
1300 if (union_obj.is_reified) {
1301 // Generated tag type for reified union; values already populated.
1302 } else {
1303 // Generated tag type for declared union; evaluate the expressions given in the union declaration.
1304 const zir_union = sema.code.getUnionDecl(zir_index);
1305 var field_it = zir_union.iterateFields();
1306 while (field_it.next()) |zir_field| {
1307 const field_val_src = block.src(.{ .container_field_value = zir_field.idx });
1308 block.comptime_reason = .{ .reason = .{
1309 .src = field_val_src,
1310 .r = .{ .simple = .enum_field_values },
1311 } };
1312 const value_body = zir_field.value_body orelse {
1313 enum_obj.field_values.get(ip)[zir_field.idx] = .none;
1314 continue;
1315 };
1316 const uncoerced = try sema.resolveInlineBody(&block, value_body, zir_index);
1317 const coerced = try sema.coerce(&block, int_tag_ty, uncoerced, field_val_src);
1318 const val = try sema.resolveConstValue(&block, field_val_src, coerced, null);
1319 enum_obj.field_values.get(ip)[zir_field.idx] = val.toIntern();
1320 }
1321 }
1322 } else if (enum_obj.is_reified) {
1323 // Reified enum; values already populated.
1324 } else {
1325 // Declared enum; evaluate the expressions given in the enum declaration.
1326 const zir_enum = sema.code.getEnumDecl(zir_index);
1327 var field_it = zir_enum.iterateFields();
1328 while (field_it.next()) |zir_field| {
1329 const field_val_src = block.src(.{ .container_field_value = zir_field.idx });
1330 block.comptime_reason = .{ .reason = .{
1331 .src = field_val_src,
1332 .r = .{ .simple = .enum_field_values },
1333 } };
1334 const value_body = zir_field.value_body orelse {
1335 enum_obj.field_values.get(ip)[zir_field.idx] = .none;
1336 continue;
1337 };
1338 const uncoerced = try sema.resolveInlineBody(&block, value_body, zir_index);
1339 const coerced = try sema.coerce(&block, int_tag_ty, uncoerced, field_val_src);
1340 const val = try sema.resolveConstDefinedValue(&block, field_val_src, coerced, null);
1341 enum_obj.field_values.get(ip)[zir_field.idx] = val.toIntern();
1342 }
1343 }
1344
1345 // Explicit values are set. Now we'll go through the whole array and figure out the final
1346 // field values. This is also where we'll detect duplicates.
1347
1348 for (0..enum_obj.field_names.len) |field_idx| {
1349 const field_val_src = block.src(.{ .container_field_value = @intCast(field_idx) });
1350 // If the field value was not specified, compute the implicit value.
1351 const field_val = val: {
1352 const explicit_val = enum_obj.field_values.get(ip)[field_idx];
1353 if (explicit_val != .none) {
1354 assert(ip.typeOf(explicit_val) == int_tag_ty.toIntern());
1355 break :val explicit_val;
1356 }
1357 if (field_idx == 0) {
1358 // Implicit value is 0, which is valid for every integer type.
1359 const val = (try pt.intValue(int_tag_ty, 0)).toIntern();
1360 enum_obj.field_values.get(ip)[field_idx] = val;
1361 break :val val;
1362 }
1363 // Implicit non-initial value: take the previous field value and add one.
1364 const prev_field_val: Value = .fromInterned(enum_obj.field_values.get(ip)[field_idx - 1]);
1365 const result = try arith.incrementDefinedInt(sema, int_tag_ty, prev_field_val);
1366 if (result.overflow) return sema.fail(
1367 &block,
1368 field_val_src,
1369 "enum tag value '{f}' too large for type '{f}'",
1370 .{ result.val.fmtValueSema(pt, sema), int_tag_ty.fmt(pt) },
1371 );
1372 const val = result.val.toIntern();
1373 enum_obj.field_values.get(ip)[field_idx] = val;
1374 break :val val;
1375 };
1376 if (ip.addFieldTagValue(enum_obj.field_values, field_value_map, field_val)) |prev_field_index| {
1377 return sema.failWithOwnedErrorMsg(&block, msg: {
1378 const prev_field_val_src = block.src(.{ .container_field_value = prev_field_index });
1379 const msg = try sema.errMsg(field_val_src, "enum tag value '{f}' for field '{f}' already taken", .{
1380 Value.fromInterned(field_val).fmtValueSema(pt, sema),
1381 enum_obj.field_names.get(ip)[field_idx].fmt(ip),
1382 });
1383 errdefer msg.destroy(gpa);
1384 try sema.errNote(prev_field_val_src, msg, "previous occurrence in field '{f}'", .{
1385 enum_obj.field_names.get(ip)[prev_field_index].fmt(ip),
1386 });
1387 break :msg msg;
1388 });
1389 }
1390 }
1391
1392 if (enum_obj.nonexhaustive) {
1393 const fields_len = enum_obj.field_names.len;
1394 if (fields_len >= 1 and std.math.log2_int(u64, fields_len) == int_tag_ty.bitSize(zcu)) {
1395 return sema.fail(&block, block.nodeOffset(.zero), "non-exhaustive enum specifies every value", .{});
1396 }
1397 }
1398}
src/Type.zig+1641-2419
......@@ -12,12 +12,10 @@ const Target = std.Target;
1212const Zcu = @import("Zcu.zig");
1313const log = std.log.scoped(.Type);
1414const target_util = @import("target.zig");
15const Sema = @import("Sema.zig");
1615const InternPool = @import("InternPool.zig");
1716const Alignment = InternPool.Alignment;
1817const Zir = std.zig.Zir;
1918const Type = @This();
20const SemaError = Zcu.SemaError;
2119
2220ip_index: InternPool.Index,
2321
......@@ -25,14 +23,288 @@ pub fn zigTypeTag(ty: Type, zcu: *const Zcu) std.builtin.TypeId {
2523 return zcu.intern_pool.zigTypeTag(ty.toIntern());
2624}
2725
28pub fn baseZigTypeTag(self: Type, mod: *Zcu) std.builtin.TypeId {
29 return switch (self.zigTypeTag(mod)) {
30 .error_union => self.errorUnionPayload(mod).baseZigTypeTag(mod),
31 .optional => {
32 return self.optionalChild(mod).baseZigTypeTag(mod);
26/// Every type is a member of exactly one "class" which determines:
27/// * whether values of the type can exist at all
28/// * whether values of the type can be runtime-knwon
29/// * whether the type is considered comptime-only
30/// * whether the type has runtime bits (nonzero ABI size)
31pub const Class = enum(u3) {
32 /// Values of this type cannot exist because the type semantically has no values. Attempting to
33 /// create a value of this type (such as by coercing `undefined`) always emits a compile error.
34 ///
35 /// Not comptime-only. No runtime bits, i.e. ABI size is 0.
36 ///
37 /// Exhaustive list of no-possible-value ("NPV") types:
38 /// * `noreturn`
39 /// * `anyopaque`, and any `opaque` type
40 /// * `[n]T` where `n` is non-zero and `T` is NPV
41 /// * Any tuple where at least one non-`comptime` field has an NPV type
42 /// * Any enum whose backing type is `noreturn`
43 /// * Any struct where at least one non-`comptime` field has an NPV type
44 /// * Any union where every field has an NPV type (including unions with no fields)
45 /// * If the union would typically have a runtime tag, even if that tag would have runtime
46 /// bits, the union type is still NPV; the runtime tag is effectively omitted.
47 no_possible_value,
48
49 /// Values of this type are always comptime-known because there is only one value inhabiting the
50 /// type. This matches the colloquial understanding of a "zero-bit type".
51 ///
52 /// Not comptime-only (although always comptime-known). No runtime bits, i.e. ABI size is 0.
53 ///
54 /// Exhaustive list of one-possible-value ("OPV") types:
55 /// * `void`
56 /// * `u0`, `i0`
57 /// * `[0]T` for any `T`
58 /// * `[n]T` where `T` is OPV
59 /// * `[n:s]T` where `T` is OPV
60 /// * `@Vector(0, T)` for any `T`
61 /// * `@Vector(n, T)` where `T` is OPV
62 /// * Any tuple where every non-`comptime` field has an OPV type (including tuples with no fields)
63 /// * Any enum whose backing type is OPV
64 /// * Any struct where every non-`comptime` field has an OPV type (including structs with no fields)
65 /// * Any union with no runtime tag where all fields have OPV
66 /// * Any union where one field has an OPV type, and either:
67 /// * All other fields have NPV types (in this case, if there would be a runtime tag, it is omitted)
68 /// * All other fields have NPV or OPV types, and the union has no runtime tag
69 one_possible_value,
70
71 /// The type holds state (so it is neither NPV nor OPV), but contains no comptime-only state, so
72 /// values may be runtime-known.
73 ///
74 /// Not comptime-only. Has runtime bits, i.e. ABI size is non-zero.
75 ///
76 /// Most types which are typically used in Zig inhabit this class. For instance, all pointer
77 /// types, all integer types other than `u0` and `i0`, and most user-defined aggregates fall
78 /// into this category.
79 runtime,
80
81 /// The type holds state (so it is neither NPV nor OPV). Some, but not all, of the contained
82 /// state is comptime-only.
83 ///
84 /// Comptime-only. Has runtime bits, i.e. ABI size is non-zero.
85 ///
86 /// Partially-comptime types arise from aggregates (`struct`s, `union`s, or tuples) which have
87 /// some fields with fully-comptime types (such as `comptime_int`) and some fields with runtime
88 /// types (such as `u8`). Because the user may acquire pointers to these fields, pointers to the
89 /// embedded runtime state must be valid, so backends are required to lower the runtime state
90 /// within the type.
91 ///
92 /// Note that logically-runtime state which cannot be directly referenced by the user (such as
93 /// the enum tag of a tagged union type, or the "populated" bit of an optional type) does not
94 /// cause a type to be partially-comptime.
95 partially_comptime,
96
97 /// The type contains exclusively comptime-only state.
98 ///
99 /// Comptime-only. No runtime bits, i.e. ABI size is 0.
100 ///
101 /// Fully-comptime types arise from a handful of primitive fully-comptime types:
102 /// * `type`
103 /// * `comptime_int`
104 /// * `comptime_float`
105 /// * `@EnumLiteral()`
106 /// * `@TypeOf(null)`
107 /// * `@TypeOf(undefined)`
108 ///
109 /// Then, aggregates containing fully-comptime types may themselves be either fully-comptime or
110 /// partially-comptime; see the doc comment on `.partially_comptime` for details.
111 fully_comptime,
112};
113
114/// Returns the `Class` for the type `ty`. Asserts that the layout of `ty` is resolved.
115pub fn classify(start_ty: Type, zcu: *const Zcu) Class {
116 const ip = &zcu.intern_pool;
117
118 // We avoid recursion in most cases to make us more optimizer-friendly because this can be a
119 // very hot code path. The only case where recursion is necessary is tuples, so that case is
120 // outlined into a separate function; see `classifyTuple`.
121
122 var extra_states: enum { none, one, many } = .none;
123
124 var cur_ty = start_ty;
125 const base: Class = while (true) break switch (ip.indexToKey(cur_ty.toIntern())) {
126 .simple_type => |t| switch (t) {
127 .f16,
128 .f32,
129 .f64,
130 .f80,
131 .f128,
132 .usize,
133 .isize,
134 .c_char,
135 .c_short,
136 .c_ushort,
137 .c_int,
138 .c_uint,
139 .c_long,
140 .c_ulong,
141 .c_longlong,
142 .c_ulonglong,
143 .c_longdouble,
144 .bool,
145 .anyerror,
146 .adhoc_inferred_error_set,
147 => .runtime,
148
149 .anyopaque => .no_possible_value,
150
151 .type,
152 .comptime_int,
153 .comptime_float,
154 .enum_literal,
155 .null,
156 .undefined,
157 => .fully_comptime,
158
159 .void => .one_possible_value,
160 .noreturn => .no_possible_value,
161
162 .generic_poison => unreachable,
163 },
164
165 .error_set_type,
166 .inferred_error_set_type,
167 .ptr_type,
168 .anyframe_type,
169 => .runtime,
170
171 .func_type => .fully_comptime,
172
173 .opaque_type => .no_possible_value,
174
175 .error_union_type => |eu| {
176 extra_states = .many;
177 cur_ty = .fromInterned(eu.payload_type);
178 continue;
179 },
180
181 .int_type => |int| switch (int.bits) {
182 0 => .one_possible_value,
183 else => .runtime,
184 },
185 .array_type => |arr| {
186 if (arr.len == 0 and arr.sentinel == .none) break .one_possible_value;
187 cur_ty = .fromInterned(arr.child);
188 continue;
189 },
190 .vector_type => |vec| {
191 if (vec.len == 0) break .one_possible_value;
192 cur_ty = .fromInterned(vec.child);
193 continue;
194 },
195 .opt_type => |child_ty_ip| {
196 extra_states = switch (extra_states) {
197 .none => .one,
198 .one, .many => .many,
199 };
200 cur_ty = .fromInterned(child_ty_ip);
201 continue;
202 },
203 .tuple_type => |tuple| {
204 @branchHint(.unlikely);
205 break classifyTuple(tuple.types.get(ip), tuple.values.get(ip), zcu);
206 },
207 .struct_type => {
208 const struct_obj = ip.loadStructType(cur_ty.toIntern());
209 switch (struct_obj.layout) {
210 .auto, .@"extern" => {
211 zcu.assertUpToDate(.wrap(.{ .type_layout = cur_ty.toIntern() }));
212 break struct_obj.class;
213 },
214 .@"packed" => {
215 cur_ty = .fromInterned(struct_obj.packed_backing_int_type);
216 continue;
217 },
218 }
219 },
220 .union_type => {
221 const union_obj = ip.loadUnionType(cur_ty.toIntern());
222 switch (union_obj.layout) {
223 .auto, .@"extern" => {
224 zcu.assertUpToDate(.wrap(.{ .type_layout = cur_ty.toIntern() }));
225 break union_obj.class;
226 },
227 .@"packed" => {
228 cur_ty = .fromInterned(union_obj.packed_backing_int_type);
229 continue;
230 },
231 }
232 },
233 .enum_type => {
234 zcu.assertUpToDate(.wrap(.{ .type_layout = cur_ty.toIntern() }));
235 cur_ty = .fromInterned(ip.loadEnumType(cur_ty.toIntern()).int_tag_type);
236 continue;
33237 },
34 else => |t| t,
238
239 // values, not types
240 .undef,
241 .simple_value,
242 .variable,
243 .@"extern",
244 .func,
245 .int,
246 .err,
247 .error_union,
248 .enum_literal,
249 .enum_tag,
250 .float,
251 .ptr,
252 .slice,
253 .opt,
254 .aggregate,
255 .un,
256 .bitpack,
257 // memoization, not types
258 .memoized_call,
259 => unreachable,
35260 };
261
262 return switch (base) {
263 .runtime => .runtime, // extra states are irrelevant, we already have many!
264 .partially_comptime => .partially_comptime, // likewise
265 .fully_comptime => {
266 // We do not need to change to `.partially_comptime` here because the extra states do
267 // not necessarily require runtime bits. This is because Zig does not provide a way to
268 // take the address of the "is null" bit of an optional or the error set "inside" of an
269 // error union.
270 return .fully_comptime;
271 },
272
273 .no_possible_value => switch (extra_states) {
274 .none => .no_possible_value,
275 .one => .one_possible_value,
276 .many => .runtime,
277 },
278
279 .one_possible_value => switch (extra_states) {
280 .none => .one_possible_value,
281 .one, .many => .runtime,
282 },
283 };
284}
285/// This is a separate function to `classify` to avoid recursion in the main `classify` function,
286/// which can encourage the optimizer to e.g. inline `classify` where it would be beneficial.
287fn classifyTuple(types: []const InternPool.Index, values: []const InternPool.Index, zcu: *const Zcu) Class {
288 var has_runtime_state = false;
289 var has_comptime_state = false;
290 for (types, values) |field_ty, field_comptime_val| {
291 if (field_comptime_val != .none) continue;
292 switch (Type.fromInterned(field_ty).classify(zcu)) {
293 .no_possible_value => return .no_possible_value,
294 .one_possible_value => {},
295 .runtime => has_runtime_state = true,
296 .fully_comptime => has_comptime_state = true,
297 .partially_comptime => {
298 has_runtime_state = true;
299 has_comptime_state = true;
300 },
301 }
302 }
303 if (has_comptime_state) {
304 return if (has_runtime_state) .partially_comptime else .fully_comptime;
305 } else {
306 return if (has_runtime_state) .runtime else .one_possible_value;
307 }
36308}
37309
38310/// Asserts the type is resolved.
......@@ -44,7 +316,7 @@ pub fn isSelfComparable(ty: Type, zcu: *const Zcu, is_equality_cmp: bool) bool {
44316 .comptime_int,
45317 => true,
46318
47 .vector => ty.elemType2(zcu).isSelfComparable(zcu, is_equality_cmp),
319 .vector => ty.childType(zcu).isSelfComparable(zcu, is_equality_cmp),
48320
49321 .bool,
50322 .type,
......@@ -121,11 +393,7 @@ pub fn eql(a: Type, b: Type, zcu: *const Zcu) bool {
121393 return a.toIntern() == b.toIntern();
122394}
123395
124pub fn format(ty: Type, writer: *std.Io.Writer) !void {
125 _ = ty;
126 _ = writer;
127 @compileError("do not format types directly; use either ty.fmtDebug() or ty.fmt()");
128}
396pub const format = @compileError("do not format types directly; use either ty.fmtDebug() or ty.fmt()");
129397
130398pub const Formatter = std.fmt.Alt(Format, Format.default);
131399
......@@ -416,13 +684,13 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari
416684 .error_union,
417685 .enum_literal,
418686 .enum_tag,
419 .empty_enum_value,
420687 .float,
421688 .ptr,
422689 .slice,
423690 .opt,
424691 .aggregate,
425692 .un,
693 .bitpack,
426694 // memoization, not types
427695 .memoized_call,
428696 => unreachable,
......@@ -440,247 +708,41 @@ pub fn toIntern(ty: Type) InternPool.Index {
440708}
441709
442710pub fn toValue(self: Type) Value {
443 return Value.fromInterned(self.toIntern());
711 return .fromInterned(self.toIntern());
444712}
445713
446const RuntimeBitsError = SemaError || error{NeedLazy};
447
714/// Returns `true` if and only if the type takes up space in memory at runtime. This is also exactly
715/// whether or not the backend/linker needs to be sent values of this type to emit to the binary.
716///
717/// Types without runtime bits have an ABI size of 0; all other types have a non-zero ABI size. All
718/// types, regardless of whether they have runtime bits, have a non-zero ABI alignment.
719///
720/// Comptime-only types may still have runtime bits. For instance, `struct { a: u32, b: type }` is a
721/// comptime-only type, but it nonetheless has runtime bits and a runtime memory layout (where the
722/// field `b: type` is omitted). This is because a user may take a pointer to the field `a`, which
723/// must then be valid to use at runtime.
724///
725/// This function is a trivial wrapper around `classify`:
726///
727/// * Types with one possible value, such as `void`, or no possible value, such as `noreturn`, do
728/// not have runtime bits and have an ABI size of 0 because they simply contain no state.
729///
730/// * Types which are fully comptime, such as `type` and `comptime_int`, do not have runtime bits
731/// because they contain only comptime state. (This compiler implementation also currently makes
732/// types like `struct { x: comptime_int }` fully comptime, but that could change in the future if
733/// we start inserting hidden safety fields into them.)
734///
735/// * All other types contain some runtime state, so have runtime bits and a non-zero ABI size.
448736pub fn hasRuntimeBits(ty: Type, zcu: *const Zcu) bool {
449 return hasRuntimeBitsInner(ty, false, .eager, zcu, {}) catch unreachable;
450}
451
452pub fn hasRuntimeBitsSema(ty: Type, pt: Zcu.PerThread) SemaError!bool {
453 return hasRuntimeBitsInner(ty, false, .sema, pt.zcu, pt.tid) catch |err| switch (err) {
454 error.NeedLazy => unreachable, // this would require a resolve strat of lazy
455 else => |e| return e,
456 };
457}
458
459pub fn hasRuntimeBitsIgnoreComptime(ty: Type, zcu: *const Zcu) bool {
460 return hasRuntimeBitsInner(ty, true, .eager, zcu, {}) catch unreachable;
461}
462
463pub fn hasRuntimeBitsIgnoreComptimeSema(ty: Type, pt: Zcu.PerThread) SemaError!bool {
464 return hasRuntimeBitsInner(ty, true, .sema, pt.zcu, pt.tid) catch |err| switch (err) {
465 error.NeedLazy => unreachable, // this would require a resolve strat of lazy
466 else => |e| return e,
467 };
468}
469
470/// true if and only if the type takes up space in memory at runtime.
471/// There are two reasons a type will return false:
472/// * the type is a comptime-only type. For example, the type `type` itself.
473/// - note, however, that a struct can have mixed fields and only the non-comptime-only
474/// fields will count towards the ABI size. For example, `struct {T: type, x: i32}`
475/// hasRuntimeBits()=true and abiSize()=4
476/// * the type has only one possible value, making its ABI size 0.
477/// - an enum with an explicit tag type has the ABI size of the integer tag type,
478/// making it one-possible-value only if the integer tag type has 0 bits.
479/// When `ignore_comptime_only` is true, then types that are comptime-only
480/// may return false positives.
481pub fn hasRuntimeBitsInner(
482 ty: Type,
483 ignore_comptime_only: bool,
484 comptime strat: ResolveStratLazy,
485 zcu: strat.ZcuPtr(),
486 tid: strat.Tid(),
487) RuntimeBitsError!bool {
488 const ip = &zcu.intern_pool;
489 const io = zcu.comp.io;
490 return switch (ty.toIntern()) {
491 .empty_tuple_type => false,
492 else => switch (ip.indexToKey(ty.toIntern())) {
493 .int_type => |int_type| int_type.bits != 0,
494 .ptr_type => {
495 // Pointers to zero-bit types still have a runtime address; however, pointers
496 // to comptime-only types do not, with the exception of function pointers.
497 if (ignore_comptime_only) return true;
498 return switch (strat) {
499 .sema => {
500 const pt = strat.pt(zcu, tid);
501 return !try ty.comptimeOnlySema(pt);
502 },
503 .eager => !ty.comptimeOnly(zcu),
504 .lazy => error.NeedLazy,
505 };
506 },
507 .anyframe_type => true,
508 .array_type => |array_type| return array_type.lenIncludingSentinel() > 0 and
509 try Type.fromInterned(array_type.child).hasRuntimeBitsInner(ignore_comptime_only, strat, zcu, tid),
510 .vector_type => |vector_type| return vector_type.len > 0 and
511 try Type.fromInterned(vector_type.child).hasRuntimeBitsInner(ignore_comptime_only, strat, zcu, tid),
512 .opt_type => |child| {
513 const child_ty = Type.fromInterned(child);
514 if (child_ty.isNoReturn(zcu)) {
515 // Then the optional is comptime-known to be null.
516 return false;
517 }
518 if (ignore_comptime_only) return true;
519 return switch (strat) {
520 .sema => !try child_ty.comptimeOnlyInner(.sema, zcu, tid),
521 .eager => !child_ty.comptimeOnly(zcu),
522 .lazy => error.NeedLazy,
523 };
524 },
525 .error_union_type,
526 .error_set_type,
527 .inferred_error_set_type,
528 => true,
529
530 // These are function *bodies*, not pointers.
531 // They return false here because they are comptime-only types.
532 // Special exceptions have to be made when emitting functions due to
533 // this returning false.
534 .func_type => false,
535
536 .simple_type => |t| switch (t) {
537 .f16,
538 .f32,
539 .f64,
540 .f80,
541 .f128,
542 .usize,
543 .isize,
544 .c_char,
545 .c_short,
546 .c_ushort,
547 .c_int,
548 .c_uint,
549 .c_long,
550 .c_ulong,
551 .c_longlong,
552 .c_ulonglong,
553 .c_longdouble,
554 .bool,
555 .anyerror,
556 .adhoc_inferred_error_set,
557 .anyopaque,
558 => true,
559
560 // These are false because they are comptime-only types.
561 .void,
562 .type,
563 .comptime_int,
564 .comptime_float,
565 .noreturn,
566 .null,
567 .undefined,
568 .enum_literal,
569 => false,
570
571 .generic_poison => unreachable,
572 },
573 .struct_type => {
574 const struct_type = ip.loadStructType(ty.toIntern());
575 if (strat != .eager and struct_type.assumeRuntimeBitsIfFieldTypesWip(ip, io)) {
576 // In this case, we guess that hasRuntimeBits() for this type is true,
577 // and then later if our guess was incorrect, we emit a compile error.
578 return true;
579 }
580 switch (strat) {
581 .sema => try ty.resolveFields(strat.pt(zcu, tid)),
582 .eager => assert(struct_type.haveFieldTypes(ip)),
583 .lazy => if (!struct_type.haveFieldTypes(ip)) return error.NeedLazy,
584 }
585 for (0..struct_type.field_types.len) |i| {
586 if (struct_type.comptime_bits.getBit(ip, i)) continue;
587 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
588 if (try field_ty.hasRuntimeBitsInner(ignore_comptime_only, strat, zcu, tid))
589 return true;
590 } else {
591 return false;
592 }
593 },
594 .tuple_type => |tuple| {
595 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
596 if (val != .none) continue; // comptime field
597 if (try Type.fromInterned(field_ty).hasRuntimeBitsInner(
598 ignore_comptime_only,
599 strat,
600 zcu,
601 tid,
602 )) return true;
603 }
604 return false;
605 },
606
607 .union_type => {
608 const union_type = ip.loadUnionType(ty.toIntern());
609 const union_flags = union_type.flagsUnordered(ip);
610 switch (union_flags.runtime_tag) {
611 .none => if (strat != .eager) {
612 // In this case, we guess that hasRuntimeBits() for this type is true,
613 // and then later if our guess was incorrect, we emit a compile error.
614 if (union_type.assumeRuntimeBitsIfFieldTypesWip(ip, io)) return true;
615 },
616 .safety, .tagged => {},
617 }
618 switch (strat) {
619 .sema => try ty.resolveFields(strat.pt(zcu, tid)),
620 .eager => assert(union_flags.status.haveFieldTypes()),
621 .lazy => if (!union_flags.status.haveFieldTypes())
622 return error.NeedLazy,
623 }
624 switch (union_flags.runtime_tag) {
625 .none => {},
626 .safety, .tagged => {
627 const tag_ty = union_type.tagTypeUnordered(ip);
628 assert(tag_ty != .none); // tag_ty should have been resolved above
629 if (try Type.fromInterned(tag_ty).hasRuntimeBitsInner(
630 ignore_comptime_only,
631 strat,
632 zcu,
633 tid,
634 )) {
635 return true;
636 }
637 },
638 }
639 for (0..union_type.field_types.len) |field_index| {
640 const field_ty = Type.fromInterned(union_type.field_types.get(ip)[field_index]);
641 if (try field_ty.hasRuntimeBitsInner(ignore_comptime_only, strat, zcu, tid))
642 return true;
643 } else {
644 return false;
645 }
646 },
647
648 .opaque_type => true,
649 .enum_type => Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).hasRuntimeBitsInner(
650 ignore_comptime_only,
651 strat,
652 zcu,
653 tid,
654 ),
655
656 // values, not types
657 .undef,
658 .simple_value,
659 .variable,
660 .@"extern",
661 .func,
662 .int,
663 .err,
664 .error_union,
665 .enum_literal,
666 .enum_tag,
667 .empty_enum_value,
668 .float,
669 .ptr,
670 .slice,
671 .opt,
672 .aggregate,
673 .un,
674 // memoization, not types
675 .memoized_call,
676 => unreachable,
677 },
737 return switch (ty.classify(zcu)) {
738 .no_possible_value, .one_possible_value, .fully_comptime => false,
739 .runtime, .partially_comptime => true,
678740 };
679741}
680742
681/// true if and only if the type has a well-defined memory layout
682/// readFrom/writeToMemory are supported only for types with a well-
683/// defined memory layout
743/// Returns `true` iff the memory layout of `ty` is defined by the Zig language specification.
744///
745/// Does not require `ty` to be resolved.
684746pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {
685747 const ip = &zcu.intern_pool;
686748 return switch (ip.indexToKey(ty.toIntern())) {
......@@ -737,17 +799,17 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {
737799 .generic_poison,
738800 => false,
739801 },
740 .struct_type => ip.loadStructType(ty.toIntern()).layout != .auto,
741 .union_type => {
742 const union_type = ip.loadUnionType(ty.toIntern());
743 return switch (union_type.flagsUnordered(ip).runtime_tag) {
744 .none, .safety => union_type.flagsUnordered(ip).layout != .auto,
745 .tagged => false,
746 };
802 .struct_type => switch (ip.loadStructType(ty.toIntern()).layout) {
803 .auto => false,
804 .@"extern", .@"packed" => true,
805 },
806 .union_type => switch (ip.loadUnionType(ty.toIntern()).layout) {
807 .auto => false,
808 .@"extern", .@"packed" => true,
747809 },
748 .enum_type => switch (ip.loadEnumType(ty.toIntern()).tag_mode) {
810 .enum_type => switch (ip.loadEnumType(ty.toIntern()).int_tag_mode) {
811 .explicit => true,
749812 .auto => false,
750 .explicit, .nonexhaustive => true,
751813 },
752814
753815 // values, not types
......@@ -761,86 +823,88 @@ pub fn hasWellDefinedLayout(ty: Type, zcu: *const Zcu) bool {
761823 .error_union,
762824 .enum_literal,
763825 .enum_tag,
764 .empty_enum_value,
765826 .float,
766827 .ptr,
767828 .slice,
768829 .opt,
769830 .aggregate,
770831 .un,
832 .bitpack,
771833 // memoization, not types
772834 .memoized_call,
773835 => unreachable,
774836 };
775837}
776838
777pub fn fnHasRuntimeBits(ty: Type, zcu: *Zcu) bool {
778 return ty.fnHasRuntimeBitsInner(.normal, zcu, {}) catch unreachable;
779}
780
781pub fn fnHasRuntimeBitsSema(ty: Type, pt: Zcu.PerThread) SemaError!bool {
782 return try ty.fnHasRuntimeBitsInner(.sema, pt.zcu, pt.tid);
783}
784
785839/// Determines whether a function type has runtime bits, i.e. whether a
786840/// function with this type can exist at runtime.
787841/// Asserts that `ty` is a function type.
788pub fn fnHasRuntimeBitsInner(
789 ty: Type,
790 comptime strat: ResolveStrat,
791 zcu: strat.ZcuPtr(),
792 tid: strat.Tid(),
793) SemaError!bool {
794 const fn_info = zcu.typeToFunc(ty).?;
795 if (fn_info.is_generic) return false;
796 if (fn_info.is_var_args) return true;
842pub fn fnHasRuntimeBits(fn_ty: Type, zcu: *const Zcu) bool {
843 assertHasLayout(fn_ty, zcu);
844 const fn_info = zcu.typeToFunc(fn_ty).?;
845 if (fn_info.comptime_bits != 0) return false;
846 for (fn_info.param_types.get(&zcu.intern_pool)) |param_ty| {
847 if (param_ty == .generic_poison_type) return false;
848 switch (Type.fromInterned(param_ty).classify(zcu)) {
849 .fully_comptime,
850 .partially_comptime,
851 .no_possible_value,
852 => return false,
853
854 .one_possible_value,
855 .runtime,
856 => {},
857 }
858 }
859 const ret_ty: Type = .fromInterned(fn_info.return_type);
860 if (ret_ty.toIntern() == .generic_poison_type) {
861 return false;
862 }
863 if (ret_ty.zigTypeTag(zcu) == .error_union and
864 ret_ty.errorUnionPayload(zcu).toIntern() == .generic_poison_type)
865 {
866 return false;
867 }
868 switch (ret_ty.classify(zcu)) {
869 .fully_comptime,
870 .partially_comptime,
871 => return false,
872
873 .no_possible_value,
874 .one_possible_value,
875 .runtime,
876 => {},
877 }
797878 if (fn_info.cc == .@"inline") return false;
798 return !try Type.fromInterned(fn_info.return_type).comptimeOnlyInner(strat, zcu, tid);
879 return true;
799880}
800881
801pub fn isFnOrHasRuntimeBits(ty: Type, zcu: *Zcu) bool {
882/// Like `hasRuntimeBits`, but also returns `true` for runtime functions.
883pub fn isRuntimeFnOrHasRuntimeBits(ty: Type, zcu: *const Zcu) bool {
802884 switch (ty.zigTypeTag(zcu)) {
803885 .@"fn" => return ty.fnHasRuntimeBits(zcu),
804886 else => return ty.hasRuntimeBits(zcu),
805887 }
806888}
807889
808/// Same as `isFnOrHasRuntimeBits` but comptime-only types may return a false positive.
809pub fn isFnOrHasRuntimeBitsIgnoreComptime(ty: Type, zcu: *Zcu) bool {
810 return switch (ty.zigTypeTag(zcu)) {
811 .@"fn" => true,
812 else => return ty.hasRuntimeBitsIgnoreComptime(zcu),
813 };
814}
815
890/// Returns whether `ty` is NPV, meaning it is "like `noreturn`" in a sense. See doc comments on
891/// `Class` for more details.
892///
893/// Exactly equivalent to `ty.classify(zcu) == .no_possible_value`.
816894pub fn isNoReturn(ty: Type, zcu: *const Zcu) bool {
817 return zcu.intern_pool.isNoReturn(ty.toIntern());
895 return ty.classify(zcu) == .no_possible_value;
818896}
819897
820898/// Never returns `none`. Asserts that all necessary type resolution is already done.
821pub fn ptrAlignment(ty: Type, zcu: *Zcu) Alignment {
822 return ptrAlignmentInner(ty, .normal, zcu, {}) catch unreachable;
823}
824
825pub fn ptrAlignmentSema(ty: Type, pt: Zcu.PerThread) SemaError!Alignment {
826 return try ty.ptrAlignmentInner(.sema, pt.zcu, pt.tid);
827}
828
829pub fn ptrAlignmentInner(
830 ty: Type,
831 comptime strat: ResolveStrat,
832 zcu: strat.ZcuPtr(),
833 tid: strat.Tid(),
834) !Alignment {
835 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
836 .ptr_type => |ptr_type| {
837 if (ptr_type.flags.alignment != .none) return ptr_type.flags.alignment;
838 const res = try Type.fromInterned(ptr_type.child).abiAlignmentInner(strat.toLazy(), zcu, tid);
839 return res.scalar;
840 },
841 .opt_type => |child| Type.fromInterned(child).ptrAlignmentInner(strat, zcu, tid),
899pub fn ptrAlignment(ptr_ty: Type, zcu: *Zcu) Alignment {
900 const ip = &zcu.intern_pool;
901 const ptr_key: InternPool.Key.PtrType = switch (ip.indexToKey(ptr_ty.toIntern())) {
902 .ptr_type => |key| key,
903 .opt_type => |child| ip.indexToKey(child).ptr_type,
842904 else => unreachable,
843905 };
906 if (ptr_key.flags.alignment != .none) return ptr_key.flags.alignment;
907 return Type.fromInterned(ptr_key.child).abiAlignment(zcu);
844908}
845909
846910pub fn ptrAddressSpace(ty: Type, zcu: *const Zcu) std.builtin.AddressSpace {
......@@ -851,861 +915,364 @@ pub fn ptrAddressSpace(ty: Type, zcu: *const Zcu) std.builtin.AddressSpace {
851915 };
852916}
853917
854/// May capture a reference to `ty`.
855/// Returned value has type `comptime_int`.
856pub fn lazyAbiAlignment(ty: Type, pt: Zcu.PerThread) !Value {
857 switch (try ty.abiAlignmentInner(.lazy, pt.zcu, pt.tid)) {
858 .val => |val| return val,
859 .scalar => |x| return pt.intValue(Type.comptime_int, x.toByteUnits() orelse 0),
860 }
861}
862
863pub const AbiAlignmentInner = union(enum) {
864 scalar: Alignment,
865 val: Value,
866};
867
868pub const ResolveStratLazy = enum {
869 /// Return a `lazy_size` or `lazy_align` value if necessary.
870 /// This value can be resolved later using `Value.resolveLazy`.
871 lazy,
872 /// Return a scalar result, expecting all necessary type resolution to be completed.
873 /// Backends should typically use this, since they must not perform type resolution.
874 eager,
875 /// Return a scalar result, performing type resolution as necessary.
876 /// This should typically be used from semantic analysis.
877 sema,
878
879 pub fn Tid(strat: ResolveStratLazy) type {
880 return switch (strat) {
881 .lazy, .sema => Zcu.PerThread.Id,
882 .eager => void,
883 };
884 }
885
886 pub fn ZcuPtr(strat: ResolveStratLazy) type {
887 return switch (strat) {
888 .eager => *const Zcu,
889 .sema, .lazy => *Zcu,
890 };
891 }
892
893 pub fn pt(
894 comptime strat: ResolveStratLazy,
895 zcu: strat.ZcuPtr(),
896 tid: strat.Tid(),
897 ) switch (strat) {
898 .lazy, .sema => Zcu.PerThread,
899 .eager => void,
900 } {
901 return switch (strat) {
902 .lazy, .sema => .{ .tid = tid, .zcu = zcu },
903 else => {},
904 };
905 }
906};
907
908/// The chosen strategy can be easily optimized away in release builds.
909/// However, in debug builds, it helps to avoid accidentally resolving types in backends.
910pub const ResolveStrat = enum {
911 /// Assert that all necessary resolution is completed.
912 /// Backends should typically use this, since they must not perform type resolution.
913 normal,
914 /// Perform type resolution as necessary using `Zcu`.
915 /// This should typically be used from semantic analysis.
916 sema,
917
918 pub fn Tid(strat: ResolveStrat) type {
919 return switch (strat) {
920 .sema => Zcu.PerThread.Id,
921 .normal => void,
922 };
923 }
924
925 pub fn ZcuPtr(strat: ResolveStrat) type {
926 return switch (strat) {
927 .normal => *const Zcu,
928 .sema => *Zcu,
929 };
930 }
931
932 pub fn pt(comptime strat: ResolveStrat, zcu: strat.ZcuPtr(), tid: strat.Tid()) switch (strat) {
933 .sema => Zcu.PerThread,
934 .normal => void,
935 } {
936 return switch (strat) {
937 .sema => .{ .tid = tid, .zcu = zcu },
938 .normal => {},
939 };
940 }
941
942 pub inline fn toLazy(strat: ResolveStrat) ResolveStratLazy {
943 return switch (strat) {
944 .normal => .eager,
945 .sema => .sema,
946 };
947 }
948};
949
950/// Never returns `none`. Asserts that all necessary type resolution is already done.
918/// Never returns `.none`. Asserts that the layout of `ty` is resolved.
919///
920/// Unlike ABI size, a type's ABI alignment is not affected by its `Class`. In other words, any
921/// alignment is possible regardless of the result of `ty.classify(zcu)`.
951922pub fn abiAlignment(ty: Type, zcu: *const Zcu) Alignment {
952 return (ty.abiAlignmentInner(.eager, zcu, {}) catch unreachable).scalar;
953}
954
955pub fn abiAlignmentSema(ty: Type, pt: Zcu.PerThread) SemaError!Alignment {
956 return (try ty.abiAlignmentInner(.sema, pt.zcu, pt.tid)).scalar;
957}
958
959/// If you pass `eager` you will get back `scalar` and assert the type is resolved.
960/// In this case there will be no error, guaranteed.
961/// If you pass `lazy` you may get back `scalar` or `val`.
962/// If `val` is returned, a reference to `ty` has been captured.
963/// If you pass `sema` you will get back `scalar` and resolve the type if
964/// necessary, possibly returning a CompileError.
965pub fn abiAlignmentInner(
966 ty: Type,
967 comptime strat: ResolveStratLazy,
968 zcu: strat.ZcuPtr(),
969 tid: strat.Tid(),
970) SemaError!AbiAlignmentInner {
971 const pt = strat.pt(zcu, tid);
972 const target = zcu.getTarget();
973923 const ip = &zcu.intern_pool;
924 const target = zcu.getTarget();
925 assertHasLayout(ty, zcu);
926 return switch (ip.indexToKey(ty.toIntern())) {
927 .int_type => |int_type| {
928 if (int_type.bits == 0) return .@"1";
929 return .fromByteUnits(std.zig.target.intAlignment(target, int_type.bits));
930 },
931 .ptr_type, .anyframe_type => ptrAbiAlignment(target),
932 .array_type => |array_type| Type.fromInterned(array_type.child).abiAlignment(zcu),
933 .vector_type => |vector_type| {
934 if (vector_type.len == 0) return .@"1";
935 switch (zcu.comp.getZigBackend()) {
936 else => {
937 const elem_bits: u32 = @intCast(Type.fromInterned(vector_type.child).bitSize(zcu));
938 if (elem_bits == 0) return .@"1";
939 const bytes = ((elem_bits * vector_type.len) + 7) / 8;
940 return .fromByteUnits(std.math.ceilPowerOfTwoAssert(u32, bytes));
941 },
942 .stage2_c => return Type.fromInterned(vector_type.child).abiAlignment(zcu),
943 .stage2_x86_64 => {
944 if (vector_type.child == .bool_type) {
945 if (vector_type.len > 256 and target.cpu.has(.x86, .avx512f)) return .@"64";
946 if (vector_type.len > 128 and target.cpu.has(.x86, .avx)) return .@"32";
947 if (vector_type.len > 64) return .@"16";
948 const bytes = std.math.divCeil(u32, vector_type.len, 8) catch unreachable;
949 return .fromByteUnits(std.math.ceilPowerOfTwoAssert(u32, bytes));
950 }
951 const elem_bytes: u32 = @intCast(Type.fromInterned(vector_type.child).abiSize(zcu));
952 if (elem_bytes == 0) return .@"1";
953 const bytes = elem_bytes * vector_type.len;
954 if (bytes > 32 and target.cpu.has(.x86, .avx512f)) return .@"64";
955 if (bytes > 16 and target.cpu.has(.x86, .avx)) return .@"32";
956 return .@"16";
957 },
958 }
959 },
974960
975 switch (ty.toIntern()) {
976 .empty_tuple_type => return .{ .scalar = .@"1" },
977 else => switch (ip.indexToKey(ty.toIntern())) {
978 .int_type => |int_type| {
979 if (int_type.bits == 0) return .{ .scalar = .@"1" };
980 return .{ .scalar = .fromByteUnits(std.zig.target.intAlignment(target, int_type.bits)) };
981 },
982 .ptr_type, .anyframe_type => {
983 return .{ .scalar = ptrAbiAlignment(target) };
984 },
985 .array_type => |array_type| {
986 return Type.fromInterned(array_type.child).abiAlignmentInner(strat, zcu, tid);
987 },
988 .vector_type => |vector_type| {
989 if (vector_type.len == 0) return .{ .scalar = .@"1" };
990 switch (zcu.comp.getZigBackend()) {
991 else => {
992 // This is fine because the child type of a vector always has a bit-size known
993 // without needing any type resolution.
994 const elem_bits: u32 = @intCast(Type.fromInterned(vector_type.child).bitSize(zcu));
995 if (elem_bits == 0) return .{ .scalar = .@"1" };
996 const bytes = ((elem_bits * vector_type.len) + 7) / 8;
997 const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes);
998 return .{ .scalar = Alignment.fromByteUnits(alignment) };
999 },
1000 .stage2_c => {
1001 return Type.fromInterned(vector_type.child).abiAlignmentInner(strat, zcu, tid);
1002 },
1003 .stage2_x86_64 => {
1004 if (vector_type.child == .bool_type) {
1005 if (vector_type.len > 256 and target.cpu.has(.x86, .avx512f)) return .{ .scalar = .@"64" };
1006 if (vector_type.len > 128 and target.cpu.has(.x86, .avx)) return .{ .scalar = .@"32" };
1007 if (vector_type.len > 64) return .{ .scalar = .@"16" };
1008 const bytes = std.math.divCeil(u32, vector_type.len, 8) catch unreachable;
1009 const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes);
1010 return .{ .scalar = Alignment.fromByteUnits(alignment) };
1011 }
1012 const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeInner(strat, zcu, tid)).scalar);
1013 if (elem_bytes == 0) return .{ .scalar = .@"1" };
1014 const bytes = elem_bytes * vector_type.len;
1015 if (bytes > 32 and target.cpu.has(.x86, .avx512f)) return .{ .scalar = .@"64" };
1016 if (bytes > 16 and target.cpu.has(.x86, .avx)) return .{ .scalar = .@"32" };
1017 return .{ .scalar = .@"16" };
1018 },
1019 }
1020 },
961 .opt_type => |child| Type.fromInterned(child).abiAlignment(zcu),
962 .error_union_type => |eu| Alignment.maxStrict(
963 Type.fromInterned(eu.payload_type).abiAlignment(zcu),
964 errorAbiAlignment(zcu),
965 ),
1021966
1022 .opt_type => return ty.abiAlignmentInnerOptional(strat, zcu, tid),
1023 .error_union_type => |info| return ty.abiAlignmentInnerErrorUnion(
1024 strat,
1025 zcu,
1026 tid,
1027 Type.fromInterned(info.payload_type),
1028 ),
967 .error_set_type, .inferred_error_set_type => errorAbiAlignment(zcu),
1029968
1030 .error_set_type, .inferred_error_set_type => {
1031 const bits = zcu.errorSetBits();
1032 if (bits == 0) return .{ .scalar = .@"1" };
1033 return .{ .scalar = .fromByteUnits(std.zig.target.intAlignment(target, bits)) };
1034 },
969 .func_type => target_util.minFunctionAlignment(target),
1035970
1036 // represents machine code; not a pointer
1037 .func_type => return .{ .scalar = target_util.minFunctionAlignment(target) },
1038
1039 .simple_type => |t| switch (t) {
1040 .bool,
1041 .anyopaque,
1042 => return .{ .scalar = .@"1" },
1043
1044 .usize,
1045 .isize,
1046 => return .{ .scalar = .fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())) },
1047
1048 .c_char => return .{ .scalar = cTypeAlign(target, .char) },
1049 .c_short => return .{ .scalar = cTypeAlign(target, .short) },
1050 .c_ushort => return .{ .scalar = cTypeAlign(target, .ushort) },
1051 .c_int => return .{ .scalar = cTypeAlign(target, .int) },
1052 .c_uint => return .{ .scalar = cTypeAlign(target, .uint) },
1053 .c_long => return .{ .scalar = cTypeAlign(target, .long) },
1054 .c_ulong => return .{ .scalar = cTypeAlign(target, .ulong) },
1055 .c_longlong => return .{ .scalar = cTypeAlign(target, .longlong) },
1056 .c_ulonglong => return .{ .scalar = cTypeAlign(target, .ulonglong) },
1057 .c_longdouble => return .{ .scalar = cTypeAlign(target, .longdouble) },
1058
1059 .f16 => return .{ .scalar = .@"2" },
1060 .f32 => return .{ .scalar = cTypeAlign(target, .float) },
1061 .f64 => switch (target.cTypeBitSize(.double)) {
1062 64 => return .{ .scalar = cTypeAlign(target, .double) },
1063 else => return .{ .scalar = .@"8" },
1064 },
1065 .f80 => switch (target.cTypeBitSize(.longdouble)) {
1066 80 => return .{ .scalar = cTypeAlign(target, .longdouble) },
1067 else => return .{ .scalar = Type.u80.abiAlignment(zcu) },
1068 },
1069 .f128 => switch (target.cTypeBitSize(.longdouble)) {
1070 128 => return .{ .scalar = cTypeAlign(target, .longdouble) },
1071 else => return .{ .scalar = .@"16" },
1072 },
1073
1074 .anyerror, .adhoc_inferred_error_set => {
1075 const bits = zcu.errorSetBits();
1076 if (bits == 0) return .{ .scalar = .@"1" };
1077 return .{ .scalar = .fromByteUnits(std.zig.target.intAlignment(target, bits)) };
1078 },
1079
1080 .void,
1081 .type,
1082 .comptime_int,
1083 .comptime_float,
1084 .null,
1085 .undefined,
1086 .enum_literal,
1087 => return .{ .scalar = .@"1" },
1088
1089 .noreturn => unreachable,
1090 .generic_poison => unreachable,
1091 },
1092 .struct_type => {
1093 const struct_type = ip.loadStructType(ty.toIntern());
1094 if (struct_type.layout == .@"packed") {
1095 switch (strat) {
1096 .sema => try ty.resolveLayout(pt),
1097 .lazy => if (struct_type.backingIntTypeUnordered(ip) == .none) return .{
1098 .val = Value.fromInterned(try pt.intern(.{ .int = .{
1099 .ty = .comptime_int_type,
1100 .storage = .{ .lazy_align = ty.toIntern() },
1101 } })),
1102 },
1103 .eager => {},
1104 }
1105 return .{ .scalar = Type.fromInterned(struct_type.backingIntTypeUnordered(ip)).abiAlignment(zcu) };
1106 }
1107
1108 if (struct_type.flagsUnordered(ip).alignment == .none) switch (strat) {
1109 .eager => unreachable, // struct alignment not resolved
1110 .sema => try ty.resolveStructAlignment(pt),
1111 .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1112 .ty = .comptime_int_type,
1113 .storage = .{ .lazy_align = ty.toIntern() },
1114 } })) },
1115 };
1116
1117 return .{ .scalar = struct_type.flagsUnordered(ip).alignment };
1118 },
1119 .tuple_type => |tuple| {
1120 var big_align: Alignment = .@"1";
1121 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
1122 if (val != .none) continue; // comptime field
1123 switch (try Type.fromInterned(field_ty).abiAlignmentInner(strat, zcu, tid)) {
1124 .scalar => |field_align| big_align = big_align.max(field_align),
1125 .val => switch (strat) {
1126 .eager => unreachable, // field type alignment not resolved
1127 .sema => unreachable, // passed to abiAlignmentInner above
1128 .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1129 .ty = .comptime_int_type,
1130 .storage = .{ .lazy_align = ty.toIntern() },
1131 } })) },
1132 },
1133 }
1134 }
1135 return .{ .scalar = big_align };
971 .simple_type => |t| switch (t) {
972 .bool,
973 .void,
974 .noreturn,
975 .anyopaque,
976 .type,
977 .comptime_int,
978 .comptime_float,
979 .null,
980 .undefined,
981 .enum_literal,
982 => .@"1",
983
984 .anyerror, .adhoc_inferred_error_set => errorAbiAlignment(zcu),
985 .usize, .isize => .fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())),
986
987 .c_char => cTypeAlign(target, .char),
988 .c_short => cTypeAlign(target, .short),
989 .c_ushort => cTypeAlign(target, .ushort),
990 .c_int => cTypeAlign(target, .int),
991 .c_uint => cTypeAlign(target, .uint),
992 .c_long => cTypeAlign(target, .long),
993 .c_ulong => cTypeAlign(target, .ulong),
994 .c_longlong => cTypeAlign(target, .longlong),
995 .c_ulonglong => cTypeAlign(target, .ulonglong),
996 .c_longdouble => cTypeAlign(target, .longdouble),
997
998 .f16 => .@"2",
999 .f32 => cTypeAlign(target, .float),
1000 .f64 => switch (target.cTypeBitSize(.double)) {
1001 64 => cTypeAlign(target, .double),
1002 else => .@"8",
11361003 },
1137 .union_type => {
1138 const union_type = ip.loadUnionType(ty.toIntern());
1139
1140 if (union_type.flagsUnordered(ip).alignment == .none) switch (strat) {
1141 .eager => unreachable, // union layout not resolved
1142 .sema => try ty.resolveUnionAlignment(pt),
1143 .lazy => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1144 .ty = .comptime_int_type,
1145 .storage = .{ .lazy_align = ty.toIntern() },
1146 } })) },
1147 };
1148
1149 return .{ .scalar = union_type.flagsUnordered(ip).alignment };
1004 .f80 => switch (target.cTypeBitSize(.longdouble)) {
1005 80 => cTypeAlign(target, .longdouble),
1006 else => Type.u80.abiAlignment(zcu),
11501007 },
1151 .opaque_type => return .{ .scalar = .@"1" },
1152 .enum_type => return .{
1153 .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiAlignment(zcu),
1008 .f128 => switch (target.cTypeBitSize(.longdouble)) {
1009 128 => cTypeAlign(target, .longdouble),
1010 else => .@"16",
11541011 },
11551012
1156 // values, not types
1157 .undef,
1158 .simple_value,
1159 .variable,
1160 .@"extern",
1161 .func,
1162 .int,
1163 .err,
1164 .error_union,
1165 .enum_literal,
1166 .enum_tag,
1167 .empty_enum_value,
1168 .float,
1169 .ptr,
1170 .slice,
1171 .opt,
1172 .aggregate,
1173 .un,
1174 // memoization, not types
1175 .memoized_call,
1176 => unreachable,
1013 .generic_poison => unreachable,
11771014 },
1178 }
1179}
1180
1181fn abiAlignmentInnerErrorUnion(
1182 ty: Type,
1183 comptime strat: ResolveStratLazy,
1184 zcu: strat.ZcuPtr(),
1185 tid: strat.Tid(),
1186 payload_ty: Type,
1187) SemaError!AbiAlignmentInner {
1188 // This code needs to be kept in sync with the equivalent switch prong
1189 // in abiSizeInner.
1190 const code_align = Type.anyerror.abiAlignment(zcu);
1191 switch (strat) {
1192 .eager, .sema => {
1193 if (!(payload_ty.hasRuntimeBitsInner(false, strat, zcu, tid) catch |err| switch (err) {
1194 error.NeedLazy => if (strat == .lazy) {
1195 const pt = strat.pt(zcu, tid);
1196 return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1197 .ty = .comptime_int_type,
1198 .storage = .{ .lazy_align = ty.toIntern() },
1199 } })) };
1200 } else unreachable,
1201 else => |e| return e,
1202 })) {
1203 return .{ .scalar = code_align };
1204 }
1205 return .{ .scalar = code_align.max(
1206 (try payload_ty.abiAlignmentInner(strat, zcu, tid)).scalar,
1207 ) };
1208 },
1209 .lazy => {
1210 const pt = strat.pt(zcu, tid);
1211 switch (try payload_ty.abiAlignmentInner(strat, zcu, tid)) {
1212 .scalar => |payload_align| return .{ .scalar = code_align.max(payload_align) },
1213 .val => {},
1015 .tuple_type => |tuple| {
1016 var big_align: Alignment = .@"1";
1017 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
1018 if (val != .none) continue; // comptime field
1019 const field_align = Type.fromInterned(field_ty).abiAlignment(zcu);
1020 big_align = big_align.maxStrict(field_align);
12141021 }
1215 return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1216 .ty = .comptime_int_type,
1217 .storage = .{ .lazy_align = ty.toIntern() },
1218 } })) };
1022 return big_align;
12191023 },
1220 }
1221}
1222
1223fn abiAlignmentInnerOptional(
1224 ty: Type,
1225 comptime strat: ResolveStratLazy,
1226 zcu: strat.ZcuPtr(),
1227 tid: strat.Tid(),
1228) SemaError!AbiAlignmentInner {
1229 const pt = strat.pt(zcu, tid);
1230 const target = zcu.getTarget();
1231 const child_type = ty.optionalChild(zcu);
1232
1233 switch (child_type.zigTypeTag(zcu)) {
1234 .pointer => return .{ .scalar = ptrAbiAlignment(target) },
1235 .error_set => return Type.anyerror.abiAlignmentInner(strat, zcu, tid),
1236 .noreturn => return .{ .scalar = .@"1" },
1237 else => {},
1238 }
1239
1240 switch (strat) {
1241 .eager, .sema => {
1242 if (!(child_type.hasRuntimeBitsInner(false, strat, zcu, tid) catch |err| switch (err) {
1243 error.NeedLazy => if (strat == .lazy) {
1244 return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1245 .ty = .comptime_int_type,
1246 .storage = .{ .lazy_align = ty.toIntern() },
1247 } })) };
1248 } else unreachable,
1249 else => |e| return e,
1250 })) {
1251 return .{ .scalar = .@"1" };
1024 .struct_type => {
1025 const struct_obj = ip.loadStructType(ty.toIntern());
1026 switch (struct_obj.layout) {
1027 .@"packed" => return Type.fromInterned(struct_obj.packed_backing_int_type).abiAlignment(zcu),
1028 .auto, .@"extern" => {
1029 assert(struct_obj.alignment != .none);
1030 return struct_obj.alignment;
1031 },
12521032 }
1253 return child_type.abiAlignmentInner(strat, zcu, tid);
12541033 },
1255 .lazy => switch (try child_type.abiAlignmentInner(strat, zcu, tid)) {
1256 .scalar => |x| return .{ .scalar = x.max(.@"1") },
1257 .val => return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1258 .ty = .comptime_int_type,
1259 .storage = .{ .lazy_align = ty.toIntern() },
1260 } })) },
1034 .union_type => {
1035 const union_obj = ip.loadUnionType(ty.toIntern());
1036 switch (union_obj.layout) {
1037 .@"packed" => return Type.fromInterned(union_obj.packed_backing_int_type).abiAlignment(zcu),
1038 .auto, .@"extern" => {
1039 assert(union_obj.alignment != .none);
1040 return union_obj.alignment;
1041 },
1042 }
12611043 },
1262 }
1263}
1264
1265const AbiSizeInner = union(enum) {
1266 scalar: u64,
1267 val: Value,
1268};
1269
1270/// Asserts the type has the ABI size already resolved.
1271/// Types that return false for hasRuntimeBits() return 0.
1272pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {
1273 return (abiSizeInner(ty, .eager, zcu, {}) catch unreachable).scalar;
1274}
1044 .enum_type => Type.fromInterned(ip.loadEnumType(ty.toIntern()).int_tag_type).abiAlignment(zcu),
1045 .opaque_type => .@"1",
12751046
1276/// May capture a reference to `ty`.
1277pub fn abiSizeLazy(ty: Type, pt: Zcu.PerThread) !Value {
1278 switch (try ty.abiSizeInner(.lazy, pt.zcu, pt.tid)) {
1279 .val => |val| return val,
1280 .scalar => |x| return pt.intValue(Type.comptime_int, x),
1281 }
1282}
1283
1284pub fn abiSizeSema(ty: Type, pt: Zcu.PerThread) SemaError!u64 {
1285 return (try abiSizeInner(ty, .sema, pt.zcu, pt.tid)).scalar;
1047 // values, not types
1048 .undef,
1049 .simple_value,
1050 .variable,
1051 .@"extern",
1052 .func,
1053 .int,
1054 .err,
1055 .error_union,
1056 .enum_literal,
1057 .enum_tag,
1058 .float,
1059 .ptr,
1060 .slice,
1061 .opt,
1062 .aggregate,
1063 .un,
1064 .bitpack,
1065 // memoization, not types
1066 .memoized_call,
1067 => unreachable,
1068 };
12861069}
12871070
1288/// If you pass `eager` you will get back `scalar` and assert the type is resolved.
1289/// In this case there will be no error, guaranteed.
1290/// If you pass `lazy` you may get back `scalar` or `val`.
1291/// If `val` is returned, a reference to `ty` has been captured.
1292/// If you pass `sema` you will get back `scalar` and resolve the type if
1293/// necessary, possibly returning a CompileError.
1294pub fn abiSizeInner(
1295 ty: Type,
1296 comptime strat: ResolveStratLazy,
1297 zcu: strat.ZcuPtr(),
1298 tid: strat.Tid(),
1299) SemaError!AbiSizeInner {
1300 const target = zcu.getTarget();
1071/// Asserts that `ty` is not an opaque type, and that the layout of `ty` is resolved.
1072///
1073/// If the type is NPV, OPV, or fully-comptime (see `Class`), the return value of this function is
1074/// guaranteed to be zero. Otherwise (if the type is runtime or partially-comptime) the return value
1075/// is guaranteed to be non-zero.
1076pub fn abiSize(ty: Type, zcu: *const Zcu) u64 {
13011077 const ip = &zcu.intern_pool;
1302
1303 switch (ty.toIntern()) {
1304 .empty_tuple_type => return .{ .scalar = 0 },
1305
1306 else => switch (ip.indexToKey(ty.toIntern())) {
1307 .int_type => |int_type| {
1308 if (int_type.bits == 0) return .{ .scalar = 0 };
1309 return .{ .scalar = std.zig.target.intByteSize(target, int_type.bits) };
1310 },
1311 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
1312 .slice => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 },
1313 else => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) },
1314 },
1315 .anyframe_type => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) },
1316
1317 .array_type => |array_type| {
1318 const len = array_type.lenIncludingSentinel();
1319 if (len == 0) return .{ .scalar = 0 };
1320 switch (try Type.fromInterned(array_type.child).abiSizeInner(strat, zcu, tid)) {
1321 .scalar => |elem_size| return .{ .scalar = len * elem_size },
1322 .val => switch (strat) {
1323 .sema, .eager => unreachable,
1324 .lazy => {
1325 const pt = strat.pt(zcu, tid);
1326 return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1327 .ty = .comptime_int_type,
1328 .storage = .{ .lazy_size = ty.toIntern() },
1329 } })) };
1330 },
1331 },
1332 }
1333 },
1334 .vector_type => |vector_type| {
1335 const sub_strat: ResolveStrat = switch (strat) {
1336 .sema => .sema,
1337 .eager => .normal,
1338 .lazy => {
1339 const pt = strat.pt(zcu, tid);
1340 return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1341 .ty = .comptime_int_type,
1342 .storage = .{ .lazy_size = ty.toIntern() },
1343 } })) };
1344 },
1345 };
1346 const alignment = (try ty.abiAlignmentInner(strat, zcu, tid)).scalar;
1347 const total_bytes = switch (zcu.comp.getZigBackend()) {
1348 else => total_bytes: {
1349 const elem_bits = try Type.fromInterned(vector_type.child).bitSizeInner(sub_strat, zcu, tid);
1350 const total_bits = elem_bits * vector_type.len;
1351 break :total_bytes (total_bits + 7) / 8;
1352 },
1353 .stage2_c => total_bytes: {
1354 const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeInner(strat, zcu, tid)).scalar);
1355 break :total_bytes elem_bytes * vector_type.len;
1356 },
1357 .stage2_x86_64 => total_bytes: {
1358 if (vector_type.child == .bool_type) break :total_bytes std.math.divCeil(u32, vector_type.len, 8) catch unreachable;
1359 const elem_bytes: u32 = @intCast((try Type.fromInterned(vector_type.child).abiSizeInner(strat, zcu, tid)).scalar);
1360 break :total_bytes elem_bytes * vector_type.len;
1361 },
1362 };
1363 return .{ .scalar = alignment.forward(total_bytes) };
1364 },
1365
1366 .opt_type => return ty.abiSizeInnerOptional(strat, zcu, tid),
1367
1368 .error_set_type, .inferred_error_set_type => {
1369 const bits = zcu.errorSetBits();
1370 if (bits == 0) return .{ .scalar = 0 };
1371 return .{ .scalar = std.zig.target.intByteSize(target, bits) };
1372 },
1373
1374 .error_union_type => |error_union_type| {
1375 const payload_ty = Type.fromInterned(error_union_type.payload_type);
1376 // This code needs to be kept in sync with the equivalent switch prong
1377 // in abiAlignmentInner.
1378 const code_size = Type.anyerror.abiSize(zcu);
1379 if (!(payload_ty.hasRuntimeBitsInner(false, strat, zcu, tid) catch |err| switch (err) {
1380 error.NeedLazy => if (strat == .lazy) {
1381 const pt = strat.pt(zcu, tid);
1382 return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1383 .ty = .comptime_int_type,
1384 .storage = .{ .lazy_size = ty.toIntern() },
1385 } })) };
1386 } else unreachable,
1387 else => |e| return e,
1388 })) {
1389 // Same as anyerror.
1390 return .{ .scalar = code_size };
1391 }
1392 const code_align = Type.anyerror.abiAlignment(zcu);
1393 const payload_align = (try payload_ty.abiAlignmentInner(strat, zcu, tid)).scalar;
1394 const payload_size = switch (try payload_ty.abiSizeInner(strat, zcu, tid)) {
1395 .scalar => |elem_size| elem_size,
1396 .val => switch (strat) {
1397 .sema => unreachable,
1398 .eager => unreachable,
1399 .lazy => {
1400 const pt = strat.pt(zcu, tid);
1401 return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1402 .ty = .comptime_int_type,
1403 .storage = .{ .lazy_size = ty.toIntern() },
1404 } })) };
1405 },
1406 },
1407 };
1408
1409 var size: u64 = 0;
1410 if (code_align.compare(.gt, payload_align)) {
1411 size += code_size;
1412 size = payload_align.forward(size);
1413 size += payload_size;
1414 size = code_align.forward(size);
1415 } else {
1416 size += payload_size;
1417 size = code_align.forward(size);
1418 size += code_size;
1419 size = payload_align.forward(size);
1420 }
1421 return .{ .scalar = size };
1422 },
1423 .func_type => unreachable, // represents machine code; not a pointer
1424 .simple_type => |t| switch (t) {
1425 .bool => return .{ .scalar = 1 },
1426
1427 .f16 => return .{ .scalar = 2 },
1428 .f32 => return .{ .scalar = 4 },
1429 .f64 => return .{ .scalar = 8 },
1430 .f128 => return .{ .scalar = 16 },
1431 .f80 => switch (target.cTypeBitSize(.longdouble)) {
1432 80 => return .{ .scalar = target.cTypeByteSize(.longdouble) },
1433 else => return .{ .scalar = Type.u80.abiSize(zcu) },
1434 },
1435
1436 .usize,
1437 .isize,
1438 => return .{ .scalar = @divExact(target.ptrBitWidth(), 8) },
1439
1440 .c_char => return .{ .scalar = target.cTypeByteSize(.char) },
1441 .c_short => return .{ .scalar = target.cTypeByteSize(.short) },
1442 .c_ushort => return .{ .scalar = target.cTypeByteSize(.ushort) },
1443 .c_int => return .{ .scalar = target.cTypeByteSize(.int) },
1444 .c_uint => return .{ .scalar = target.cTypeByteSize(.uint) },
1445 .c_long => return .{ .scalar = target.cTypeByteSize(.long) },
1446 .c_ulong => return .{ .scalar = target.cTypeByteSize(.ulong) },
1447 .c_longlong => return .{ .scalar = target.cTypeByteSize(.longlong) },
1448 .c_ulonglong => return .{ .scalar = target.cTypeByteSize(.ulonglong) },
1449 .c_longdouble => return .{ .scalar = target.cTypeByteSize(.longdouble) },
1450
1451 .anyopaque,
1452 .void,
1453 .type,
1454 .comptime_int,
1455 .comptime_float,
1456 .null,
1457 .undefined,
1458 .enum_literal,
1459 => return .{ .scalar = 0 },
1460
1461 .anyerror, .adhoc_inferred_error_set => {
1462 const bits = zcu.errorSetBits();
1463 if (bits == 0) return .{ .scalar = 0 };
1464 return .{ .scalar = std.zig.target.intByteSize(target, bits) };
1078 const target = zcu.getTarget();
1079 assertHasLayout(ty, zcu);
1080 return switch (ip.indexToKey(ty.toIntern())) {
1081 .int_type => |int_type| std.zig.target.intByteSize(target, int_type.bits),
1082 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
1083 .slice => ptrAbiSize(target) * 2,
1084 .one, .many, .c => ptrAbiSize(target),
1085 },
1086 .anyframe_type => ptrAbiSize(target),
1087 .array_type => |arr| arr.lenIncludingSentinel() * Type.fromInterned(arr.child).abiSize(zcu),
1088 .vector_type => |vec| {
1089 const elem_ty: Type = .fromInterned(vec.child);
1090 const bytes = switch (zcu.comp.getZigBackend()) {
1091 else => std.math.divCeil(u64, vec.len * elem_ty.bitSize(zcu), 8) catch unreachable,
1092 .stage2_c => vec.len * elem_ty.abiSize(zcu),
1093 .stage2_x86_64 => switch (elem_ty.toIntern()) {
1094 .bool_type => std.math.divCeil(u64, vec.len, 8) catch unreachable,
1095 else => vec.len * elem_ty.abiSize(zcu),
14651096 },
1466
1467 .noreturn => unreachable,
1468 .generic_poison => unreachable,
1469 },
1470 .struct_type => {
1471 const struct_type = ip.loadStructType(ty.toIntern());
1472 switch (strat) {
1473 .sema => try ty.resolveLayout(strat.pt(zcu, tid)),
1474 .lazy => {
1475 const pt = strat.pt(zcu, tid);
1476 switch (struct_type.layout) {
1477 .@"packed" => {
1478 if (struct_type.backingIntTypeUnordered(ip) == .none) return .{
1479 .val = Value.fromInterned(try pt.intern(.{ .int = .{
1480 .ty = .comptime_int_type,
1481 .storage = .{ .lazy_size = ty.toIntern() },
1482 } })),
1483 };
1484 },
1485 .auto, .@"extern" => {
1486 if (!struct_type.haveLayout(ip)) return .{
1487 .val = Value.fromInterned(try pt.intern(.{ .int = .{
1488 .ty = .comptime_int_type,
1489 .storage = .{ .lazy_size = ty.toIntern() },
1490 } })),
1491 };
1492 },
1493 }
1494 },
1495 .eager => {},
1496 }
1497 switch (struct_type.layout) {
1498 .@"packed" => return .{
1499 .scalar = Type.fromInterned(struct_type.backingIntTypeUnordered(ip)).abiSize(zcu),
1500 },
1501 .auto, .@"extern" => {
1502 assert(struct_type.haveLayout(ip));
1503 return .{ .scalar = struct_type.sizeUnordered(ip) };
1504 },
1505 }
1506 },
1507 .tuple_type => |tuple| {
1508 switch (strat) {
1509 .sema => try ty.resolveLayout(strat.pt(zcu, tid)),
1510 .lazy, .eager => {},
1511 }
1512 const field_count = tuple.types.len;
1513 if (field_count == 0) {
1514 return .{ .scalar = 0 };
1515 }
1516 return .{ .scalar = ty.structFieldOffset(field_count, zcu) };
1517 },
1518
1519 .union_type => {
1520 const union_type = ip.loadUnionType(ty.toIntern());
1521 switch (strat) {
1522 .sema => try ty.resolveLayout(strat.pt(zcu, tid)),
1523 .lazy => {
1524 const pt = strat.pt(zcu, tid);
1525 if (!union_type.flagsUnordered(ip).status.haveLayout()) return .{
1526 .val = Value.fromInterned(try pt.intern(.{ .int = .{
1527 .ty = .comptime_int_type,
1528 .storage = .{ .lazy_size = ty.toIntern() },
1529 } })),
1530 };
1531 },
1532 .eager => {},
1533 }
1534
1535 assert(union_type.haveLayout(ip));
1536 return .{ .scalar = union_type.sizeUnordered(ip) };
1097 };
1098 return ty.abiAlignment(zcu).forward(bytes);
1099 },
1100 .opt_type => |child_ty_ip| {
1101 const child_ty: Type = .fromInterned(child_ty_ip);
1102 if (child_ty.classify(zcu) == .no_possible_value) return 0;
1103 if (ty.optionalReprIsPayload(zcu)) return child_ty.abiSize(zcu);
1104 // Optional types are represented as a struct with the child type as the first
1105 // field and a boolean as the second. Since the child type's abi alignment is
1106 // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal
1107 // to the child type's ABI alignment.
1108 return child_ty.abiSize(zcu) + child_ty.abiAlignment(zcu).toByteUnits().?;
1109 },
1110 .error_set_type, .inferred_error_set_type => errorAbiSize(zcu),
1111 .error_union_type => |error_union| {
1112 const payload_ty: Type = .fromInterned(error_union.payload_type);
1113 switch (payload_ty.classify(zcu)) {
1114 // Zig has no way to take the address of the error set "in" an error union (giving
1115 // implementations more freedom in terms of data layout), so if the payload type is
1116 // fully comptime, we don't need to dedicate runtime bits to the error set.
1117 .fully_comptime => return 0,
1118 else => {},
1119 }
1120 // The layout will either be (code, payload, padding) or (payload, code, padding)
1121 // depending on which has larger alignment. So the overall size is just the code
1122 // and payload sizes added and padded to the larger alignment.
1123 const big_align: Alignment = .maxStrict(errorAbiAlignment(zcu), payload_ty.abiAlignment(zcu));
1124 return big_align.forward(errorAbiSize(zcu) + payload_ty.abiSize(zcu));
1125 },
1126 .func_type => 0,
1127 .simple_type => |t| switch (t) {
1128 .void,
1129 .noreturn,
1130 .type,
1131 .comptime_int,
1132 .comptime_float,
1133 .null,
1134 .undefined,
1135 .enum_literal,
1136 => 0,
1137
1138 .bool => 1,
1139 .anyerror, .adhoc_inferred_error_set => errorAbiSize(zcu),
1140 .usize, .isize => ptrAbiSize(target),
1141
1142 .c_char => target.cTypeByteSize(.char),
1143 .c_short => target.cTypeByteSize(.short),
1144 .c_ushort => target.cTypeByteSize(.ushort),
1145 .c_int => target.cTypeByteSize(.int),
1146 .c_uint => target.cTypeByteSize(.uint),
1147 .c_long => target.cTypeByteSize(.long),
1148 .c_ulong => target.cTypeByteSize(.ulong),
1149 .c_longlong => target.cTypeByteSize(.longlong),
1150 .c_ulonglong => target.cTypeByteSize(.ulonglong),
1151 .c_longdouble => target.cTypeByteSize(.longdouble),
1152
1153 .f16 => 2,
1154 .f32 => 4,
1155 .f64 => 8,
1156 .f80 => switch (target.cTypeBitSize(.longdouble)) {
1157 80 => target.cTypeByteSize(.longdouble),
1158 else => Type.u80.abiSize(zcu),
15371159 },
1538 .opaque_type => unreachable, // no size available
1539 .enum_type => return .{ .scalar = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).abiSize(zcu) },
1160 .f128 => 16,
15401161
1541 // values, not types
1542 .undef,
1543 .simple_value,
1544 .variable,
1545 .@"extern",
1546 .func,
1547 .int,
1548 .err,
1549 .error_union,
1550 .enum_literal,
1551 .enum_tag,
1552 .empty_enum_value,
1553 .float,
1554 .ptr,
1555 .slice,
1556 .opt,
1557 .aggregate,
1558 .un,
1559 // memoization, not types
1560 .memoized_call,
1561 => unreachable,
1162 .anyopaque => unreachable,
1163 .generic_poison => unreachable,
15621164 },
1563 }
1564}
1565
1566fn abiSizeInnerOptional(
1567 ty: Type,
1568 comptime strat: ResolveStratLazy,
1569 zcu: strat.ZcuPtr(),
1570 tid: strat.Tid(),
1571) SemaError!AbiSizeInner {
1572 const child_ty = ty.optionalChild(zcu);
1573
1574 if (child_ty.isNoReturn(zcu)) {
1575 return .{ .scalar = 0 };
1576 }
1577
1578 if (!(child_ty.hasRuntimeBitsInner(false, strat, zcu, tid) catch |err| switch (err) {
1579 error.NeedLazy => if (strat == .lazy) {
1580 const pt = strat.pt(zcu, tid);
1581 return .{ .val = Value.fromInterned(try pt.intern(.{ .int = .{
1582 .ty = .comptime_int_type,
1583 .storage = .{ .lazy_size = ty.toIntern() },
1584 } })) };
1585 } else unreachable,
1586 else => |e| return e,
1587 })) return .{ .scalar = 1 };
1588
1589 if (ty.optionalReprIsPayload(zcu)) {
1590 return child_ty.abiSizeInner(strat, zcu, tid);
1591 }
1592
1593 const payload_size = switch (try child_ty.abiSizeInner(strat, zcu, tid)) {
1594 .scalar => |elem_size| elem_size,
1595 .val => switch (strat) {
1596 .sema => unreachable,
1597 .eager => unreachable,
1598 .lazy => return .{ .val = Value.fromInterned(try strat.pt(zcu, tid).intern(.{ .int = .{
1599 .ty = .comptime_int_type,
1600 .storage = .{ .lazy_size = ty.toIntern() },
1601 } })) },
1165 .tuple_type => |tuple| switch (ty.classify(zcu)) {
1166 // `structFieldOffset` is bogus on NPV tuples, because there may be some fields with
1167 // non-zero size.
1168 .no_possible_value => 0,
1169 else => ty.structFieldOffset(tuple.types.len, zcu),
16021170 },
1603 };
1171 .struct_type => {
1172 const struct_obj = ip.loadStructType(ty.toIntern());
1173 switch (struct_obj.layout) {
1174 .@"packed" => return Type.fromInterned(struct_obj.packed_backing_int_type).abiSize(zcu),
1175 .auto, .@"extern" => return struct_obj.size,
1176 }
1177 },
1178 .union_type => {
1179 const union_obj = ip.loadUnionType(ty.toIntern());
1180 switch (union_obj.layout) {
1181 .@"packed" => return Type.fromInterned(union_obj.packed_backing_int_type).abiSize(zcu),
1182 .auto, .@"extern" => return union_obj.size,
1183 }
1184 },
1185 .enum_type => Type.fromInterned(ip.loadEnumType(ty.toIntern()).int_tag_type).abiSize(zcu),
1186 .opaque_type => unreachable,
16041187
1605 // Optional types are represented as a struct with the child type as the first
1606 // field and a boolean as the second. Since the child type's abi alignment is
1607 // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal
1608 // to the child type's ABI alignment.
1609 return .{
1610 .scalar = (child_ty.abiAlignment(zcu).toByteUnits() orelse 0) + payload_size,
1188 // values, not types
1189 .undef,
1190 .simple_value,
1191 .variable,
1192 .@"extern",
1193 .func,
1194 .int,
1195 .err,
1196 .error_union,
1197 .enum_literal,
1198 .enum_tag,
1199 .float,
1200 .ptr,
1201 .slice,
1202 .opt,
1203 .aggregate,
1204 .un,
1205 .bitpack,
1206 // memoization, not types
1207 .memoized_call,
1208 => unreachable,
16111209 };
16121210}
16131211
16141212pub fn ptrAbiAlignment(target: *const Target) Alignment {
1615 return Alignment.fromNonzeroByteUnits(@divExact(target.ptrBitWidth(), 8));
1213 return .fromNonzeroByteUnits(@divExact(target.ptrBitWidth(), 8));
16161214}
1617
1618pub fn bitSize(ty: Type, zcu: *const Zcu) u64 {
1619 return bitSizeInner(ty, .normal, zcu, {}) catch unreachable;
1215pub fn ptrAbiSize(target: *const Target) u64 {
1216 return @divExact(target.ptrBitWidth(), 8);
16201217}
1621
1622pub fn bitSizeSema(ty: Type, pt: Zcu.PerThread) SemaError!u64 {
1623 return bitSizeInner(ty, .sema, pt.zcu, pt.tid);
1218pub fn errorAbiAlignment(zcu: *const Zcu) Alignment {
1219 return .fromNonzeroByteUnits(std.zig.target.intAlignment(zcu.getTarget(), zcu.errorSetBits()));
1220}
1221pub fn errorAbiSize(zcu: *const Zcu) u64 {
1222 return std.zig.target.intByteSize(zcu.getTarget(), zcu.errorSetBits());
16241223}
16251224
1626pub fn bitSizeInner(
1627 ty: Type,
1628 comptime strat: ResolveStrat,
1629 zcu: strat.ZcuPtr(),
1630 tid: strat.Tid(),
1631) SemaError!u64 {
1225/// Asserts that `ty` is not an opaque or comptime-only type.
1226/// Once #19755 is implemented, this query will only work on types with a defined bit-level representation.
1227pub fn bitSize(ty: Type, zcu: *const Zcu) u64 {
16321228 const target = zcu.getTarget();
16331229 const ip = &zcu.intern_pool;
1634
1635 const strat_lazy: ResolveStratLazy = strat.toLazy();
1636
1637 switch (ip.indexToKey(ty.toIntern())) {
1638 .int_type => |int_type| return int_type.bits,
1230 assertHasLayout(ty, zcu);
1231 return switch (ip.indexToKey(ty.toIntern())) {
1232 .int_type => |int_type| int_type.bits,
16391233 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
1640 .slice => return target.ptrBitWidth() * 2,
1641 else => return target.ptrBitWidth(),
1234 .slice => target.ptrBitWidth() * 2,
1235 else => target.ptrBitWidth(),
16421236 },
1643 .anyframe_type => return target.ptrBitWidth(),
1644
1237 .anyframe_type => target.ptrBitWidth(),
16451238 .array_type => |array_type| {
1646 const len = array_type.lenIncludingSentinel();
1647 if (len == 0) return 0;
16481239 const elem_ty: Type = .fromInterned(array_type.child);
1649 switch (zcu.comp.getZigBackend()) {
1650 else => {
1651 const elem_size = (try elem_ty.abiSizeInner(strat_lazy, zcu, tid)).scalar;
1652 if (elem_size == 0) return 0;
1653 const elem_bit_size = try elem_ty.bitSizeInner(strat, zcu, tid);
1654 return (len - 1) * 8 * elem_size + elem_bit_size;
1655 },
1656 .stage2_x86_64 => {
1657 const elem_bit_size = try elem_ty.bitSizeInner(strat, zcu, tid);
1658 return elem_bit_size * len;
1240 const len = array_type.lenIncludingSentinel();
1241 return switch (zcu.comp.getZigBackend()) {
1242 .stage2_x86_64 => len * elem_ty.bitSize(zcu),
1243 // this case will be removed under #19755
1244 else => switch (len) {
1245 0 => 0,
1246 else => (len - 1) * 8 * elem_ty.abiSize(zcu) + elem_ty.bitSize(zcu),
16591247 },
1660 }
1661 },
1662 .vector_type => |vector_type| {
1663 const child_ty: Type = .fromInterned(vector_type.child);
1664 const elem_bit_size = try child_ty.bitSizeInner(strat, zcu, tid);
1665 return elem_bit_size * vector_type.len;
1666 },
1667 .opt_type => {
1668 // Optionals and error unions are not packed so their bitsize
1669 // includes padding bits.
1670 return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8;
1248 };
16711249 },
1250 .vector_type => |vec| vec.len * Type.fromInterned(vec.child).bitSize(zcu),
1251 .error_set_type, .inferred_error_set_type => zcu.errorSetBits(),
1252 .func_type => unreachable,
16721253
1673 .error_set_type, .inferred_error_set_type => return zcu.errorSetBits(),
1674
1675 .error_union_type => {
1676 // Optionals and error unions are not packed so their bitsize
1677 // includes padding bits.
1678 return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8;
1679 },
1680 .func_type => unreachable, // represents machine code; not a pointer
16811254 .simple_type => |t| switch (t) {
1682 .f16 => return 16,
1683 .f32 => return 32,
1684 .f64 => return 64,
1685 .f80 => return 80,
1686 .f128 => return 128,
1687
1688 .usize,
1689 .isize,
1690 => return target.ptrBitWidth(),
1691
1692 .c_char => return target.cTypeBitSize(.char),
1693 .c_short => return target.cTypeBitSize(.short),
1694 .c_ushort => return target.cTypeBitSize(.ushort),
1695 .c_int => return target.cTypeBitSize(.int),
1696 .c_uint => return target.cTypeBitSize(.uint),
1697 .c_long => return target.cTypeBitSize(.long),
1698 .c_ulong => return target.cTypeBitSize(.ulong),
1699 .c_longlong => return target.cTypeBitSize(.longlong),
1700 .c_ulonglong => return target.cTypeBitSize(.ulonglong),
1701 .c_longdouble => return target.cTypeBitSize(.longdouble),
1702
1703 .bool => return 1,
1704 .void => return 0,
1705
1706 .anyerror,
1707 .adhoc_inferred_error_set,
1708 => return zcu.errorSetBits(),
1255 .void => 0,
1256 .bool => 1,
1257 .anyerror, .adhoc_inferred_error_set => zcu.errorSetBits(),
1258 .usize, .isize => target.ptrBitWidth(),
1259
1260 .c_char => target.cTypeBitSize(.char),
1261 .c_short => target.cTypeBitSize(.short),
1262 .c_ushort => target.cTypeBitSize(.ushort),
1263 .c_int => target.cTypeBitSize(.int),
1264 .c_uint => target.cTypeBitSize(.uint),
1265 .c_long => target.cTypeBitSize(.long),
1266 .c_ulong => target.cTypeBitSize(.ulong),
1267 .c_longlong => target.cTypeBitSize(.longlong),
1268 .c_ulonglong => target.cTypeBitSize(.ulonglong),
1269 .c_longdouble => target.cTypeBitSize(.longdouble),
1270
1271 .f16 => 16,
1272 .f32 => 32,
1273 .f64 => 64,
1274 .f80 => 80,
1275 .f128 => 128,
17091276
17101277 .anyopaque => unreachable,
17111278 .type => unreachable,
......@@ -1717,49 +1284,30 @@ pub fn bitSizeInner(
17171284 .enum_literal => unreachable,
17181285 .generic_poison => unreachable,
17191286 },
1287
17201288 .struct_type => {
1721 const struct_type = ip.loadStructType(ty.toIntern());
1722 const is_packed = struct_type.layout == .@"packed";
1723 if (strat == .sema) {
1724 const pt = strat.pt(zcu, tid);
1725 try ty.resolveFields(pt);
1726 if (is_packed) try ty.resolveLayout(pt);
1727 }
1728 if (is_packed) {
1729 return try Type.fromInterned(struct_type.backingIntTypeUnordered(ip))
1730 .bitSizeInner(strat, zcu, tid);
1289 const struct_obj = ip.loadStructType(ty.toIntern());
1290 switch (struct_obj.layout) {
1291 .@"packed" => return Type.fromInterned(struct_obj.packed_backing_int_type).bitSize(zcu),
1292 .auto, .@"extern" => return struct_obj.size * 8, // will be `unreachable` under #19755
17311293 }
1732 return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8;
17331294 },
1734
1735 .tuple_type => {
1736 return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8;
1737 },
1738
17391295 .union_type => {
1740 const union_type = ip.loadUnionType(ty.toIntern());
1741 const is_packed = ty.containerLayout(zcu) == .@"packed";
1742 if (strat == .sema) {
1743 const pt = strat.pt(zcu, tid);
1744 try ty.resolveFields(pt);
1745 if (is_packed) try ty.resolveLayout(pt);
1746 }
1747 if (!is_packed) {
1748 return (try ty.abiSizeInner(strat_lazy, zcu, tid)).scalar * 8;
1296 const union_obj = ip.loadUnionType(ty.toIntern());
1297 switch (union_obj.layout) {
1298 .@"packed" => return Type.fromInterned(union_obj.packed_backing_int_type).bitSize(zcu),
1299 .auto, .@"extern" => return union_obj.size * 8, // will be `unreachable` under #19755
17491300 }
1750 assert(union_type.flagsUnordered(ip).status.haveFieldTypes());
1301 },
1302 .enum_type => Type.fromInterned(ip.loadEnumType(ty.toIntern()).int_tag_type).bitSize(zcu),
17511303
1752 var size: u64 = 0;
1753 for (0..union_type.field_types.len) |field_index| {
1754 const field_ty = union_type.field_types.get(ip)[field_index];
1755 size = @max(size, try Type.fromInterned(field_ty).bitSizeInner(strat, zcu, tid));
1756 }
1304 // will be `unreachable` under #19755
1305 .opt_type,
1306 .error_union_type,
1307 .tuple_type,
1308 => ty.abiSize(zcu) * 8,
17571309
1758 return size;
1759 },
17601310 .opaque_type => unreachable,
1761 .enum_type => return Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty)
1762 .bitSizeInner(strat, zcu, tid),
17631311
17641312 // values, not types
17651313 .undef,
......@@ -1772,33 +1320,16 @@ pub fn bitSizeInner(
17721320 .error_union,
17731321 .enum_literal,
17741322 .enum_tag,
1775 .empty_enum_value,
17761323 .float,
17771324 .ptr,
1778 .slice,
1779 .opt,
1780 .aggregate,
1781 .un,
1782 // memoization, not types
1783 .memoized_call,
1784 => unreachable,
1785 }
1786}
1787
1788/// Returns true if the type's layout is already resolved and it is safe
1789/// to use `abiSize`, `abiAlignment` and `bitSize` on it.
1790pub fn layoutIsResolved(ty: Type, zcu: *const Zcu) bool {
1791 const ip = &zcu.intern_pool;
1792 return switch (ip.indexToKey(ty.toIntern())) {
1793 .struct_type => ip.loadStructType(ty.toIntern()).haveLayout(ip),
1794 .union_type => ip.loadUnionType(ty.toIntern()).haveLayout(ip),
1795 .array_type => |array_type| {
1796 if (array_type.lenIncludingSentinel() == 0) return true;
1797 return Type.fromInterned(array_type.child).layoutIsResolved(zcu);
1798 },
1799 .opt_type => |child| Type.fromInterned(child).layoutIsResolved(zcu),
1800 .error_union_type => |k| Type.fromInterned(k.payload_type).layoutIsResolved(zcu),
1801 else => true,
1325 .slice,
1326 .opt,
1327 .aggregate,
1328 .un,
1329 .bitpack,
1330 // memoization, not types
1331 .memoized_call,
1332 => unreachable,
18021333 };
18031334}
18041335
......@@ -1841,7 +1372,7 @@ pub fn isSliceAtRuntime(ty: Type, zcu: *const Zcu) bool {
18411372}
18421373
18431374pub fn slicePtrFieldType(ty: Type, zcu: *const Zcu) Type {
1844 return Type.fromInterned(zcu.intern_pool.slicePtrType(ty.toIntern()));
1375 return .fromInterned(zcu.intern_pool.slicePtrType(ty.toIntern()));
18451376}
18461377
18471378pub fn isConstPtr(ty: Type, zcu: *const Zcu) bool {
......@@ -1897,10 +1428,7 @@ pub fn isPtrAtRuntime(ty: Type, zcu: *const Zcu) bool {
18971428/// For pointer-like optionals, returns true, otherwise returns the allowzero property
18981429/// of pointers.
18991430pub fn ptrAllowsZero(ty: Type, zcu: *const Zcu) bool {
1900 if (ty.isPtrLikeOptional(zcu)) {
1901 return true;
1902 }
1903 return ty.ptrInfo(zcu).flags.is_allowzero;
1431 return ty.isPtrLikeOptional(zcu) or ty.ptrInfo(zcu).flags.is_allowzero;
19041432}
19051433
19061434/// See also `isPtrLikeOptional`.
......@@ -1918,7 +1446,6 @@ pub fn optionalReprIsPayload(ty: Type, zcu: *const Zcu) bool {
19181446
19191447/// Returns true if the type is optional and would be lowered to a single pointer
19201448/// address value, using 0 for null. Note that this returns true for C pointers.
1921/// This function must be kept in sync with `Sema.typePtrOrOptionalPtrTy`.
19221449pub fn isPtrLikeOptional(ty: Type, zcu: *const Zcu) bool {
19231450 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
19241451 .ptr_type => |ptr_type| ptr_type.flags.size == .c,
......@@ -1947,52 +1474,54 @@ pub fn childTypeIp(ty: Type, ip: *const InternPool) Type {
19471474 return Type.fromInterned(ip.childType(ty.toIntern()));
19481475}
19491476
1950/// For `*[N]T`, returns `T`.
1951/// For `?*T`, returns `T`.
1952/// For `?*[N]T`, returns `T`.
1953/// For `?[*]T`, returns `T`.
1954/// For `*T`, returns `T`.
1955/// For `[*]T`, returns `T`.
1956/// For `[N]T`, returns `T`.
1957/// For `[]T`, returns `T`.
1958/// For `anyframe->T`, returns `T`.
1959pub fn elemType2(ty: Type, zcu: *const Zcu) Type {
1960 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1961 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
1962 .one => Type.fromInterned(ptr_type.child).shallowElemType(zcu),
1963 .many, .c, .slice => Type.fromInterned(ptr_type.child),
1964 },
1965 .anyframe_type => |child| {
1966 assert(child != .none);
1967 return Type.fromInterned(child);
1477/// Similar to `childType`, but for pointer-like (or slice-like) optionals, gets the child type
1478/// of the *pointer* type. Asserts that `ty` is either a pointer or a pointer-like optional.
1479///
1480/// Essentially, unwraps any one of the following into `T`:
1481/// ```
1482/// *T ?*T *allowzero T
1483/// [*]T ?[*]T [*]allowzero T
1484/// []T ?[]T []allowzero T
1485/// [*c]T
1486/// ```
1487/// This is primarily useful in Sema to implement operations which can act on optional pointers.
1488pub fn nullablePtrElem(ty: Type, zcu: *const Zcu) Type {
1489 switch (ty.zigTypeTag(zcu)) {
1490 .pointer => return ty.childType(zcu),
1491 .optional => {
1492 const ptr_ty = ty.childType(zcu);
1493 const ptr_info = zcu.intern_pool.indexToKey(ptr_ty.toIntern()).ptr_type;
1494 assert(ptr_info.flags.size != .c);
1495 assert(!ptr_info.flags.is_allowzero);
1496 return .fromInterned(ptr_info.child);
19681497 },
1969 .vector_type => |vector_type| Type.fromInterned(vector_type.child),
1970 .array_type => |array_type| Type.fromInterned(array_type.child),
1971 .opt_type => |child| Type.fromInterned(zcu.intern_pool.childType(child)),
19721498 else => unreachable,
1973 };
1974}
1975
1976/// Given that `ty` is an indexable pointer, returns its element type. Specifically:
1977/// * for `*[n]T`, returns `T`
1978/// * for `[]T`, returns `T`
1979/// * for `[*]T`, returns `T`
1980/// * for `[*c]T`, returns `T`
1981pub fn indexablePtrElem(ty: Type, zcu: *const Zcu) Type {
1982 const ip = &zcu.intern_pool;
1983 const ptr_type = ip.indexToKey(ty.toIntern()).ptr_type;
1984 switch (ptr_type.flags.size) {
1985 .many, .slice, .c => return .fromInterned(ptr_type.child),
1986 .one => {},
19871499 }
1988 const array_type = ip.indexToKey(ptr_type.child).array_type;
1989 return .fromInterned(array_type.child);
19901500}
19911501
1992fn shallowElemType(child_ty: Type, zcu: *const Zcu) Type {
1993 return switch (child_ty.zigTypeTag(zcu)) {
1994 .array, .vector => child_ty.childType(zcu),
1995 else => child_ty,
1502/// Asserts that `ty` is an indexable type, and returns its element type. Tuples (and pointers to
1503/// tuples) are not supported because they do not have a single element type.
1504///
1505/// Returns `T` for each of the following types:
1506/// * `[n]T`
1507/// * `@Vector(n, T)`
1508/// * `*[n]T`
1509/// * `*@Vector(n, T)`
1510/// * `[]T`
1511/// * `[*]T`
1512/// * `[*c]T`
1513pub fn indexableElem(ty: Type, zcu: *const Zcu) Type {
1514 const ip = &zcu.intern_pool;
1515 return switch (ip.indexToKey(ty.toIntern())) {
1516 inline .array_type, .vector_type => |arr| .fromInterned(arr.child),
1517 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
1518 .many, .slice, .c => .fromInterned(ptr_type.child),
1519 .one => switch (ip.indexToKey(ptr_type.child)) {
1520 inline .array_type, .vector_type => |arr| .fromInterned(arr.child),
1521 else => unreachable,
1522 },
1523 },
1524 else => unreachable,
19961525 };
19971526}
19981527
......@@ -2004,61 +1533,54 @@ pub fn scalarType(ty: Type, zcu: *const Zcu) Type {
20041533 };
20051534}
20061535
2007/// Asserts that the type is an optional.
2008/// Note that for C pointers this returns the type unmodified.
1536/// Asserts that the type is an optional, or a C pointer.
1537/// For C pointers this returns the type unmodified.
20091538pub fn optionalChild(ty: Type, zcu: *const Zcu) Type {
2010 return switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
2011 .opt_type => |child| Type.fromInterned(child),
2012 .ptr_type => |ptr_type| b: {
1539 switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
1540 .opt_type => |child| return .fromInterned(child),
1541 .ptr_type => |ptr_type| {
20131542 assert(ptr_type.flags.size == .c);
2014 break :b ty;
1543 return ty;
20151544 },
20161545 else => unreachable,
2017 };
1546 }
20181547}
20191548
2020/// Returns the tag type of a union, if the type is a union and it has a tag type.
2021/// Otherwise, returns `null`.
1549/// If `ty` is a tagged union, returns its tag type. Otherwise, returns `null`.
20221550pub fn unionTagType(ty: Type, zcu: *const Zcu) ?Type {
1551 assertHasLayout(ty, zcu);
20231552 const ip = &zcu.intern_pool;
20241553 switch (ip.indexToKey(ty.toIntern())) {
20251554 .union_type => {},
20261555 else => return null,
20271556 }
2028 const union_type = ip.loadUnionType(ty.toIntern());
2029 const union_flags = union_type.flagsUnordered(ip);
2030 switch (union_flags.runtime_tag) {
2031 .tagged => {
2032 assert(union_flags.status.haveFieldTypes());
2033 return Type.fromInterned(union_type.enum_tag_ty);
2034 },
2035 else => return null,
2036 }
1557 const union_obj = ip.loadUnionType(ty.toIntern());
1558 return switch (union_obj.tag_usage) {
1559 .tagged => .fromInterned(union_obj.enum_tag_type),
1560 .none, .safety => null,
1561 };
20371562}
20381563
2039/// Same as `unionTagType` but includes safety tag.
2040/// Codegen should use this version.
2041pub fn unionTagTypeSafety(ty: Type, zcu: *const Zcu) ?Type {
2042 const ip = &zcu.intern_pool;
2043 return switch (ip.indexToKey(ty.toIntern())) {
2044 .union_type => {
2045 const union_type = ip.loadUnionType(ty.toIntern());
2046 if (!union_type.hasTag(ip)) return null;
2047 assert(union_type.haveFieldTypes(ip));
2048 return Type.fromInterned(union_type.enum_tag_ty);
2049 },
2050 else => null,
2051 };
1564/// If the given union type contains a tag (including a safety tag) in its runtime layout, returns
1565/// its enum tag type. Otherwise, returns null. Asserts that `ty` is a union type.
1566///
1567/// In general, codegen logic should call this function instead of `unionTagType`.
1568pub fn unionTagTypeRuntime(ty: Type, zcu: *const Zcu) ?Type {
1569 assertHasLayout(ty, zcu);
1570 const union_type = zcu.intern_pool.loadUnionType(ty.toIntern());
1571 if (!union_type.has_runtime_tag) return null;
1572 return .fromInterned(union_type.enum_tag_type);
20521573}
20531574
2054/// Asserts the type is a union; returns the tag type, even if the tag will
2055/// not be stored at runtime.
1575/// Asserts that `ty` is a union type, and returns its tag type, even if the tag will not be stored at runtime.
20561576pub fn unionTagTypeHypothetical(ty: Type, zcu: *const Zcu) Type {
2057 const union_obj = zcu.typeToUnion(ty).?;
2058 return Type.fromInterned(union_obj.enum_tag_ty);
1577 assertHasLayout(ty, zcu);
1578 const union_obj = zcu.intern_pool.loadUnionType(ty.toIntern());
1579 return .fromInterned(union_obj.enum_tag_type);
20591580}
20601581
20611582pub fn unionFieldType(ty: Type, enum_tag: Value, zcu: *const Zcu) ?Type {
1583 assertHasLayout(ty, zcu);
20621584 const ip = &zcu.intern_pool;
20631585 const union_obj = zcu.typeToUnion(ty).?;
20641586 const union_fields = union_obj.field_types.get(ip);
......@@ -2067,17 +1589,20 @@ pub fn unionFieldType(ty: Type, enum_tag: Value, zcu: *const Zcu) ?Type {
20671589}
20681590
20691591pub fn unionFieldTypeByIndex(ty: Type, index: usize, zcu: *const Zcu) Type {
1592 assertHasLayout(ty, zcu);
20701593 const ip = &zcu.intern_pool;
20711594 const union_obj = zcu.typeToUnion(ty).?;
20721595 return Type.fromInterned(union_obj.field_types.get(ip)[index]);
20731596}
20741597
20751598pub fn unionTagFieldIndex(ty: Type, enum_tag: Value, zcu: *const Zcu) ?u32 {
1599 assertHasLayout(ty, zcu);
20761600 const union_obj = zcu.typeToUnion(ty).?;
20771601 return zcu.unionTagFieldIndex(union_obj, enum_tag);
20781602}
20791603
20801604pub fn unionHasAllZeroBitFieldTypes(ty: Type, zcu: *Zcu) bool {
1605 assertHasLayout(ty, zcu);
20811606 const ip = &zcu.intern_pool;
20821607 const union_obj = zcu.typeToUnion(ty).?;
20831608 for (union_obj.field_types.get(ip)) |field_ty| {
......@@ -2087,17 +1612,21 @@ pub fn unionHasAllZeroBitFieldTypes(ty: Type, zcu: *Zcu) bool {
20871612}
20881613
20891614/// Returns the type used for backing storage of this union during comptime operations.
2090/// Asserts the type is either an extern or packed union.
2091pub fn unionBackingType(ty: Type, pt: Zcu.PerThread) !Type {
1615/// Asserts the type is an extern union.
1616pub fn externUnionBackingType(ty: Type, pt: Zcu.PerThread) !Type {
20921617 const zcu = pt.zcu;
2093 return switch (ty.containerLayout(zcu)) {
2094 .@"extern" => try pt.arrayType(.{ .len = ty.abiSize(zcu), .child = .u8_type }),
2095 .@"packed" => try pt.intType(.unsigned, @intCast(ty.bitSize(zcu))),
1618 assertHasLayout(ty, zcu);
1619 const loaded_union = zcu.intern_pool.loadUnionType(ty.toIntern());
1620 switch (loaded_union.layout) {
1621 .@"extern" => return pt.arrayType(.{ .len = ty.abiSize(zcu), .child = .u8_type }),
1622 .@"packed" => unreachable,
20961623 .auto => unreachable,
2097 };
1624 }
20981625}
20991626
1627/// Asserts that `ty` is a non-packed union type.
21001628pub fn unionGetLayout(ty: Type, zcu: *const Zcu) Zcu.UnionLayout {
1629 assertHasLayout(ty, zcu);
21011630 const union_obj = zcu.intern_pool.loadUnionType(ty.toIntern());
21021631 return Type.getUnionLayout(union_obj, zcu);
21031632}
......@@ -2105,9 +1634,18 @@ pub fn unionGetLayout(ty: Type, zcu: *const Zcu) Zcu.UnionLayout {
21051634pub fn containerLayout(ty: Type, zcu: *const Zcu) std.builtin.Type.ContainerLayout {
21061635 const ip = &zcu.intern_pool;
21071636 return switch (ip.indexToKey(ty.toIntern())) {
2108 .struct_type => ip.loadStructType(ty.toIntern()).layout,
21091637 .tuple_type => .auto,
2110 .union_type => ip.loadUnionType(ty.toIntern()).flagsUnordered(ip).layout,
1638 .struct_type => ip.loadStructType(ty.toIntern()).layout,
1639 .union_type => ip.loadUnionType(ty.toIntern()).layout,
1640 else => unreachable,
1641 };
1642}
1643
1644pub fn bitpackBackingInt(ty: Type, zcu: *const Zcu) Type {
1645 const ip = &zcu.intern_pool;
1646 return switch (ip.indexToKey(ty.toIntern())) {
1647 .struct_type => .fromInterned(ip.loadStructType(ty.toIntern()).packed_backing_int_type),
1648 .union_type => .fromInterned(ip.loadUnionType(ty.toIntern()).packed_backing_int_type),
21111649 else => unreachable,
21121650 };
21131651}
......@@ -2123,6 +1661,11 @@ pub fn errorUnionSet(ty: Type, zcu: *const Zcu) Type {
21231661}
21241662
21251663/// Returns false for unresolved inferred error sets.
1664///
1665/// TODO: this function will behave incorrectly under incremental compilation, because in that case
1666/// it may see an outdated resolved error set. This function must be either deleted, or its contract
1667/// changed to require the caller to resolve the error set beforehand. If you must introduce new
1668/// call sites, please make sure the error set in question is definitely resolved first!
21261669pub fn errorSetIsEmpty(ty: Type, zcu: *const Zcu) bool {
21271670 const ip = &zcu.intern_pool;
21281671 return switch (ty.toIntern()) {
......@@ -2141,6 +1684,11 @@ pub fn errorSetIsEmpty(ty: Type, zcu: *const Zcu) bool {
21411684/// Returns true if it is an error set that includes anyerror, false otherwise.
21421685/// Note that the result may be a false negative if the type did not get error set
21431686/// resolution prior to this call.
1687///
1688/// TODO: this function will behave incorrectly under incremental compilation, because in that case
1689/// it may see an outdated resolved error set. This function must be either deleted, or its contract
1690/// changed to require the caller to resolve the error set beforehand. If you must introduce new
1691/// call sites, please make sure the error set in question is definitely resolved first!
21441692pub fn isAnyError(ty: Type, zcu: *const Zcu) bool {
21451693 const ip = &zcu.intern_pool;
21461694 return switch (ty.toIntern()) {
......@@ -2163,46 +1711,25 @@ pub fn isError(ty: Type, zcu: *const Zcu) bool {
21631711/// Returns whether ty, which must be an error set, includes an error `name`.
21641712/// Might return a false negative if `ty` is an inferred error set and not fully
21651713/// resolved yet.
2166pub fn errorSetHasFieldIp(
2167 ip: *const InternPool,
2168 ty: InternPool.Index,
1714///
1715/// TODO: this function will behave incorrectly under incremental compilation, because in that case
1716/// it may see an outdated resolved error set. This function must be either deleted, or its contract
1717/// changed to require the caller to resolve the error set beforehand. If you must introduce new
1718/// call sites, please make sure the error set in question is definitely resolved first!
1719pub fn errorSetHasField(
1720 ty: Type,
21691721 name: InternPool.NullTerminatedString,
1722 zcu: *const Zcu,
21701723) bool {
2171 return switch (ty) {
2172 .anyerror_type => true,
2173 else => switch (ip.indexToKey(ty)) {
2174 .error_set_type => |error_set_type| error_set_type.nameIndex(ip, name) != null,
2175 .inferred_error_set_type => |i| switch (ip.funcIesResolvedUnordered(i)) {
2176 .anyerror_type => true,
2177 .none => false,
2178 else => |t| ip.indexToKey(t).error_set_type.nameIndex(ip, name) != null,
2179 },
2180 else => unreachable,
2181 },
2182 };
2183}
2184
2185/// Returns whether ty, which must be an error set, includes an error `name`.
2186/// Might return a false negative if `ty` is an inferred error set and not fully
2187/// resolved yet.
2188pub fn errorSetHasField(ty: Type, name: []const u8, zcu: *const Zcu) bool {
21891724 const ip = &zcu.intern_pool;
21901725 return switch (ty.toIntern()) {
21911726 .anyerror_type => true,
21921727 else => switch (ip.indexToKey(ty.toIntern())) {
2193 .error_set_type => |error_set_type| {
2194 // If the string is not interned, then the field certainly is not present.
2195 const field_name_interned = ip.getString(name).unwrap() orelse return false;
2196 return error_set_type.nameIndex(ip, field_name_interned) != null;
2197 },
1728 .error_set_type => |error_set_type| error_set_type.nameIndex(ip, name) != null,
21981729 .inferred_error_set_type => |i| switch (ip.funcIesResolvedUnordered(i)) {
21991730 .anyerror_type => true,
22001731 .none => false,
2201 else => |t| {
2202 // If the string is not interned, then the field certainly is not present.
2203 const field_name_interned = ip.getString(name).unwrap() orelse return false;
2204 return ip.indexToKey(t).error_set_type.nameIndex(ip, field_name_interned) != null;
2205 },
1732 else => |t| ip.indexToKey(t).error_set_type.nameIndex(ip, name) != null,
22061733 },
22071734 else => unreachable,
22081735 },
......@@ -2275,12 +1802,12 @@ pub fn isUnsignedInt(ty: Type, zcu: *const Zcu) bool {
22751802 };
22761803}
22771804
2278/// Returns true for integers, enums, error sets, and packed structs.
1805/// Returns true for integers, enums, error sets, and packed structs/unions.
22791806/// If this function returns true, then intInfo() can be called on the type.
22801807pub fn isAbiInt(ty: Type, zcu: *const Zcu) bool {
22811808 return switch (ty.zigTypeTag(zcu)) {
22821809 .int, .@"enum", .error_set => true,
2283 .@"struct" => ty.containerLayout(zcu) == .@"packed",
1810 .@"struct", .@"union" => ty.containerLayout(zcu) == .@"packed",
22841811 else => false,
22851812 };
22861813}
......@@ -2308,8 +1835,17 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {
23081835 .c_ulonglong_type => return .{ .signedness = .unsigned, .bits = target.cTypeBitSize(.ulonglong) },
23091836 else => switch (ip.indexToKey(ty.toIntern())) {
23101837 .int_type => |int_type| return int_type,
2311 .struct_type => ty = Type.fromInterned(ip.loadStructType(ty.toIntern()).backingIntTypeUnordered(ip)),
2312 .enum_type => ty = Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty),
1838 .struct_type => {
1839 const struct_obj = ip.loadStructType(ty.toIntern());
1840 assert(struct_obj.layout == .@"packed");
1841 ty = .fromInterned(struct_obj.packed_backing_int_type);
1842 },
1843 .union_type => {
1844 const union_obj = ip.loadUnionType(ty.toIntern());
1845 assert(union_obj.layout == .@"packed");
1846 ty = .fromInterned(union_obj.packed_backing_int_type);
1847 },
1848 .enum_type => ty = .fromInterned(ip.loadEnumType(ty.toIntern()).int_tag_type),
23131849 .vector_type => |vector_type| ty = Type.fromInterned(vector_type.child),
23141850
23151851 .error_set_type, .inferred_error_set_type => {
......@@ -2327,7 +1863,6 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {
23271863 .func_type => unreachable,
23281864 .simple_type => unreachable, // handled via Index enum tag above
23291865
2330 .union_type => unreachable,
23311866 .opaque_type => unreachable,
23321867
23331868 // values, not types
......@@ -2341,13 +1876,13 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {
23411876 .error_union,
23421877 .enum_literal,
23431878 .enum_tag,
2344 .empty_enum_value,
23451879 .float,
23461880 .ptr,
23471881 .slice,
23481882 .opt,
23491883 .aggregate,
23501884 .un,
1885 .bitpack,
23511886 // memoization, not types
23521887 .memoized_call,
23531888 => unreachable,
......@@ -2355,25 +1890,6 @@ pub fn intInfo(starting_ty: Type, zcu: *const Zcu) InternPool.Key.IntType {
23551890 };
23561891}
23571892
2358pub fn isNamedInt(ty: Type) bool {
2359 return switch (ty.toIntern()) {
2360 .usize_type,
2361 .isize_type,
2362 .c_char_type,
2363 .c_short_type,
2364 .c_ushort_type,
2365 .c_int_type,
2366 .c_uint_type,
2367 .c_long_type,
2368 .c_ulong_type,
2369 .c_longlong_type,
2370 .c_ulonglong_type,
2371 => true,
2372
2373 else => false,
2374 };
2375}
2376
23771893/// Returns `false` for `comptime_float`.
23781894pub fn isRuntimeFloat(ty: Type) bool {
23791895 return switch (ty.toIntern()) {
......@@ -2488,429 +2004,181 @@ pub fn isNumeric(ty: Type, zcu: *const Zcu) bool {
24882004 };
24892005}
24902006
2491/// During semantic analysis, instead call `Sema.typeHasOnePossibleValue` which
2492/// resolves field types rather than asserting they are already resolved.
2493pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {
2007/// If the type's classification is `Class.one_possible_value` (see `classify`), returns the only
2008/// possible value for the type. Otherwise, returns `null`.
2009pub fn onePossibleValue(ty: Type, pt: Zcu.PerThread) !?Value {
24942010 const zcu = pt.zcu;
24952011 const comp = zcu.comp;
24962012 const gpa = comp.gpa;
2497 const io = comp.io;
24982013 const ip = &zcu.intern_pool;
2499 var ty = starting_type;
2500 while (true) switch (ty.toIntern()) {
2501 .empty_tuple_type => return Value.empty_tuple,
2502
2503 else => switch (ip.indexToKey(ty.toIntern())) {
2504 .int_type => |int_type| {
2505 if (int_type.bits == 0) {
2506 return try pt.intValue(ty, 0);
2507 } else {
2508 return null;
2509 }
2510 },
2511
2512 .ptr_type,
2513 .error_union_type,
2514 .func_type,
2515 .anyframe_type,
2516 .error_set_type,
2517 .inferred_error_set_type,
2518 => return null,
2519
2520 inline .array_type, .vector_type => |seq_type, seq_tag| {
2521 const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none;
2522 if (seq_type.len + @intFromBool(has_sentinel) == 0) {
2523 return try pt.aggregateValue(ty, &.{});
2524 }
2525 if (try Type.fromInterned(seq_type.child).onePossibleValue(pt)) |opv| {
2526 return try pt.aggregateSplatValue(ty, opv);
2527 }
2528 return null;
2529 },
2530 .opt_type => |child| {
2531 if (child == .noreturn_type) {
2532 return try pt.nullValue(ty);
2533 } else {
2534 return null;
2535 }
2536 },
2537
2538 .simple_type => |t| switch (t) {
2539 .f16,
2540 .f32,
2541 .f64,
2542 .f80,
2543 .f128,
2544 .usize,
2545 .isize,
2546 .c_char,
2547 .c_short,
2548 .c_ushort,
2549 .c_int,
2550 .c_uint,
2551 .c_long,
2552 .c_ulong,
2553 .c_longlong,
2554 .c_ulonglong,
2555 .c_longdouble,
2556 .anyopaque,
2557 .bool,
2558 .type,
2559 .anyerror,
2560 .comptime_int,
2561 .comptime_float,
2562 .enum_literal,
2563 .adhoc_inferred_error_set,
2564 => return null,
2565
2566 .void => return Value.void,
2567 .noreturn => return Value.@"unreachable",
2568 .null => return Value.null,
2569 .undefined => return Value.undef,
2570
2571 .generic_poison => unreachable,
2572 },
2573 .struct_type => {
2574 const struct_type = ip.loadStructType(ty.toIntern());
2575 assert(struct_type.haveFieldTypes(ip));
2576 if (struct_type.knownNonOpv(ip))
2577 return null;
2578 const field_vals = try zcu.gpa.alloc(InternPool.Index, struct_type.field_types.len);
2579 defer zcu.gpa.free(field_vals);
2580 for (field_vals, 0..) |*field_val, i_usize| {
2581 const i: u32 = @intCast(i_usize);
2582 if (struct_type.fieldIsComptime(ip, i)) {
2583 assert(struct_type.haveFieldInits(ip));
2584 field_val.* = struct_type.field_inits.get(ip)[i];
2585 continue;
2586 }
2587 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
2588 if (try field_ty.onePossibleValue(pt)) |field_opv| {
2589 field_val.* = field_opv.toIntern();
2590 } else return null;
2591 }
2592
2593 // In this case the struct has no runtime-known fields and
2594 // therefore has one possible value.
2595 return try pt.aggregateValue(ty, field_vals);
2596 },
2597
2598 .tuple_type => |tuple| {
2599 if (tuple.types.len == 0) {
2600 return try pt.aggregateValue(ty, &.{});
2601 }
2602
2603 const field_vals = try zcu.gpa.alloc(
2604 InternPool.Index,
2605 tuple.types.len,
2606 );
2607 defer zcu.gpa.free(field_vals);
2608 for (
2609 field_vals,
2610 tuple.types.get(ip),
2611 tuple.values.get(ip),
2612 ) |*field_val, field_ty, field_comptime_val| {
2613 if (field_comptime_val != .none) {
2614 field_val.* = field_comptime_val;
2615 continue;
2616 }
2617 if (try Type.fromInterned(field_ty).onePossibleValue(pt)) |opv| {
2618 field_val.* = opv.toIntern();
2619 } else return null;
2620 }
2621
2622 return try pt.aggregateValue(ty, field_vals);
2623 },
2624
2625 .union_type => {
2626 const union_obj = ip.loadUnionType(ty.toIntern());
2627 const tag_val = (try Type.fromInterned(union_obj.enum_tag_ty).onePossibleValue(pt)) orelse
2628 return null;
2629 if (union_obj.field_types.len == 0) {
2630 const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() });
2631 return Value.fromInterned(only);
2632 }
2633 const only_field_ty = union_obj.field_types.get(ip)[0];
2634 const val_val = (try Type.fromInterned(only_field_ty).onePossibleValue(pt)) orelse
2635 return null;
2636 const only = try pt.internUnion(.{
2637 .ty = ty.toIntern(),
2638 .tag = tag_val.toIntern(),
2639 .val = val_val.toIntern(),
2640 });
2641 return Value.fromInterned(only);
2642 },
2643 .opaque_type => return null,
2644 .enum_type => {
2645 const enum_type = ip.loadEnumType(ty.toIntern());
2646 switch (enum_type.tag_mode) {
2647 .nonexhaustive => {
2648 if (enum_type.tag_ty == .comptime_int_type) return null;
2649
2650 if (try Type.fromInterned(enum_type.tag_ty).onePossibleValue(pt)) |int_opv| {
2651 const only = try pt.intern(.{ .enum_tag = .{
2652 .ty = ty.toIntern(),
2653 .int = int_opv.toIntern(),
2654 } });
2655 return Value.fromInterned(only);
2656 }
2657
2658 return null;
2659 },
2660 .auto, .explicit => {
2661 if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(zcu)) return null;
2662
2663 return Value.fromInterned(switch (enum_type.names.len) {
2664 0 => try pt.intern(.{ .empty_enum_value = ty.toIntern() }),
2665 1 => try pt.intern(.{ .enum_tag = .{
2666 .ty = ty.toIntern(),
2667 .int = if (enum_type.values.len == 0)
2668 (try pt.intValue(.fromInterned(enum_type.tag_ty), 0)).toIntern()
2669 else
2670 try ip.getCoercedInts(
2671 gpa,
2672 io,
2673 pt.tid,
2674 ip.indexToKey(enum_type.values.get(ip)[0]).int,
2675 enum_type.tag_ty,
2676 ),
2677 } }),
2678 else => return null,
2679 });
2680 },
2681 }
2682 },
2014 assertHasLayout(ty, zcu);
2015 return switch (ip.indexToKey(ty.toIntern())) {
2016 .ptr_type,
2017 .error_union_type,
2018 .func_type,
2019 .anyframe_type,
2020 .error_set_type,
2021 .inferred_error_set_type,
2022 .opaque_type,
2023 => null,
26832024
2684 // values, not types
2685 .undef,
2686 .simple_value,
2687 .variable,
2688 .@"extern",
2689 .func,
2690 .int,
2691 .err,
2692 .error_union,
2025 .simple_type => |t| switch (t) {
2026 .f16,
2027 .f32,
2028 .f64,
2029 .f80,
2030 .f128,
2031 .usize,
2032 .isize,
2033 .c_char,
2034 .c_short,
2035 .c_ushort,
2036 .c_int,
2037 .c_uint,
2038 .c_long,
2039 .c_ulong,
2040 .c_longlong,
2041 .c_ulonglong,
2042 .c_longdouble,
2043 .anyopaque,
2044 .bool,
2045 .type,
2046 .anyerror,
2047 .comptime_int,
2048 .comptime_float,
26932049 .enum_literal,
2694 .enum_tag,
2695 .empty_enum_value,
2696 .float,
2697 .ptr,
2698 .slice,
2699 .opt,
2700 .aggregate,
2701 .un,
2702 // memoization, not types
2703 .memoized_call,
2704 => unreachable,
2705 },
2706 };
2707}
2708
2709/// During semantic analysis, instead call `ty.comptimeOnlySema` which
2710/// resolves field types rather than asserting they are already resolved.
2711pub fn comptimeOnly(ty: Type, zcu: *const Zcu) bool {
2712 return ty.comptimeOnlyInner(.normal, zcu, {}) catch unreachable;
2713}
2714
2715pub fn comptimeOnlySema(ty: Type, pt: Zcu.PerThread) SemaError!bool {
2716 return try ty.comptimeOnlyInner(.sema, pt.zcu, pt.tid);
2717}
2718
2719/// `generic_poison` will return false.
2720/// May return false negatives when structs and unions are having their field types resolved.
2721pub fn comptimeOnlyInner(
2722 ty: Type,
2723 comptime strat: ResolveStrat,
2724 zcu: strat.ZcuPtr(),
2725 tid: strat.Tid(),
2726) SemaError!bool {
2727 const ip = &zcu.intern_pool;
2728 const io = zcu.comp.io;
2729 return switch (ty.toIntern()) {
2730 .empty_tuple_type => false,
2050 .adhoc_inferred_error_set,
2051 .null,
2052 .undefined,
2053 .noreturn,
2054 => null,
27312055
2732 else => switch (ip.indexToKey(ty.toIntern())) {
2733 .int_type => false,
2734 .ptr_type => |ptr_type| {
2735 const child_ty = Type.fromInterned(ptr_type.child);
2736 switch (child_ty.zigTypeTag(zcu)) {
2737 .@"fn" => return !try child_ty.fnHasRuntimeBitsInner(strat, zcu, tid),
2738 .@"opaque" => return false,
2739 else => return child_ty.comptimeOnlyInner(strat, zcu, tid),
2740 }
2741 },
2742 .anyframe_type => |child| {
2743 if (child == .none) return false;
2744 return Type.fromInterned(child).comptimeOnlyInner(strat, zcu, tid);
2745 },
2746 .array_type => |array_type| return Type.fromInterned(array_type.child).comptimeOnlyInner(strat, zcu, tid),
2747 .vector_type => |vector_type| return Type.fromInterned(vector_type.child).comptimeOnlyInner(strat, zcu, tid),
2748 .opt_type => |child| return Type.fromInterned(child).comptimeOnlyInner(strat, zcu, tid),
2749 .error_union_type => |error_union_type| return Type.fromInterned(error_union_type.payload_type).comptimeOnlyInner(strat, zcu, tid),
2056 .void => .void,
27502057
2751 .error_set_type,
2752 .inferred_error_set_type,
2753 => false,
2058 .generic_poison => unreachable,
2059 },
27542060
2755 // These are function bodies, not function pointers.
2756 .func_type => true,
2757
2758 .simple_type => |t| switch (t) {
2759 .f16,
2760 .f32,
2761 .f64,
2762 .f80,
2763 .f128,
2764 .usize,
2765 .isize,
2766 .c_char,
2767 .c_short,
2768 .c_ushort,
2769 .c_int,
2770 .c_uint,
2771 .c_long,
2772 .c_ulong,
2773 .c_longlong,
2774 .c_ulonglong,
2775 .c_longdouble,
2776 .anyopaque,
2777 .bool,
2778 .void,
2779 .anyerror,
2780 .adhoc_inferred_error_set,
2781 .noreturn,
2782 .generic_poison,
2783 => false,
2784
2785 .type,
2786 .comptime_int,
2787 .comptime_float,
2788 .null,
2789 .undefined,
2790 .enum_literal,
2791 => true,
2792 },
2793 .struct_type => {
2794 const struct_type = ip.loadStructType(ty.toIntern());
2795 // packed structs cannot be comptime-only because they have a well-defined
2796 // memory layout and every field has a well-defined bit pattern.
2797 if (struct_type.layout == .@"packed")
2798 return false;
2799
2800 return switch (strat) {
2801 .normal => switch (struct_type.requiresComptime(ip)) {
2802 .wip => unreachable,
2803 .no => false,
2804 .yes => true,
2805 .unknown => unreachable,
2806 },
2807 .sema => switch (struct_type.setRequiresComptimeWip(ip, io)) {
2808 .no, .wip => false,
2809 .yes => true,
2810 .unknown => {
2811 if (struct_type.flagsUnordered(ip).field_types_wip) {
2812 struct_type.setRequiresComptime(ip, io, .unknown);
2813 return false;
2814 }
2815
2816 errdefer struct_type.setRequiresComptime(ip, io, .unknown);
2817
2818 const pt = strat.pt(zcu, tid);
2819 try ty.resolveFields(pt);
2820
2821 for (0..struct_type.field_types.len) |i_usize| {
2822 const i: u32 = @intCast(i_usize);
2823 if (struct_type.fieldIsComptime(ip, i)) continue;
2824 const field_ty = struct_type.field_types.get(ip)[i];
2825 if (try Type.fromInterned(field_ty).comptimeOnlyInner(strat, zcu, tid)) {
2826 // Note that this does not cause the layout to
2827 // be considered resolved. Comptime-only types
2828 // still maintain a layout of their
2829 // runtime-known fields.
2830 struct_type.setRequiresComptime(ip, io, .yes);
2831 return true;
2832 }
2833 }
2834
2835 struct_type.setRequiresComptime(ip, io, .no);
2836 return false;
2837 },
2838 },
2839 };
2840 },
2061 .int_type => |int_type| switch (int_type.bits) {
2062 0 => try pt.intValue(ty, 0),
2063 else => null,
2064 },
28412065
2842 .tuple_type => |tuple| {
2843 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
2844 const have_comptime_val = val != .none;
2845 if (!have_comptime_val and try Type.fromInterned(field_ty).comptimeOnlyInner(strat, zcu, tid)) return true;
2066 inline .array_type, .vector_type => |seq_type, seq_tag| {
2067 const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none;
2068 if (seq_type.len + @intFromBool(has_sentinel) == 0) {
2069 return try pt.aggregateValue(ty, &.{});
2070 }
2071 if (try Type.fromInterned(seq_type.child).onePossibleValue(pt)) |opv| {
2072 return try pt.aggregateSplatValue(ty, opv);
2073 }
2074 return null;
2075 },
2076 .opt_type => |child| switch (Type.fromInterned(child).classify(zcu)) {
2077 .no_possible_value => try pt.nullValue(ty),
2078 else => null,
2079 },
2080 .tuple_type => |tuple| {
2081 // Check *whether* the OPV exists first, because constructing it is a little more expensive.
2082 if (ty.classify(zcu) != .one_possible_value) return null;
2083 const field_vals = try zcu.gpa.dupe(InternPool.Index, tuple.values.get(ip));
2084 defer zcu.gpa.free(field_vals);
2085 for (field_vals, tuple.types.get(ip)) |*field_val, field_ty_ip| {
2086 if (field_val.* != .none) continue; // comptime field value
2087 const field_ty: Type = .fromInterned(field_ty_ip);
2088 field_val.* = (try field_ty.onePossibleValue(pt)).?.toIntern();
2089 }
2090 return try pt.aggregateValue(ty, field_vals);
2091 },
2092 .struct_type => {
2093 const struct_obj = ip.loadStructType(ty.toIntern());
2094 switch (struct_obj.layout) {
2095 .auto, .@"extern" => {},
2096 .@"packed" => {
2097 const backing_ty: Type = .fromInterned(struct_obj.packed_backing_int_type);
2098 const backing_val = try backing_ty.onePossibleValue(pt) orelse return null;
2099 return try pt.bitpackValue(ty, backing_val);
2100 },
2101 }
2102 // Type resolution already figured out whether there is an OPV, but if there is, it's
2103 // our job to compute it.
2104 if (struct_obj.class != .one_possible_value) return null;
2105 const field_vals = try gpa.alloc(InternPool.Index, struct_obj.field_types.len);
2106 defer gpa.free(field_vals);
2107 for (field_vals, 0..) |*field_val, i_usize| {
2108 const i: u32 = @intCast(i_usize);
2109 if (struct_obj.field_is_comptime_bits.get(ip, i)) {
2110 field_val.* = struct_obj.field_defaults.get(ip)[i];
2111 assert(field_val.* != .none);
2112 continue;
28462113 }
2847 return false;
2848 },
2849
2850 .union_type => {
2851 const union_type = ip.loadUnionType(ty.toIntern());
2852 return switch (strat) {
2853 .normal => switch (union_type.requiresComptime(ip)) {
2854 .wip => unreachable,
2855 .no => false,
2856 .yes => true,
2857 .unknown => unreachable,
2858 },
2859 .sema => switch (union_type.setRequiresComptimeWip(ip, io)) {
2860 .no, .wip => return false,
2861 .yes => return true,
2862 .unknown => {
2863 if (union_type.flagsUnordered(ip).status == .field_types_wip) {
2864 union_type.setRequiresComptime(ip, io, .unknown);
2865 return false;
2866 }
2867
2868 errdefer union_type.setRequiresComptime(ip, io, .unknown);
2869
2870 const pt = strat.pt(zcu, tid);
2871 try ty.resolveFields(pt);
2872
2873 for (0..union_type.field_types.len) |field_idx| {
2874 const field_ty = union_type.field_types.get(ip)[field_idx];
2875 if (try Type.fromInterned(field_ty).comptimeOnlyInner(strat, zcu, tid)) {
2876 union_type.setRequiresComptime(ip, io, .yes);
2877 return true;
2878 }
2879 }
2880
2881 union_type.setRequiresComptime(ip, io, .no);
2882 return false;
2883 },
2884 },
2885 };
2886 },
2887
2888 .opaque_type => false,
2889
2890 .enum_type => return Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).comptimeOnlyInner(strat, zcu, tid),
2891
2892 // values, not types
2893 .undef,
2894 .simple_value,
2895 .variable,
2896 .@"extern",
2897 .func,
2898 .int,
2899 .err,
2900 .error_union,
2901 .enum_literal,
2902 .enum_tag,
2903 .empty_enum_value,
2904 .float,
2905 .ptr,
2906 .slice,
2907 .opt,
2908 .aggregate,
2909 .un,
2910 // memoization, not types
2911 .memoized_call,
2912 => unreachable,
2114 const field_ty: Type = .fromInterned(struct_obj.field_types.get(ip)[i]);
2115 field_val.* = (try field_ty.onePossibleValue(pt)).?.toIntern();
2116 }
2117 return try pt.aggregateValue(ty, field_vals);
29132118 },
2119 .union_type => {
2120 const union_obj = ip.loadUnionType(ty.toIntern());
2121 if (union_obj.layout == .@"packed") {
2122 const backing_ty: Type = .fromInterned(union_obj.packed_backing_int_type);
2123 const backing_val = try backing_ty.onePossibleValue(pt) orelse return null;
2124 return try pt.bitpackValue(ty, backing_val);
2125 }
2126 // Type resolution already figured out whether there is an OPV, but if there is, it's
2127 // our job to compute it.
2128 if (union_obj.class != .one_possible_value) return null;
2129 // The OPV comes from exactly one field whose type is OPV, while all others are NPV.
2130 for (union_obj.field_types.get(ip), 0..) |field_ty_ip, field_index| {
2131 const field_ty: Type = .fromInterned(field_ty_ip);
2132 switch (field_ty.classify(zcu)) {
2133 .no_possible_value => continue,
2134 .one_possible_value => {},
2135 else => unreachable,
2136 }
2137 // This field is the one!
2138 const enum_tag_ty: Type = .fromInterned(union_obj.enum_tag_type);
2139 const tag_val = try pt.enumValueFieldIndex(enum_tag_ty, @intCast(field_index));
2140 const payload_val = (try field_ty.onePossibleValue(pt)).?;
2141 return try pt.unionValue(ty, tag_val, payload_val);
2142 } else unreachable;
2143 },
2144 .enum_type => if (try ty.intTagType(zcu).onePossibleValue(pt)) |int_tag_opv| {
2145 return .fromInterned(try pt.intern(.{ .enum_tag = .{
2146 .ty = ty.toIntern(),
2147 .int = int_tag_opv.toIntern(),
2148 } }));
2149 } else null,
2150
2151 // values, not types
2152 .undef,
2153 .simple_value,
2154 .variable,
2155 .@"extern",
2156 .func,
2157 .int,
2158 .err,
2159 .error_union,
2160 .enum_literal,
2161 .enum_tag,
2162 .float,
2163 .ptr,
2164 .slice,
2165 .opt,
2166 .aggregate,
2167 .un,
2168 .bitpack,
2169 // memoization, not types
2170 .memoized_call,
2171 => unreachable,
2172 };
2173}
2174
2175/// Asserts that `ty` has its layout resolved. `generic_poison` will return `false`.
2176pub fn comptimeOnly(ty: Type, zcu: *const Zcu) bool {
2177 if (ty.toIntern() == .generic_poison_type) return false;
2178 if (ty.zigTypeTag(zcu) == .error_union and ty.errorUnionPayload(zcu).toIntern() == .generic_poison_type) return false;
2179 return switch (ty.classify(zcu)) {
2180 .no_possible_value, .one_possible_value, .runtime => false,
2181 .partially_comptime, .fully_comptime => true,
29142182 };
29152183}
29162184
......@@ -3056,20 +2324,18 @@ pub fn maxIntScalar(ty: Type, pt: Zcu.PerThread, dest_ty: Type) !Value {
30562324/// Asserts the type is an enum or a union.
30572325pub fn intTagType(ty: Type, zcu: *const Zcu) Type {
30582326 const ip = &zcu.intern_pool;
3059 return switch (ip.indexToKey(ty.toIntern())) {
3060 .union_type => Type.fromInterned(ip.loadUnionType(ty.toIntern()).enum_tag_ty).intTagType(zcu),
3061 .enum_type => Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty),
2327 const enum_ty: Type = switch (ip.indexToKey(ty.toIntern())) {
2328 .union_type => .fromInterned(ip.loadUnionType(ty.toIntern()).enum_tag_type),
2329 .enum_type => ty,
30622330 else => unreachable,
30632331 };
2332 return .fromInterned(ip.loadEnumType(enum_ty.toIntern()).int_tag_type);
30642333}
30652334
30662335pub fn isNonexhaustiveEnum(ty: Type, zcu: *const Zcu) bool {
30672336 const ip = &zcu.intern_pool;
30682337 return switch (ip.indexToKey(ty.toIntern())) {
3069 .enum_type => switch (ip.loadEnumType(ty.toIntern()).tag_mode) {
3070 .nonexhaustive => true,
3071 .auto, .explicit => false,
3072 },
2338 .enum_type => ip.loadEnumType(ty.toIntern()).nonexhaustive,
30732339 else => false,
30742340 };
30752341}
......@@ -3090,28 +2356,33 @@ pub fn errorSetNames(ty: Type, zcu: *const Zcu) InternPool.NullTerminatedString.
30902356}
30912357
30922358pub fn enumFields(ty: Type, zcu: *const Zcu) InternPool.NullTerminatedString.Slice {
3093 return zcu.intern_pool.loadEnumType(ty.toIntern()).names;
2359 assertHasLayout(ty, zcu);
2360 return zcu.intern_pool.loadEnumType(ty.toIntern()).field_names;
30942361}
30952362
30962363pub fn enumFieldCount(ty: Type, zcu: *const Zcu) usize {
3097 return zcu.intern_pool.loadEnumType(ty.toIntern()).names.len;
2364 assertHasLayout(ty, zcu);
2365 return zcu.intern_pool.loadEnumType(ty.toIntern()).field_names.len;
30982366}
30992367
31002368pub fn enumFieldName(ty: Type, field_index: usize, zcu: *const Zcu) InternPool.NullTerminatedString {
2369 assertHasLayout(ty, zcu);
31012370 const ip = &zcu.intern_pool;
3102 return ip.loadEnumType(ty.toIntern()).names.get(ip)[field_index];
2371 return ip.loadEnumType(ty.toIntern()).field_names.get(ip)[field_index];
31032372}
31042373
31052374pub fn enumFieldIndex(ty: Type, field_name: InternPool.NullTerminatedString, zcu: *const Zcu) ?u32 {
2375 assertHasLayout(ty, zcu);
31062376 const ip = &zcu.intern_pool;
31072377 const enum_type = ip.loadEnumType(ty.toIntern());
31082378 return enum_type.nameIndex(ip, field_name);
31092379}
31102380
3111/// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or
3112/// an integer which represents the enum value. Returns the field index in
2381/// Asserts `ty` is an enum. `enum_tag` can either be the actual enum tag value
2382/// or an integer which represents the enum value. Returns the field index in
31132383/// declaration order, or `null` if `enum_tag` does not match any field.
31142384pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, zcu: *const Zcu) ?u32 {
2385 assertHasLayout(ty, zcu);
31152386 const ip = &zcu.intern_pool;
31162387 const enum_type = ip.loadEnumType(ty.toIntern());
31172388 const int_tag = switch (ip.indexToKey(enum_tag.toIntern())) {
......@@ -3119,200 +2390,116 @@ pub fn enumTagFieldIndex(ty: Type, enum_tag: Value, zcu: *const Zcu) ?u32 {
31192390 .enum_tag => |info| info.int,
31202391 else => unreachable,
31212392 };
3122 assert(ip.typeOf(int_tag) == enum_type.tag_ty);
2393 assert(ip.typeOf(int_tag) == enum_type.int_tag_type);
31232394 return enum_type.tagValueIndex(ip, int_tag);
31242395}
31252396
31262397/// Returns none in the case of a tuple which uses the integer index as the field name.
31272398pub fn structFieldName(ty: Type, index: usize, zcu: *const Zcu) InternPool.OptionalNullTerminatedString {
31282399 const ip = &zcu.intern_pool;
3129 return switch (ip.indexToKey(ty.toIntern())) {
3130 .struct_type => ip.loadStructType(ty.toIntern()).fieldName(ip, index).toOptional(),
3131 .tuple_type => .none,
2400 switch (ip.indexToKey(ty.toIntern())) {
2401 .struct_type => {
2402 assertHasLayout(ty, zcu);
2403 return ip.loadStructType(ty.toIntern()).field_names.get(ip)[index].toOptional();
2404 },
2405 .tuple_type => return .none,
31322406 else => unreachable,
3133 };
2407 }
31342408}
31352409
31362410pub fn structFieldCount(ty: Type, zcu: *const Zcu) u32 {
31372411 const ip = &zcu.intern_pool;
3138 return switch (ip.indexToKey(ty.toIntern())) {
3139 .struct_type => ip.loadStructType(ty.toIntern()).field_types.len,
3140 .tuple_type => |tuple| tuple.types.len,
2412 switch (ip.indexToKey(ty.toIntern())) {
2413 .struct_type => {
2414 assertHasLayout(ty, zcu);
2415 return ip.loadStructType(ty.toIntern()).field_types.len;
2416 },
2417 .tuple_type => |tuple| return tuple.types.len,
31412418 else => unreachable,
3142 };
2419 }
31432420}
31442421
3145/// Returns the field type. Supports structs and unions.
2422/// Returns the field type. Supports tuples, structs, and unions.
31462423pub fn fieldType(ty: Type, index: usize, zcu: *const Zcu) Type {
31472424 const ip = &zcu.intern_pool;
3148 return switch (ip.indexToKey(ty.toIntern())) {
3149 .struct_type => Type.fromInterned(ip.loadStructType(ty.toIntern()).field_types.get(ip)[index]),
3150 .union_type => {
3151 const union_obj = ip.loadUnionType(ty.toIntern());
3152 return Type.fromInterned(union_obj.field_types.get(ip)[index]);
2425 const types = switch (ip.indexToKey(ty.toIntern())) {
2426 .struct_type => types: {
2427 assertHasLayout(ty, zcu);
2428 break :types ip.loadStructType(ty.toIntern()).field_types;
31532429 },
3154 .tuple_type => |tuple| Type.fromInterned(tuple.types.get(ip)[index]),
2430 .union_type => types: {
2431 assertHasLayout(ty, zcu);
2432 break :types ip.loadUnionType(ty.toIntern()).field_types;
2433 },
2434 .tuple_type => |tuple| tuple.types,
31552435 else => unreachable,
31562436 };
2437 return .fromInterned(types.get(ip)[index]);
31572438}
31582439
3159pub fn fieldAlignment(ty: Type, index: usize, zcu: *Zcu) Alignment {
3160 return ty.fieldAlignmentInner(index, .normal, zcu, {}) catch unreachable;
3161}
3162
3163pub fn fieldAlignmentSema(ty: Type, index: usize, pt: Zcu.PerThread) SemaError!Alignment {
3164 return try ty.fieldAlignmentInner(index, .sema, pt.zcu, pt.tid);
3165}
3166
3167/// Returns the field alignment. Supports structs and unions.
3168/// If `strat` is `.sema`, may perform type resolution.
3169/// Asserts the layout is not packed.
2440/// If an alignment was explicitly specified for the given field of the struct or union type `ty`,
2441/// returns that. Otherwise, returns `.none`. This function also supports tuples, for which it
2442/// always returns `.none`.
31702443///
3171/// Provide the struct field as the `ty`.
3172pub fn fieldAlignmentInner(
3173 ty: Type,
3174 index: usize,
3175 comptime strat: ResolveStrat,
3176 zcu: strat.ZcuPtr(),
3177 tid: strat.Tid(),
3178) SemaError!Alignment {
2444/// Asserts that the layout of `ty` is resolved, unless `ty` is a tuple.
2445pub fn explicitFieldAlignment(ty: Type, index: usize, zcu: *const Zcu) Alignment {
31792446 const ip = &zcu.intern_pool;
3180 switch (ip.indexToKey(ty.toIntern())) {
2447 return switch (ip.indexToKey(ty.toIntern())) {
2448 .tuple_type => .none,
31812449 .struct_type => {
3182 const struct_type = ip.loadStructType(ty.toIntern());
3183 assert(struct_type.layout != .@"packed");
3184 const explicit_align = struct_type.fieldAlign(ip, index);
3185 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[index]);
3186 return field_ty.structFieldAlignmentInner(explicit_align, struct_type.layout, strat, zcu, tid);
3187 },
3188 .tuple_type => |tuple| {
3189 return (try Type.fromInterned(tuple.types.get(ip)[index]).abiAlignmentInner(
3190 strat.toLazy(),
3191 zcu,
3192 tid,
3193 )).scalar;
2450 assertHasLayout(ty, zcu);
2451 const struct_obj = ip.loadStructType(ty.toIntern());
2452 assert(struct_obj.layout != .@"packed");
2453 if (struct_obj.field_aligns.len == 0) return .none;
2454 return struct_obj.field_aligns.get(ip)[index];
31942455 },
31952456 .union_type => {
2457 assertHasLayout(ty, zcu);
31962458 const union_obj = ip.loadUnionType(ty.toIntern());
3197 const layout = union_obj.flagsUnordered(ip).layout;
3198 assert(layout != .@"packed");
3199 const explicit_align = union_obj.fieldAlign(ip, index);
3200 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[index]);
3201 return field_ty.unionFieldAlignmentInner(explicit_align, layout, strat, zcu, tid);
2459 assert(union_obj.layout != .@"packed");
2460 if (union_obj.field_aligns.len == 0) return .none;
2461 return union_obj.field_aligns.get(ip)[index];
32022462 },
32032463 else => unreachable,
3204 }
2464 };
32052465}
32062466
3207/// Returns the alignment of a non-packed struct field. Assert the layout is not packed.
2467/// Returns the alignment a struct field of type `field_ty` will be given if no alignment is
2468/// explicitly specified. However, in an `extern struct`, a higher alignment may be available due
2469/// to the struct's full layout (i.e. a field might coincidentally be more aligned).
32082470///
3209/// Asserts that all resolution needed was done.
3210pub fn structFieldAlignment(
2471/// Asserts that the layout of `field_ty` is resolved. Asserts that `layout` is not `.@"packed"`.
2472pub fn defaultStructFieldAlignment(
32112473 field_ty: Type,
3212 explicit_alignment: InternPool.Alignment,
32132474 layout: std.builtin.Type.ContainerLayout,
3214 zcu: *Zcu,
2475 zcu: *const Zcu,
32152476) Alignment {
3216 return field_ty.structFieldAlignmentInner(
3217 explicit_alignment,
3218 layout,
3219 .normal,
3220 zcu,
3221 {},
3222 ) catch unreachable;
3223}
3224
3225/// Returns the alignment of a non-packed struct field. Assert the layout is not packed.
3226/// May do type resolution when needed.
3227/// Asserts that all resolution needed was done.
3228pub fn structFieldAlignmentSema(
3229 field_ty: Type,
3230 explicit_alignment: InternPool.Alignment,
3231 layout: std.builtin.Type.ContainerLayout,
3232 pt: Zcu.PerThread,
3233) SemaError!Alignment {
3234 return try field_ty.structFieldAlignmentInner(
3235 explicit_alignment,
3236 layout,
3237 .sema,
3238 pt.zcu,
3239 pt.tid,
3240 );
3241}
3242
3243/// Returns the alignment of a non-packed struct field. Asserts the layout is not packed.
3244/// If `strat` is `.sema`, may perform type resolution.
3245pub fn structFieldAlignmentInner(
3246 field_ty: Type,
3247 explicit_alignment: Alignment,
3248 layout: std.builtin.Type.ContainerLayout,
3249 comptime strat: Type.ResolveStrat,
3250 zcu: strat.ZcuPtr(),
3251 tid: strat.Tid(),
3252) SemaError!Alignment {
3253 assert(layout != .@"packed");
3254 if (explicit_alignment != .none) return explicit_alignment;
3255 const ty_abi_align = (try field_ty.abiAlignmentInner(
3256 strat.toLazy(),
3257 zcu,
3258 tid,
3259 )).scalar;
3260 switch (layout) {
2477 const overalign_big_int = switch (layout) {
32612478 .@"packed" => unreachable,
3262 .auto => if (zcu.getTarget().ofmt != .c) return ty_abi_align,
3263 .@"extern" => {},
3264 }
3265 // extern
3266 if (field_ty.isAbiInt(zcu) and field_ty.intInfo(zcu).bits >= 128) {
3267 return ty_abi_align.maxStrict(.@"16");
2479 .auto => zcu.getTarget().ofmt == .c,
2480 .@"extern" => true,
2481 };
2482 const abi_align = field_ty.abiAlignment(zcu);
2483 assert(abi_align != .none);
2484 if (overalign_big_int and field_ty.isAbiInt(zcu) and field_ty.intInfo(zcu).bits >= 128) {
2485 return abi_align.maxStrict(.@"16");
32682486 }
3269 return ty_abi_align;
3270}
3271
3272pub fn unionFieldAlignmentSema(
3273 field_ty: Type,
3274 explicit_alignment: Alignment,
3275 layout: std.builtin.Type.ContainerLayout,
3276 pt: Zcu.PerThread,
3277) SemaError!Alignment {
3278 return field_ty.unionFieldAlignmentInner(
3279 explicit_alignment,
3280 layout,
3281 .sema,
3282 pt.zcu,
3283 pt.tid,
3284 );
3285}
3286
3287pub fn unionFieldAlignmentInner(
3288 field_ty: Type,
3289 explicit_alignment: Alignment,
3290 layout: std.builtin.Type.ContainerLayout,
3291 comptime strat: Type.ResolveStrat,
3292 zcu: strat.ZcuPtr(),
3293 tid: strat.Tid(),
3294) SemaError!Alignment {
3295 assert(layout != .@"packed");
3296 if (explicit_alignment != .none) return explicit_alignment;
3297 if (field_ty.isNoReturn(zcu)) return .none;
3298 return (try field_ty.abiAlignmentInner(strat.toLazy(), zcu, tid)).scalar;
2487 return abi_align;
32992488}
33002489
3301pub fn structFieldDefaultValue(ty: Type, index: usize, zcu: *const Zcu) Value {
2490pub fn structFieldDefaultValue(ty: Type, index: usize, zcu: *const Zcu) ?Value {
33022491 const ip = &zcu.intern_pool;
33032492 switch (ip.indexToKey(ty.toIntern())) {
33042493 .struct_type => {
3305 const struct_type = ip.loadStructType(ty.toIntern());
3306 const val = struct_type.fieldInit(ip, index);
3307 // TODO: avoid using `unreachable` to indicate this.
3308 if (val == .none) return Value.@"unreachable";
3309 return Value.fromInterned(val);
2494 const field_defaults = ip.loadStructType(ty.toIntern()).field_defaults.get(ip);
2495 if (field_defaults.len == 0) return null;
2496 if (field_defaults[index] == .none) return null;
2497 return .fromInterned(field_defaults[index]);
33102498 },
33112499 .tuple_type => |tuple| {
33122500 const val = tuple.values.get(ip)[index];
3313 // TODO: avoid using `unreachable` to indicate this.
3314 if (val == .none) return Value.@"unreachable";
3315 return Value.fromInterned(val);
2501 if (val == .none) return null;
2502 return .fromInterned(val);
33162503 },
33172504 else => unreachable,
33182505 }
......@@ -3324,9 +2511,8 @@ pub fn structFieldValueComptime(ty: Type, pt: Zcu.PerThread, index: usize) !?Val
33242511 switch (ip.indexToKey(ty.toIntern())) {
33252512 .struct_type => {
33262513 const struct_type = ip.loadStructType(ty.toIntern());
3327 if (struct_type.fieldIsComptime(ip, index)) {
3328 assert(struct_type.haveFieldInits(ip));
3329 return Value.fromInterned(struct_type.field_inits.get(ip)[index]);
2514 if (struct_type.field_is_comptime_bits.get(ip, index)) {
2515 return .fromInterned(struct_type.field_defaults.get(ip)[index]);
33302516 } else {
33312517 return Type.fromInterned(struct_type.field_types.get(ip)[index]).onePossibleValue(pt);
33322518 }
......@@ -3336,7 +2522,7 @@ pub fn structFieldValueComptime(ty: Type, pt: Zcu.PerThread, index: usize) !?Val
33362522 if (val == .none) {
33372523 return Type.fromInterned(tuple.types.get(ip)[index]).onePossibleValue(pt);
33382524 } else {
3339 return Value.fromInterned(val);
2525 return .fromInterned(val);
33402526 }
33412527 },
33422528 else => unreachable,
......@@ -3345,11 +2531,14 @@ pub fn structFieldValueComptime(ty: Type, pt: Zcu.PerThread, index: usize) !?Val
33452531
33462532pub fn structFieldIsComptime(ty: Type, index: usize, zcu: *const Zcu) bool {
33472533 const ip = &zcu.intern_pool;
3348 return switch (ip.indexToKey(ty.toIntern())) {
3349 .struct_type => ip.loadStructType(ty.toIntern()).fieldIsComptime(ip, index),
3350 .tuple_type => |tuple| tuple.values.get(ip)[index] != .none,
2534 switch (ip.indexToKey(ty.toIntern())) {
2535 .struct_type => {
2536 assertHasLayout(ty, zcu);
2537 return ip.loadStructType(ty.toIntern()).field_is_comptime_bits.get(ip, index);
2538 },
2539 .tuple_type => |tuple| return tuple.values.get(ip)[index] != .none,
33512540 else => unreachable,
3352 };
2541 }
33532542}
33542543
33552544pub const FieldOffset = struct {
......@@ -3357,15 +2546,15 @@ pub const FieldOffset = struct {
33572546 offset: u64,
33582547};
33592548
3360/// Supports structs and unions.
2549/// Supports structs, tuples, and unions.
33612550pub fn structFieldOffset(ty: Type, index: usize, zcu: *const Zcu) u64 {
2551 assertHasLayout(ty, zcu);
33622552 const ip = &zcu.intern_pool;
33632553 switch (ip.indexToKey(ty.toIntern())) {
33642554 .struct_type => {
33652555 const struct_type = ip.loadStructType(ty.toIntern());
3366 assert(struct_type.haveLayout(ip));
33672556 assert(struct_type.layout != .@"packed");
3368 return struct_type.offsets.get(ip)[index];
2557 return struct_type.field_offsets.get(ip)[index];
33692558 },
33702559
33712560 .tuple_type => |tuple| {
......@@ -3375,7 +2564,7 @@ pub fn structFieldOffset(ty: Type, index: usize, zcu: *const Zcu) u64 {
33752564 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
33762565 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(zcu)) {
33772566 // comptime field
3378 if (i == index) return offset;
2567 if (i == index) return 0;
33792568 continue;
33802569 }
33812570
......@@ -3391,8 +2580,7 @@ pub fn structFieldOffset(ty: Type, index: usize, zcu: *const Zcu) u64 {
33912580
33922581 .union_type => {
33932582 const union_type = ip.loadUnionType(ty.toIntern());
3394 if (!union_type.hasTag(ip))
3395 return 0;
2583 if (!union_type.has_runtime_tag) return 0;
33962584 const layout = Type.getUnionLayout(union_type, zcu);
33972585 if (layout.tag_align.compare(.gte, layout.payload_align)) {
33982586 // {Tag, Payload}
......@@ -3414,7 +2602,7 @@ pub fn srcLocOrNull(ty: Type, zcu: *Zcu) ?Zcu.LazySrcLoc {
34142602 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
34152603 .declared => |d| d.zir_index,
34162604 .reified => |r| r.zir_index,
3417 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,
2605 .generated_union_tag => |union_ty| ip.loadUnionType(union_ty).zir_index,
34182606 },
34192607 else => return null,
34202608 },
......@@ -3438,8 +2626,8 @@ pub fn isTuple(ty: Type, zcu: *const Zcu) bool {
34382626 };
34392627}
34402628
3441/// Traverses optional child types and error union payloads until the type
3442/// is not a pointer. For `E!?u32`, returns `u32`; for `*u8`, returns `*u8`.
2629/// Traverses optional child types and error union payloads until the type is neither of those.
2630/// For `E!?u32`, returns `u32`; for `*u8`, returns `*u8`.
34432631pub fn optEuBaseType(ty: Type, zcu: *const Zcu) Type {
34442632 var cur = ty;
34452633 while (true) switch (cur.zigTypeTag(zcu)) {
......@@ -3485,439 +2673,81 @@ pub fn typeDeclInstAllowGeneratedTag(ty: Type, zcu: *const Zcu) ?InternPool.Trac
34852673 const ip = &zcu.intern_pool;
34862674 return switch (ip.indexToKey(ty.toIntern())) {
34872675 .struct_type => ip.loadStructType(ty.toIntern()).zir_index,
3488 .union_type => ip.loadUnionType(ty.toIntern()).zir_index,
3489 .enum_type => |e| switch (e) {
3490 .declared, .reified => ip.loadEnumType(ty.toIntern()).zir_index.unwrap().?,
3491 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,
3492 },
3493 .opaque_type => ip.loadOpaqueType(ty.toIntern()).zir_index,
3494 else => null,
3495 };
3496}
3497
3498pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
3499 // Note that changes to ZIR instruction tracking only need to update this code
3500 // if a newly-tracked instruction can be a type's owner `zir_index`.
3501 comptime assert(Zir.inst_tracking_version == 0);
3502
3503 const ip = &zcu.intern_pool;
3504 const tracked = switch (ip.indexToKey(ty.toIntern())) {
3505 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
3506 .declared => |d| d.zir_index,
3507 .reified => |r| r.zir_index,
3508 .generated_tag => |gt| ip.loadUnionType(gt.union_type).zir_index,
3509 },
3510 else => return null,
3511 };
3512 const info = tracked.resolveFull(&zcu.intern_pool) orelse return null;
3513 const file = zcu.fileByIndex(info.file);
3514 const zir = switch (file.getMode()) {
3515 .zig => file.zir.?,
3516 .zon => return 0,
3517 };
3518 const inst = zir.instructions.get(@intFromEnum(info.inst));
3519 return switch (inst.tag) {
3520 .struct_init, .struct_init_ref => zir.extraData(Zir.Inst.StructInit, inst.data.pl_node.payload_index).data.abs_line,
3521 .struct_init_anon => zir.extraData(Zir.Inst.StructInitAnon, inst.data.pl_node.payload_index).data.abs_line,
3522 .extended => switch (inst.data.extended.opcode) {
3523 .struct_decl => zir.extraData(Zir.Inst.StructDecl, inst.data.extended.operand).data.src_line,
3524 .union_decl => zir.extraData(Zir.Inst.UnionDecl, inst.data.extended.operand).data.src_line,
3525 .enum_decl => zir.extraData(Zir.Inst.EnumDecl, inst.data.extended.operand).data.src_line,
3526 .opaque_decl => zir.extraData(Zir.Inst.OpaqueDecl, inst.data.extended.operand).data.src_line,
3527 .reify_enum => zir.extraData(Zir.Inst.ReifyEnum, inst.data.extended.operand).data.src_line,
3528 .reify_struct => zir.extraData(Zir.Inst.ReifyStruct, inst.data.extended.operand).data.src_line,
3529 .reify_union => zir.extraData(Zir.Inst.ReifyUnion, inst.data.extended.operand).data.src_line,
3530 else => unreachable,
3531 },
3532 else => unreachable,
3533 };
3534}
3535
3536/// Given a namespace type, returns its list of captured values.
3537pub fn getCaptures(ty: Type, zcu: *const Zcu) InternPool.CaptureValue.Slice {
3538 const ip = &zcu.intern_pool;
3539 return switch (ip.indexToKey(ty.toIntern())) {
3540 .struct_type => ip.loadStructType(ty.toIntern()).captures,
3541 .union_type => ip.loadUnionType(ty.toIntern()).captures,
3542 .enum_type => ip.loadEnumType(ty.toIntern()).captures,
3543 .opaque_type => ip.loadOpaqueType(ty.toIntern()).captures,
3544 else => unreachable,
3545 };
3546}
3547
3548pub fn arrayBase(ty: Type, zcu: *const Zcu) struct { Type, u64 } {
3549 var cur_ty: Type = ty;
3550 var cur_len: u64 = 1;
3551 while (cur_ty.zigTypeTag(zcu) == .array) {
3552 cur_len *= cur_ty.arrayLenIncludingSentinel(zcu);
3553 cur_ty = cur_ty.childType(zcu);
3554 }
3555 return .{ cur_ty, cur_len };
3556}
3557
3558/// Returns a bit-pointer with the same value and a new packed offset.
3559pub fn packedStructFieldPtrInfo(
3560 struct_ty: Type,
3561 parent_ptr_ty: Type,
3562 field_idx: u32,
3563 pt: Zcu.PerThread,
3564) InternPool.Key.PtrType.PackedOffset {
3565 comptime assert(Type.packed_struct_layout_version == 2);
3566
3567 const zcu = pt.zcu;
3568 const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu);
3569
3570 var bit_offset: u16 = 0;
3571 var running_bits: u16 = 0;
3572 for (0..struct_ty.structFieldCount(zcu)) |i| {
3573 const f_ty = struct_ty.fieldType(i, zcu);
3574 if (i == field_idx) {
3575 bit_offset = running_bits;
3576 }
3577 running_bits += @intCast(f_ty.bitSize(zcu));
3578 }
3579
3580 const res_host_size: u16, const res_bit_offset: u16 = if (parent_ptr_info.packed_offset.host_size != 0) .{
3581 parent_ptr_info.packed_offset.host_size,
3582 parent_ptr_info.packed_offset.bit_offset + bit_offset,
3583 } else .{
3584 switch (zcu.comp.getZigBackend()) {
3585 else => (running_bits + 7) / 8,
3586 .stage2_x86_64, .stage2_c => @intCast(struct_ty.abiSize(zcu)),
3587 },
3588 bit_offset,
3589 };
3590
3591 return .{
3592 .host_size = res_host_size,
3593 .bit_offset = res_bit_offset,
3594 };
3595}
3596
3597pub fn resolveLayout(ty: Type, pt: Zcu.PerThread) SemaError!void {
3598 const zcu = pt.zcu;
3599 const ip = &zcu.intern_pool;
3600 switch (ty.zigTypeTag(zcu)) {
3601 .@"struct" => switch (ip.indexToKey(ty.toIntern())) {
3602 .tuple_type => |tuple_type| for (0..tuple_type.types.len) |i| {
3603 const field_ty = Type.fromInterned(tuple_type.types.get(ip)[i]);
3604 try field_ty.resolveLayout(pt);
3605 },
3606 .struct_type => return ty.resolveStructInner(pt, .layout),
3607 else => unreachable,
3608 },
3609 .@"union" => return ty.resolveUnionInner(pt, .layout),
3610 .array => {
3611 if (ty.arrayLenIncludingSentinel(zcu) == 0) return;
3612 const elem_ty = ty.childType(zcu);
3613 return elem_ty.resolveLayout(pt);
3614 },
3615 .optional => {
3616 const payload_ty = ty.optionalChild(zcu);
3617 return payload_ty.resolveLayout(pt);
3618 },
3619 .error_union => {
3620 const payload_ty = ty.errorUnionPayload(zcu);
3621 return payload_ty.resolveLayout(pt);
3622 },
3623 .@"fn" => {
3624 const info = zcu.typeToFunc(ty).?;
3625 if (info.is_generic) {
3626 // Resolving of generic function types is deferred to when
3627 // the function is instantiated.
3628 return;
3629 }
3630 for (0..info.param_types.len) |i| {
3631 const param_ty = info.param_types.get(ip)[i];
3632 try Type.fromInterned(param_ty).resolveLayout(pt);
3633 }
3634 try Type.fromInterned(info.return_type).resolveLayout(pt);
3635 },
3636 else => {},
3637 }
3638}
3639
3640pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void {
3641 const ip = &pt.zcu.intern_pool;
3642 const ty_ip = ty.toIntern();
3643
3644 switch (ty_ip) {
3645 .none => unreachable,
3646
3647 .u0_type,
3648 .i0_type,
3649 .u1_type,
3650 .u8_type,
3651 .i8_type,
3652 .u16_type,
3653 .i16_type,
3654 .u29_type,
3655 .u32_type,
3656 .i32_type,
3657 .u64_type,
3658 .i64_type,
3659 .u80_type,
3660 .u128_type,
3661 .i128_type,
3662 .usize_type,
3663 .isize_type,
3664 .c_char_type,
3665 .c_short_type,
3666 .c_ushort_type,
3667 .c_int_type,
3668 .c_uint_type,
3669 .c_long_type,
3670 .c_ulong_type,
3671 .c_longlong_type,
3672 .c_ulonglong_type,
3673 .c_longdouble_type,
3674 .f16_type,
3675 .f32_type,
3676 .f64_type,
3677 .f80_type,
3678 .f128_type,
3679 .anyopaque_type,
3680 .bool_type,
3681 .void_type,
3682 .type_type,
3683 .anyerror_type,
3684 .adhoc_inferred_error_set_type,
3685 .comptime_int_type,
3686 .comptime_float_type,
3687 .noreturn_type,
3688 .anyframe_type,
3689 .null_type,
3690 .undefined_type,
3691 .enum_literal_type,
3692 .ptr_usize_type,
3693 .ptr_const_comptime_int_type,
3694 .manyptr_u8_type,
3695 .manyptr_const_u8_type,
3696 .manyptr_const_u8_sentinel_0_type,
3697 .slice_const_u8_type,
3698 .slice_const_u8_sentinel_0_type,
3699 .optional_noreturn_type,
3700 .anyerror_void_error_union_type,
3701 .generic_poison_type,
3702 .empty_tuple_type,
3703 => {},
3704
3705 .undef => unreachable,
3706 .zero => unreachable,
3707 .zero_usize => unreachable,
3708 .zero_u1 => unreachable,
3709 .zero_u8 => unreachable,
3710 .one => unreachable,
3711 .one_usize => unreachable,
3712 .one_u1 => unreachable,
3713 .one_u8 => unreachable,
3714 .four_u8 => unreachable,
3715 .negative_one => unreachable,
3716 .void_value => unreachable,
3717 .unreachable_value => unreachable,
3718 .null_value => unreachable,
3719 .bool_true => unreachable,
3720 .bool_false => unreachable,
3721 .empty_tuple => unreachable,
3722
3723 else => switch (ty_ip.unwrap(ip).getTag(ip)) {
3724 .type_struct,
3725 .type_struct_packed,
3726 .type_struct_packed_inits,
3727 => return ty.resolveStructInner(pt, .fields),
3728
3729 .type_union => return ty.resolveUnionInner(pt, .fields),
3730
3731 else => {},
3732 },
3733 }
3734}
3735
3736pub fn resolveFully(ty: Type, pt: Zcu.PerThread) SemaError!void {
3737 const zcu = pt.zcu;
3738 const ip = &zcu.intern_pool;
3739
3740 switch (ty.zigTypeTag(zcu)) {
3741 .type,
3742 .void,
3743 .bool,
3744 .noreturn,
3745 .int,
3746 .float,
3747 .comptime_float,
3748 .comptime_int,
3749 .undefined,
3750 .null,
3751 .error_set,
3752 .@"enum",
3753 .@"opaque",
3754 .frame,
3755 .@"anyframe",
3756 .vector,
3757 .enum_literal,
3758 => {},
3759
3760 .pointer => return ty.childType(zcu).resolveFully(pt),
3761 .array => return ty.childType(zcu).resolveFully(pt),
3762 .optional => return ty.optionalChild(zcu).resolveFully(pt),
3763 .error_union => return ty.errorUnionPayload(zcu).resolveFully(pt),
3764 .@"fn" => {
3765 const info = zcu.typeToFunc(ty).?;
3766 if (info.is_generic) return;
3767 for (0..info.param_types.len) |i| {
3768 const param_ty = info.param_types.get(ip)[i];
3769 try Type.fromInterned(param_ty).resolveFully(pt);
3770 }
3771 try Type.fromInterned(info.return_type).resolveFully(pt);
3772 },
3773
3774 .@"struct" => switch (ip.indexToKey(ty.toIntern())) {
3775 .tuple_type => |tuple_type| for (0..tuple_type.types.len) |i| {
3776 const field_ty = Type.fromInterned(tuple_type.types.get(ip)[i]);
3777 try field_ty.resolveFully(pt);
3778 },
3779 .struct_type => return ty.resolveStructInner(pt, .full),
3780 else => unreachable,
3781 },
3782 .@"union" => return ty.resolveUnionInner(pt, .full),
3783 }
3784}
3785
3786pub fn resolveStructFieldInits(ty: Type, pt: Zcu.PerThread) SemaError!void {
3787 // TODO: stop calling this for tuples!
3788 _ = pt.zcu.typeToStruct(ty) orelse return;
3789 return ty.resolveStructInner(pt, .inits);
3790}
3791
3792pub fn resolveStructAlignment(ty: Type, pt: Zcu.PerThread) SemaError!void {
3793 return ty.resolveStructInner(pt, .alignment);
3794}
3795
3796pub fn resolveUnionAlignment(ty: Type, pt: Zcu.PerThread) SemaError!void {
3797 return ty.resolveUnionInner(pt, .alignment);
3798}
3799
3800/// `ty` must be a struct.
3801fn resolveStructInner(
3802 ty: Type,
3803 pt: Zcu.PerThread,
3804 resolution: enum { fields, inits, alignment, layout, full },
3805) SemaError!void {
3806 const zcu = pt.zcu;
3807 const gpa = zcu.gpa;
3808
3809 const struct_obj = zcu.typeToStruct(ty).?;
3810 const owner: InternPool.AnalUnit = .wrap(.{ .type = ty.toIntern() });
3811
3812 if (zcu.failed_analysis.contains(owner) or zcu.transitive_failed_analysis.contains(owner)) {
3813 return error.AnalysisFail;
3814 }
3815
3816 if (zcu.comp.debugIncremental()) {
3817 const info = try zcu.incremental_debug_state.getUnitInfo(gpa, owner);
3818 info.last_update_gen = zcu.generation;
3819 }
3820
3821 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
3822 defer analysis_arena.deinit();
2676 .union_type => ip.loadUnionType(ty.toIntern()).zir_index,
2677 .enum_type => |e| switch (e) {
2678 .declared, .reified => ip.loadEnumType(ty.toIntern()).zir_index.unwrap().?,
2679 .generated_union_tag => |union_ty| ip.loadUnionType(union_ty).zir_index,
2680 },
2681 .opaque_type => ip.loadOpaqueType(ty.toIntern()).zir_index,
2682 else => null,
2683 };
2684}
38232685
3824 var comptime_err_ret_trace = std.array_list.Managed(Zcu.LazySrcLoc).init(gpa);
3825 defer comptime_err_ret_trace.deinit();
2686pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
2687 // Note that changes to ZIR instruction tracking only need to update this code
2688 // if a newly-tracked instruction can be a type's owner `zir_index`.
2689 comptime assert(Zir.inst_tracking_version == 0);
38262690
3827 const zir = zcu.namespacePtr(struct_obj.namespace).fileScope(zcu).zir.?;
3828 var sema: Sema = .{
3829 .pt = pt,
3830 .gpa = gpa,
3831 .arena = analysis_arena.allocator(),
3832 .code = zir,
3833 .owner = owner,
3834 .func_index = .none,
3835 .func_is_naked = false,
3836 .fn_ret_ty = Type.void,
3837 .fn_ret_ty_ies = null,
3838 .comptime_err_ret_trace = &comptime_err_ret_trace,
2691 const ip = &zcu.intern_pool;
2692 const tracked = switch (ip.indexToKey(ty.toIntern())) {
2693 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
2694 .declared => |d| d.zir_index,
2695 .reified => |r| r.zir_index,
2696 .generated_union_tag => |union_ty| ip.loadUnionType(union_ty).zir_index,
2697 },
2698 else => return null,
38392699 };
3840 defer sema.deinit();
3841
3842 (switch (resolution) {
3843 .fields => sema.resolveStructFieldTypes(ty.toIntern(), struct_obj),
3844 .inits => sema.resolveStructFieldInits(ty),
3845 .alignment => sema.resolveStructAlignment(ty.toIntern(), struct_obj),
3846 .layout => sema.resolveStructLayout(ty),
3847 .full => sema.resolveStructFully(ty),
3848 }) catch |err| switch (err) {
3849 error.AnalysisFail => {
3850 if (!zcu.failed_analysis.contains(owner)) {
3851 try zcu.transitive_failed_analysis.put(gpa, owner, {});
3852 }
3853 return error.AnalysisFail;
2700 const info = tracked.resolveFull(&zcu.intern_pool) orelse return null;
2701 const file = zcu.fileByIndex(info.file);
2702 const zir = switch (file.getMode()) {
2703 .zig => file.zir.?,
2704 .zon => return 0,
2705 };
2706 const inst = zir.instructions.get(@intFromEnum(info.inst));
2707 return switch (inst.tag) {
2708 .struct_init, .struct_init_ref => zir.extraData(Zir.Inst.StructInit, inst.data.pl_node.payload_index).data.abs_line,
2709 .struct_init_anon => zir.extraData(Zir.Inst.StructInitAnon, inst.data.pl_node.payload_index).data.abs_line,
2710 .extended => switch (inst.data.extended.opcode) {
2711 .struct_decl => zir.getStructDecl(info.inst).src_line,
2712 .union_decl => zir.getUnionDecl(info.inst).src_line,
2713 .enum_decl => zir.getEnumDecl(info.inst).src_line,
2714 .opaque_decl => zir.getOpaqueDecl(info.inst).src_line,
2715 .reify_enum => zir.extraData(Zir.Inst.ReifyEnum, inst.data.extended.operand).data.src_line,
2716 .reify_struct => zir.extraData(Zir.Inst.ReifyStruct, inst.data.extended.operand).data.src_line,
2717 .reify_union => zir.extraData(Zir.Inst.ReifyUnion, inst.data.extended.operand).data.src_line,
2718 else => unreachable,
38542719 },
3855 error.OutOfMemory, error.Canceled => |e| return e,
2720 else => unreachable,
38562721 };
38572722}
38582723
3859/// `ty` must be a union.
3860fn resolveUnionInner(
3861 ty: Type,
3862 pt: Zcu.PerThread,
3863 resolution: enum { fields, alignment, layout, full },
3864) SemaError!void {
3865 const zcu = pt.zcu;
3866 const gpa = zcu.gpa;
3867
3868 const union_obj = zcu.typeToUnion(ty).?;
3869 const owner: InternPool.AnalUnit = .wrap(.{ .type = ty.toIntern() });
3870
3871 if (zcu.failed_analysis.contains(owner) or zcu.transitive_failed_analysis.contains(owner)) {
3872 return error.AnalysisFail;
3873 }
2724/// Given a namespace type, returns its list of captured values.
2725pub fn getCaptures(ty: Type, zcu: *const Zcu) InternPool.CaptureValue.Slice {
2726 const ip = &zcu.intern_pool;
2727 return switch (ip.indexToKey(ty.toIntern())) {
2728 .struct_type => ip.loadStructType(ty.toIntern()).captures,
2729 .union_type => ip.loadUnionType(ty.toIntern()).captures,
2730 .enum_type => ip.loadEnumType(ty.toIntern()).captures,
2731 .opaque_type => ip.loadOpaqueType(ty.toIntern()).captures,
2732 else => unreachable,
2733 };
2734}
38742735
3875 if (zcu.comp.debugIncremental()) {
3876 const info = try zcu.incremental_debug_state.getUnitInfo(gpa, owner);
3877 info.last_update_gen = zcu.generation;
2736pub fn arrayBase(ty: Type, zcu: *const Zcu) struct { Type, u64 } {
2737 var cur_ty: Type = ty;
2738 var cur_len: u64 = 1;
2739 while (cur_ty.zigTypeTag(zcu) == .array) {
2740 cur_len *= cur_ty.arrayLenIncludingSentinel(zcu);
2741 cur_ty = cur_ty.childType(zcu);
38782742 }
3879
3880 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
3881 defer analysis_arena.deinit();
3882
3883 var comptime_err_ret_trace = std.array_list.Managed(Zcu.LazySrcLoc).init(gpa);
3884 defer comptime_err_ret_trace.deinit();
3885
3886 const zir = zcu.namespacePtr(union_obj.namespace).fileScope(zcu).zir.?;
3887 var sema: Sema = .{
3888 .pt = pt,
3889 .gpa = gpa,
3890 .arena = analysis_arena.allocator(),
3891 .code = zir,
3892 .owner = owner,
3893 .func_index = .none,
3894 .func_is_naked = false,
3895 .fn_ret_ty = Type.void,
3896 .fn_ret_ty_ies = null,
3897 .comptime_err_ret_trace = &comptime_err_ret_trace,
3898 };
3899 defer sema.deinit();
3900
3901 (switch (resolution) {
3902 .fields => sema.resolveUnionFieldTypes(ty, union_obj),
3903 .alignment => sema.resolveUnionAlignment(ty, union_obj),
3904 .layout => sema.resolveUnionLayout(ty),
3905 .full => sema.resolveUnionFully(ty),
3906 }) catch |err| switch (err) {
3907 error.AnalysisFail => {
3908 if (!zcu.failed_analysis.contains(owner)) {
3909 try zcu.transitive_failed_analysis.put(gpa, owner, {});
3910 }
3911 return error.AnalysisFail;
3912 },
3913 error.OutOfMemory => |e| return e,
3914 error.Canceled => |e| return e,
3915 };
2743 return .{ cur_ty, cur_len };
39162744}
39172745
2746/// Asserts that `loaded_union.layout` is not `.@"packed"`.
39182747pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu) Zcu.UnionLayout {
2748 assert(loaded_union.layout != .@"packed");
2749
39192750 const ip = &zcu.intern_pool;
3920 assert(loaded_union.haveLayout(ip));
39212751 var most_aligned_field: u32 = 0;
39222752 var most_aligned_field_align: InternPool.Alignment = .@"1";
39232753 var most_aligned_field_size: u64 = 0;
......@@ -3928,11 +2758,14 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)
39282758 const field_ty: Type = .fromInterned(field_ty_ip_index);
39292759 if (field_ty.isNoReturn(zcu)) continue;
39302760
3931 const explicit_align = loaded_union.fieldAlign(ip, field_index);
3932 const field_align = if (explicit_align != .none)
3933 explicit_align
3934 else
3935 field_ty.abiAlignment(zcu);
2761 const field_align: InternPool.Alignment = a: {
2762 const explicit_aligns = loaded_union.field_aligns.get(ip);
2763 if (explicit_aligns.len > 0) {
2764 const a = explicit_aligns[field_index];
2765 if (a != .none) break :a a;
2766 }
2767 break :a field_ty.abiAlignment(zcu);
2768 };
39362769 if (field_ty.hasRuntimeBits(zcu)) {
39372770 const field_size = field_ty.abiSize(zcu);
39382771 if (field_size > payload_size) {
......@@ -3947,8 +2780,9 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)
39472780 }
39482781 payload_align = payload_align.max(field_align);
39492782 }
3950 const have_tag = loaded_union.flagsUnordered(ip).runtime_tag.hasTag();
3951 if (!have_tag or !Type.fromInterned(loaded_union.enum_tag_ty).hasRuntimeBits(zcu)) {
2783 if (!loaded_union.has_runtime_tag or
2784 !Type.fromInterned(loaded_union.enum_tag_type).hasRuntimeBits(zcu))
2785 {
39522786 return .{
39532787 .abi_size = payload_align.forward(payload_size),
39542788 .abi_align = payload_align,
......@@ -3963,10 +2797,10 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)
39632797 };
39642798 }
39652799
3966 const tag_size = Type.fromInterned(loaded_union.enum_tag_ty).abiSize(zcu);
3967 const tag_align = Type.fromInterned(loaded_union.enum_tag_ty).abiAlignment(zcu).max(.@"1");
2800 const tag_size = Type.fromInterned(loaded_union.enum_tag_type).abiSize(zcu);
2801 const tag_align = Type.fromInterned(loaded_union.enum_tag_type).abiAlignment(zcu).max(.@"1");
39682802 return .{
3969 .abi_size = loaded_union.sizeUnordered(ip),
2803 .abi_size = loaded_union.size,
39702804 .abi_align = tag_align.max(payload_align),
39712805 .most_aligned_field = most_aligned_field,
39722806 .most_aligned_field_size = most_aligned_field_size,
......@@ -3975,85 +2809,229 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)
39752809 .payload_align = payload_align,
39762810 .tag_align = tag_align,
39772811 .tag_size = tag_size,
3978 .padding = loaded_union.paddingUnordered(ip),
2812 .padding = loaded_union.padding,
39792813 };
39802814}
39812815
3982/// Returns the type of a pointer to an element.
3983/// Asserts that the type is a pointer, and that the element type is indexable.
3984/// If the element index is comptime-known, it must be passed in `offset`.
3985/// For *@Vector(n, T), return *align(a:b:h:v) T
3986/// For *[N]T, return *T
3987/// For [*]T, returns *T
3988/// For []T, returns *T
3989/// Handles const-ness and address spaces in particular.
3990/// This code is duplicated in `Sema.analyzePtrArithmetic`.
3991/// May perform type resolution and return a transitive `error.AnalysisFail`.
3992pub fn elemPtrType(ptr_ty: Type, offset: ?usize, pt: Zcu.PerThread) !Type {
2816/// Asserts that `ptr_ty` is either a many-item pointer, a slice, a C pointer, or a single pointer
2817/// to array (in other words, a pointer which is indexed by pointer arithmetic), and returns the
2818/// type of the element pointer at the given index.
2819///
2820/// Asserts that the layout of the pointer element type is resolved.
2821///
2822/// If `index` is `null`, the index is an arbitrary runtime-known value.
2823pub fn elemPtrType(ptr_ty: Type, index: ?u64, pt: Zcu.PerThread) Allocator.Error!Type {
39932824 const zcu = pt.zcu;
3994 const ptr_info = ptr_ty.ptrInfo(zcu);
3995 const elem_ty = ptr_ty.elemType2(zcu);
3996 const is_allowzero = ptr_info.flags.is_allowzero and (offset orelse 0) == 0;
3997 const parent_ty = ptr_ty.childType(zcu);
3998
3999 const VI = InternPool.Key.PtrType.VectorIndex;
4000
4001 const vector_info: struct {
4002 host_size: u16 = 0,
4003 alignment: Alignment = .none,
4004 vector_index: VI = .none,
4005 } = if (parent_ty.isVector(zcu) and ptr_info.flags.size == .one) blk: {
4006 const elem_bits = elem_ty.bitSize(zcu);
4007 if (elem_bits == 0) break :blk .{};
4008 const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits);
4009 if (!is_packed) break :blk .{};
4010
4011 break :blk .{
4012 .host_size = @intCast(parent_ty.arrayLen(zcu)),
4013 .alignment = parent_ty.abiAlignment(zcu),
4014 .vector_index = @enumFromInt(offset.?),
4015 };
4016 } else .{};
4017
4018 const alignment: Alignment = a: {
4019 // Calculate the new pointer alignment.
4020 if (ptr_info.flags.alignment == .none) {
4021 // In case of an ABI-aligned pointer, any pointer arithmetic
4022 // maintains the same ABI-alignedness.
4023 break :a vector_info.alignment;
4024 }
4025 // If the addend is not a comptime-known value we can still count on
4026 // it being a multiple of the type size.
4027 const elem_size = (try elem_ty.abiSizeInner(.sema, zcu, pt.tid)).scalar;
4028 const addend = if (offset) |off| elem_size * off else elem_size;
4029
4030 // The resulting pointer is aligned to the lcd between the offset (an
4031 // arbitrary number) and the alignment factor (always a power of two,
4032 // non zero).
4033 const new_align: Alignment = @enumFromInt(@min(
4034 @ctz(addend),
4035 ptr_info.flags.alignment.toLog2Units(),
4036 ));
4037 assert(new_align != .none);
4038 break :a new_align;
2825 const ip = &zcu.intern_pool;
2826 const ptr_info = ip.indexToKey(ptr_ty.toIntern()).ptr_type;
2827 const elem_ty: Type = switch (ptr_info.flags.size) {
2828 .slice, .many, .c => .fromInterned(ptr_info.child),
2829 .one => switch (ip.indexToKey(ptr_info.child)) {
2830 .array_type => |array_type| .fromInterned(array_type.child),
2831 else => unreachable,
2832 },
2833 };
2834 elem_ty.assertHasLayout(zcu);
2835 const elem_align: Alignment = switch (elem_ty.classify(zcu)) {
2836 .no_possible_value,
2837 .one_possible_value,
2838 => ptr_info.flags.alignment,
2839
2840 .partially_comptime,
2841 .fully_comptime,
2842 => switch (ptr_info.flags.alignment) {
2843 .none => .none,
2844 else => |array_align| .minStrict(array_align, elem_ty.abiAlignment(zcu)),
2845 },
2846
2847 .runtime => switch (ptr_info.flags.alignment) {
2848 .none => .none,
2849 else => |array_align| elem_align: {
2850 // If the index is runtime-known, use 1 as it gives the minimum possible alignment.
2851 const effective_index = index orelse 1;
2852 if (effective_index == 0) break :elem_align array_align;
2853 const byte_offset = effective_index * elem_ty.abiSize(zcu);
2854 break :elem_align .minStrict(array_align, .fromLog2Units(@ctz(byte_offset)));
2855 },
2856 },
40392857 };
4040 return pt.ptrTypeSema(.{
2858 return pt.ptrType(.{
40412859 .child = elem_ty.toIntern(),
40422860 .flags = .{
4043 .alignment = alignment,
2861 .size = .one,
40442862 .is_const = ptr_info.flags.is_const,
40452863 .is_volatile = ptr_info.flags.is_volatile,
4046 .is_allowzero = is_allowzero,
2864 .is_allowzero = ptr_info.flags.is_allowzero and (index == null or index == 0),
40472865 .address_space = ptr_info.flags.address_space,
4048 .vector_index = vector_info.vector_index,
4049 },
4050 .packed_offset = .{
4051 .host_size = vector_info.host_size,
4052 .bit_offset = 0,
2866 .alignment = elem_align,
40532867 },
40542868 });
40552869}
40562870
2871/// Asserts that `ptr_ty` is a pointer (single-item or C) to a struct, union, tuple, or slice, and
2872/// returns the type of a pointer to the field at `field_index`.
2873///
2874/// Asserts that the layout of the pointer child type is resolved.
2875///
2876/// For slices, `Value.slice_ptr_index` and `Value.slice_len_index` are used for the field index.
2877pub fn fieldPtrType(ptr_ty: Type, field_index: u32, pt: Zcu.PerThread) Allocator.Error!Type {
2878 const zcu = pt.zcu;
2879 const ip = &zcu.intern_pool;
2880 const ptr_info = ip.indexToKey(ptr_ty.toIntern()).ptr_type;
2881 assert(ptr_info.flags.size == .one or ptr_info.flags.size == .c);
2882 const aggregate_ty: Type = .fromInterned(ptr_info.child);
2883 aggregate_ty.assertHasLayout(zcu);
2884 // We only exit this `switch` for default-layout aggregates, where the field pointer alignment
2885 // is a simple minimum of the aggregate pointer alignment and the field alignment.
2886 // `field_align` is `.none` if there is no explicit alignment annotation.
2887 const field_ty: Type, const field_align: Alignment = switch (aggregate_ty.zigTypeTag(zcu)) {
2888 .@"struct" => switch (aggregate_ty.containerLayout(zcu)) {
2889 .auto => field: {
2890 if (aggregate_ty.isTuple(zcu)) {
2891 break :field .{ aggregate_ty.fieldType(field_index, zcu), .none };
2892 }
2893 const struct_obj = ip.loadStructType(aggregate_ty.toIntern());
2894 break :field .{
2895 .fromInterned(struct_obj.field_types.get(ip)[field_index]),
2896 struct_obj.field_aligns.getOrNone(ip, field_index),
2897 };
2898 },
2899 .@"extern" => {
2900 // Field alignment is determined based on the actual field offset. For instance, in
2901 // `extern struct { x: u32, y: u16 }`, the `y` field is 4-byte aligned.
2902 const field_ty = aggregate_ty.fieldType(field_index, zcu);
2903 const field_offset = aggregate_ty.structFieldOffset(field_index, zcu);
2904 const parent_align = switch (ptr_info.flags.alignment) {
2905 .none => aggregate_ty.abiAlignment(zcu),
2906 else => |a| a,
2907 };
2908 const actual_field_align = switch (field_offset) {
2909 0 => parent_align,
2910 else => parent_align.minStrict(.fromLog2Units(@ctz(field_offset))),
2911 };
2912 const field_ptr_align: Alignment = a: {
2913 if (ptr_info.flags.alignment == .none and
2914 aggregate_ty.explicitFieldAlignment(field_index, zcu) == .none and
2915 actual_field_align == field_ty.abiAlignment(zcu))
2916 {
2917 // There's no user-specified 'align' in sight, and the alignment from the
2918 // field offset matches the field type's natural alignment, so just use a
2919 // default-aligned pointer.
2920 break :a .none;
2921 }
2922 break :a actual_field_align;
2923 };
2924 var field_ptr_info = ptr_info;
2925 field_ptr_info.child = field_ty.toIntern();
2926 field_ptr_info.flags.alignment = field_ptr_align;
2927 return pt.ptrType(field_ptr_info);
2928 },
2929 .@"packed" => {
2930 var field_ptr_info = ptr_info;
2931 if (field_ptr_info.flags.alignment == .none) {
2932 field_ptr_info.flags.alignment = aggregate_ty.abiAlignment(zcu);
2933 }
2934 field_ptr_info.packed_offset = packed_offset: {
2935 comptime assert(Type.packed_struct_layout_version == 2);
2936 const bit_offset = zcu.structPackedFieldBitOffset(
2937 ip.loadStructType(aggregate_ty.toIntern()),
2938 field_index,
2939 );
2940 break :packed_offset if (ptr_info.packed_offset.host_size != 0) .{
2941 .host_size = ptr_info.packed_offset.host_size,
2942 .bit_offset = ptr_info.packed_offset.bit_offset + bit_offset,
2943 } else .{
2944 .host_size = switch (zcu.comp.getZigBackend()) {
2945 else => @intCast((aggregate_ty.bitSize(zcu) + 7) / 8),
2946 .stage2_x86_64, .stage2_c => @intCast(aggregate_ty.abiSize(zcu)),
2947 },
2948 .bit_offset = ptr_info.packed_offset.bit_offset + bit_offset,
2949 };
2950 };
2951 field_ptr_info.child = aggregate_ty.fieldType(field_index, zcu).toIntern();
2952 return pt.ptrType(field_ptr_info);
2953 },
2954 },
2955 .@"union" => switch (aggregate_ty.containerLayout(zcu)) {
2956 .auto => field: {
2957 const union_obj = ip.loadUnionType(aggregate_ty.toIntern());
2958 break :field .{
2959 .fromInterned(union_obj.field_types.get(ip)[field_index]),
2960 union_obj.field_aligns.getOrNone(ip, field_index),
2961 };
2962 },
2963 .@"extern" => {
2964 // The alignment always matches that of the union pointer. If the union pointer is
2965 // default aligned (`.none`), we may need to explicitly align the result pointer.
2966 const field_ty = aggregate_ty.fieldType(field_index, zcu);
2967 var field_ptr_info = ptr_info;
2968 field_ptr_info.child = field_ty.toIntern();
2969 if (field_ptr_info.flags.alignment == .none and
2970 Alignment.compareStrict(field_ty.abiAlignment(zcu), .neq, aggregate_ty.abiAlignment(zcu)))
2971 {
2972 field_ptr_info.flags.alignment = aggregate_ty.abiAlignment(zcu);
2973 }
2974 return pt.ptrType(field_ptr_info);
2975 },
2976 .@"packed" => {
2977 const field_ty = aggregate_ty.fieldType(field_index, zcu);
2978 var field_ptr_info = ptr_info;
2979 if (field_ptr_info.flags.alignment == .none) {
2980 const resolved_align = aggregate_ty.abiAlignment(zcu);
2981 if (field_ty.abiAlignment(zcu) != resolved_align) {
2982 field_ptr_info.flags.alignment = resolved_align;
2983 }
2984 }
2985 field_ptr_info.child = aggregate_ty.fieldType(field_index, zcu).toIntern();
2986 return pt.ptrType(field_ptr_info);
2987 },
2988 },
2989 .pointer => field: {
2990 assert(aggregate_ty.isSlice(zcu));
2991 break :field switch (field_index) {
2992 Value.slice_ptr_index => .{ aggregate_ty.slicePtrFieldType(zcu), .none },
2993 Value.slice_len_index => .{ .usize, .none },
2994 else => unreachable,
2995 };
2996 },
2997 else => unreachable,
2998 };
2999 const field_ptr_align: Alignment = a: {
3000 if (aggregate_ty.zigTypeTag(zcu) == .@"struct" and aggregate_ty.structFieldIsComptime(field_index, zcu)) {
3001 // For `comptime` fields, just use exactly what was specified, or ABI alignment if nothing was specified.
3002 break :a field_align;
3003 }
3004 const actual_field_align = switch (field_align) {
3005 .none => switch (ip.indexToKey(aggregate_ty.toIntern())) {
3006 .tuple_type, .union_type => field_ty.abiAlignment(zcu),
3007 .struct_type => field_ty.defaultStructFieldAlignment(.auto, zcu),
3008 .ptr_type => Type.usize.abiAlignment(zcu),
3009 else => unreachable,
3010 },
3011 else => |a| a,
3012 };
3013 const actual_aggregate_align = switch (ptr_info.flags.alignment) {
3014 .none => aggregate_ty.abiAlignment(zcu),
3015 else => |a| a,
3016 };
3017 if (actual_aggregate_align.compareStrict(.lt, actual_field_align)) {
3018 // Underaligned aggregate; use that alignment.
3019 assert(ptr_info.flags.alignment != .none);
3020 break :a actual_aggregate_align;
3021 }
3022 if (field_align == .none and actual_field_align == field_ty.abiAlignment(zcu)) {
3023 // No explicit annotation on the field (nor an unusual default), and the aggregate
3024 // alignment is irrelevant to us, so return an un-annotated pointer.
3025 break :a .none;
3026 }
3027 break :a actual_field_align;
3028 };
3029 var field_ptr_info = ptr_info;
3030 field_ptr_info.flags.alignment = field_ptr_align;
3031 field_ptr_info.child = field_ty.toIntern();
3032 return pt.ptrType(field_ptr_info);
3033}
3034
40573035pub fn containerTypeName(ty: Type, ip: *const InternPool) InternPool.NullTerminatedString {
40583036 return switch (ip.indexToKey(ty.toIntern())) {
40593037 .struct_type => ip.loadStructType(ty.toIntern()).name,
......@@ -4064,14 +3042,257 @@ pub fn containerTypeName(ty: Type, ip: *const InternPool) InternPool.NullTermina
40643042 };
40653043}
40663044
4067/// Returns `true` if a value of this type is always `null`.
4068/// Returns `false` if a value of this type is neve `null`.
4069/// Returns `null` otherwise.
4070pub fn isNullFromType(ty: Type, zcu: *const Zcu) ?bool {
4071 if (ty.zigTypeTag(zcu) != .optional and !ty.isCPtr(zcu)) return false;
4072 const child = ty.optionalChild(zcu);
4073 if (child.zigTypeTag(zcu) == .noreturn) return true; // `?noreturn` is always null
4074 return null;
3045pub fn destructurable(ty: Type, zcu: *const Zcu) bool {
3046 return switch (ty.zigTypeTag(zcu)) {
3047 .array, .vector => true,
3048 .@"struct" => ty.isTuple(zcu),
3049 else => false,
3050 };
3051}
3052
3053pub const UnpackableReason = union(enum) {
3054 comptime_only,
3055 pointer,
3056 enum_inferred_int_tag: Type,
3057 non_packed_struct: Type,
3058 non_packed_union: Type,
3059 slice,
3060 other,
3061};
3062
3063/// Returns `null` iff `ty` is allowed in packed types.
3064pub fn unpackable(ty: Type, zcu: *const Zcu) ?UnpackableReason {
3065 return switch (ty.zigTypeTag(zcu)) {
3066 .void,
3067 .bool,
3068 .float,
3069 .int,
3070 => null,
3071
3072 .type,
3073 .comptime_float,
3074 .comptime_int,
3075 .enum_literal,
3076 .undefined,
3077 .null,
3078 => .comptime_only,
3079
3080 .noreturn,
3081 .@"opaque",
3082 .error_union,
3083 .error_set,
3084 .frame,
3085 .@"anyframe",
3086 .@"fn",
3087 .array,
3088 .vector,
3089 => .other,
3090
3091 .optional => if (ty.isPtrLikeOptional(zcu))
3092 .pointer
3093 else
3094 .other,
3095
3096 .pointer => switch (ty.ptrSize(zcu)) {
3097 .slice => .slice,
3098 .one, .many, .c => .pointer,
3099 },
3100
3101 .@"enum" => switch (zcu.intern_pool.loadEnumType(ty.toIntern()).int_tag_mode) {
3102 .explicit => null,
3103 .auto => .{ .enum_inferred_int_tag = ty },
3104 },
3105
3106 .@"struct" => switch (ty.containerLayout(zcu)) {
3107 .@"packed" => null,
3108 .auto, .@"extern" => .{ .non_packed_struct = ty },
3109 },
3110 .@"union" => switch (ty.containerLayout(zcu)) {
3111 .@"packed" => null,
3112 .auto, .@"extern" => .{ .non_packed_union = ty },
3113 },
3114 };
3115}
3116
3117pub const ExternPosition = enum {
3118 ret_ty,
3119 param_ty,
3120 union_field,
3121 struct_field,
3122 element,
3123 other,
3124};
3125
3126/// Returns true if `ty` is allowed in extern types.
3127/// Asserts that `ty` is fully resolved.
3128/// Keep in sync with `Sema.explainWhyTypeIsNotExtern`.
3129pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool {
3130 ty.assertHasLayout(zcu);
3131 return switch (ty.zigTypeTag(zcu)) {
3132 .type,
3133 .comptime_float,
3134 .comptime_int,
3135 .enum_literal,
3136 .undefined,
3137 .null,
3138 .error_union,
3139 .error_set,
3140 .frame,
3141 => false,
3142
3143 .void => switch (position) {
3144 .ret_ty,
3145 .union_field,
3146 .struct_field,
3147 .element,
3148 => true,
3149 .param_ty,
3150 .other,
3151 => false,
3152 },
3153
3154 .noreturn => position == .ret_ty,
3155
3156 .@"opaque",
3157 .bool,
3158 .float,
3159 .@"anyframe",
3160 => true,
3161
3162 .pointer => {
3163 if (ty.isSlice(zcu)) return false;
3164 const child_ty = ty.childType(zcu);
3165 if (child_ty.zigTypeTag(zcu) == .@"fn") {
3166 return ty.isConstPtr(zcu) and validateExternCallconv(child_ty.fnCallingConvention(zcu));
3167 }
3168 return true;
3169 },
3170 .int => switch (ty.intInfo(zcu).bits) {
3171 0, 8, 16, 32, 64, 128 => true,
3172 else => false,
3173 },
3174 .@"fn" => {
3175 if (position != .other) return false;
3176 return validateExternCallconv(ty.fnCallingConvention(zcu));
3177 },
3178 .@"enum" => {
3179 const enum_obj = zcu.intern_pool.loadEnumType(ty.toIntern());
3180 return switch (enum_obj.int_tag_mode) {
3181 .auto => false,
3182 .explicit => Type.fromInterned(enum_obj.int_tag_type).validateExtern(position, zcu),
3183 };
3184 },
3185 .@"struct" => {
3186 const struct_obj = zcu.intern_pool.loadStructType(ty.toIntern());
3187 return switch (struct_obj.layout) {
3188 .auto => false,
3189 .@"extern" => true,
3190 .@"packed" => switch (struct_obj.packed_backing_mode) {
3191 .auto => false,
3192 .explicit => Type.fromInterned(struct_obj.packed_backing_int_type).validateExtern(position, zcu),
3193 },
3194 };
3195 },
3196 .@"union" => {
3197 const union_obj = zcu.intern_pool.loadUnionType(ty.toIntern());
3198 return switch (union_obj.layout) {
3199 .auto => false,
3200 .@"extern" => true,
3201 .@"packed" => switch (union_obj.packed_backing_mode) {
3202 .auto => false,
3203 .explicit => Type.fromInterned(union_obj.packed_backing_int_type).validateExtern(position, zcu),
3204 },
3205 };
3206 },
3207 .array => switch (position) {
3208 .ret_ty,
3209 .param_ty,
3210 => false,
3211
3212 .union_field,
3213 .struct_field,
3214 .element,
3215 .other,
3216 => ty.childType(zcu).validateExtern(.element, zcu),
3217 },
3218 .vector => ty.childType(zcu).validateExtern(.element, zcu),
3219 .optional => ty.isPtrLikeOptional(zcu),
3220 };
3221}
3222fn validateExternCallconv(cc: std.builtin.CallingConvention) bool {
3223 return switch (cc) {
3224 // For now we want to authorize PTX kernel to use zig objects, even if we end up exposing the ABI.
3225 // The goal is to experiment with more integrated CPU/GPU code.
3226 .nvptx_kernel => true,
3227 else => !target_util.fnCallConvAllowsZigTypes(cc),
3228 };
3229}
3230
3231/// Asserts that `ty` has resolved layout.
3232pub fn assertHasLayout(ty: Type, zcu: *const Zcu) void {
3233 if (!std.debug.runtime_safety) {
3234 // This early exit isn't necessary (`Zcu.assertUpToDate` checks `std.debug.runtime_safety`
3235 // itself), but LLVM has been observed to fail at optimizing away this safety check, which
3236 // has a major performance impact on ReleaseFast compiler builds.
3237 return;
3238 }
3239 switch (zcu.intern_pool.indexToKey(ty.toIntern())) {
3240 .int_type,
3241 .ptr_type,
3242 .anyframe_type,
3243 .simple_type,
3244 .opaque_type,
3245 .error_set_type,
3246 .inferred_error_set_type,
3247 => {},
3248 .func_type => |func_type| {
3249 for (func_type.param_types.get(&zcu.intern_pool)) |param_ty| {
3250 assertHasLayout(.fromInterned(param_ty), zcu);
3251 }
3252 assertHasLayout(.fromInterned(func_type.return_type), zcu);
3253 },
3254 .array_type => |arr| assertHasLayout(.fromInterned(arr.child), zcu),
3255 .vector_type => |vec| assertHasLayout(.fromInterned(vec.child), zcu),
3256 .opt_type => |child| assertHasLayout(.fromInterned(child), zcu),
3257 .error_union_type => |eu| assertHasLayout(.fromInterned(eu.payload_type), zcu),
3258 .tuple_type => |tuple| for (tuple.types.get(&zcu.intern_pool)) |field_ty| {
3259 assertHasLayout(.fromInterned(field_ty), zcu);
3260 },
3261 .struct_type => {
3262 assert(zcu.intern_pool.loadStructType(ty.toIntern()).want_layout);
3263 zcu.assertUpToDate(.wrap(.{ .type_layout = ty.toIntern() }));
3264 },
3265 .union_type => {
3266 assert(zcu.intern_pool.loadUnionType(ty.toIntern()).want_layout);
3267 zcu.assertUpToDate(.wrap(.{ .type_layout = ty.toIntern() }));
3268 },
3269 .enum_type => {
3270 assert(zcu.intern_pool.loadEnumType(ty.toIntern()).want_layout);
3271 zcu.assertUpToDate(.wrap(.{ .type_layout = ty.toIntern() }));
3272 },
3273
3274 // values, not types
3275 .simple_value,
3276 .variable,
3277 .@"extern",
3278 .func,
3279 .int,
3280 .err,
3281 .error_union,
3282 .enum_literal,
3283 .enum_tag,
3284 .float,
3285 .ptr,
3286 .slice,
3287 .opt,
3288 .aggregate,
3289 .un,
3290 .bitpack,
3291 .undef,
3292 // memoization, not types
3293 .memoized_call,
3294 => unreachable,
3295 }
40753296}
40763297
40773298/// Recursively walks the type and marks for each subtype how many times it has been seen
......@@ -4138,13 +3359,13 @@ fn collectSubtypes(ty: Type, pt: Zcu.PerThread, visited: *std.AutoArrayHashMapUn
41383359 .error_union,
41393360 .enum_literal,
41403361 .enum_tag,
4141 .empty_enum_value,
41423362 .float,
41433363 .ptr,
41443364 .slice,
41453365 .opt,
41463366 .aggregate,
41473367 .un,
3368 .bitpack,
41483369 // memoization, not types
41493370 .memoized_call,
41503371 => unreachable,
......@@ -4243,6 +3464,7 @@ pub const Comparison = struct {
42433464 };
42443465};
42453466
3467pub const @"u0": Type = .{ .ip_index = .u0_type };
42463468pub const @"u1": Type = .{ .ip_index = .u1_type };
42473469pub const @"u8": Type = .{ .ip_index = .u8_type };
42483470pub const @"u16": Type = .{ .ip_index = .u16_type };
src/Value.zig+295-897
......@@ -146,80 +146,23 @@ pub fn toType(self: Value) Type {
146146 return Type.fromInterned(self.toIntern());
147147}
148148
149pub fn intFromEnum(val: Value, ty: Type, pt: Zcu.PerThread) Allocator.Error!Value {
150 const ip = &pt.zcu.intern_pool;
151 const enum_ty = ip.typeOf(val.toIntern());
152 return switch (ip.indexToKey(enum_ty)) {
153 // Assume it is already an integer and return it directly.
154 .simple_type, .int_type => val,
155 .enum_literal => |enum_literal| {
156 const field_index = ty.enumFieldIndex(enum_literal, pt.zcu).?;
157 switch (ip.indexToKey(ty.toIntern())) {
158 // Assume it is already an integer and return it directly.
159 .simple_type, .int_type => return val,
160 .enum_type => {
161 const enum_type = ip.loadEnumType(ty.toIntern());
162 if (enum_type.values.len != 0) {
163 return Value.fromInterned(enum_type.values.get(ip)[field_index]);
164 } else {
165 // Field index and integer values are the same.
166 return pt.intValue(Type.fromInterned(enum_type.tag_ty), field_index);
167 }
168 },
169 else => unreachable,
170 }
171 },
172 .enum_type => try pt.getCoerced(val, Type.fromInterned(ip.loadEnumType(enum_ty).tag_ty)),
173 else => unreachable,
174 };
149pub fn intFromEnum(val: Value, zcu: *const Zcu) Value {
150 return .fromInterned(zcu.intern_pool.indexToKey(val.toIntern()).enum_tag.int);
175151}
176152
177pub const ResolveStrat = Type.ResolveStrat;
178
179/// Asserts the value is an integer.
180pub fn toBigInt(val: Value, space: *BigIntSpace, zcu: *Zcu) BigIntConst {
181 return val.toBigIntAdvanced(space, .normal, zcu, {}) catch unreachable;
182}
183
184pub fn toBigIntSema(val: Value, space: *BigIntSpace, pt: Zcu.PerThread) !BigIntConst {
185 return try val.toBigIntAdvanced(space, .sema, pt.zcu, pt.tid);
186}
187
188/// Asserts the value is an integer.
189pub fn toBigIntAdvanced(
190 val: Value,
191 space: *BigIntSpace,
192 comptime strat: ResolveStrat,
193 zcu: *Zcu,
194 tid: strat.Tid(),
195) Zcu.SemaError!BigIntConst {
153/// Asserts that `val` is an integer.
154pub fn toBigInt(val: Value, space: *BigIntSpace, zcu: *const Zcu) BigIntConst {
155 if (val.getUnsignedInt(zcu)) |x| {
156 return BigIntMutable.init(&space.limbs, x).toConst();
157 }
196158 const ip = &zcu.intern_pool;
197 return switch (val.toIntern()) {
198 .bool_false => BigIntMutable.init(&space.limbs, 0).toConst(),
199 .bool_true => BigIntMutable.init(&space.limbs, 1).toConst(),
200 .null_value => BigIntMutable.init(&space.limbs, 0).toConst(),
201 else => switch (ip.indexToKey(val.toIntern())) {
202 .int => |int| switch (int.storage) {
203 .u64, .i64, .big_int => int.storage.toBigInt(space),
204 .lazy_align, .lazy_size => |ty| {
205 if (strat == .sema) try Type.fromInterned(ty).resolveLayout(strat.pt(zcu, tid));
206 const x = switch (int.storage) {
207 else => unreachable,
208 .lazy_align => Type.fromInterned(ty).abiAlignment(zcu).toByteUnits() orelse 0,
209 .lazy_size => Type.fromInterned(ty).abiSize(zcu),
210 };
211 return BigIntMutable.init(&space.limbs, x).toConst();
212 },
213 },
214 .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).toBigIntAdvanced(space, strat, zcu, tid),
215 .opt, .ptr => BigIntMutable.init(
216 &space.limbs,
217 (try val.getUnsignedIntInner(strat, zcu, tid)).?,
218 ).toConst(),
219 .err => |err| BigIntMutable.init(&space.limbs, ip.getErrorValueIfExists(err.name).?).toConst(),
220 else => unreachable,
221 },
159 const int_key = switch (ip.indexToKey(val.toIntern())) {
160 .enum_tag => |enum_tag| ip.indexToKey(enum_tag.int).int,
161 .bitpack => |bitpack| ip.indexToKey(bitpack.backing_int_val).int,
162 .int => |int| int,
163 else => unreachable,
222164 };
165 return int_key.storage.toBigInt(space);
223166}
224167
225168pub fn isFuncBody(val: Value, zcu: *Zcu) bool {
......@@ -240,31 +183,17 @@ pub fn getVariable(val: Value, mod: *Zcu) ?InternPool.Key.Variable {
240183 };
241184}
242185
243/// If the value fits in a u64, return it, otherwise null.
244/// Asserts not undefined.
245pub fn getUnsignedInt(val: Value, zcu: *const Zcu) ?u64 {
246 return getUnsignedIntInner(val, .normal, zcu, {}) catch unreachable;
247}
248
249/// Asserts the value is an integer and it fits in a u64
186/// Asserts the value is a (defined) integer and it fits in a u64.
250187pub fn toUnsignedInt(val: Value, zcu: *const Zcu) u64 {
251188 return getUnsignedInt(val, zcu).?;
252189}
253190
254pub fn getUnsignedIntSema(val: Value, pt: Zcu.PerThread) !?u64 {
255 return try val.getUnsignedIntInner(.sema, pt.zcu, pt.tid);
256}
257
258191/// If the value fits in a u64, return it, otherwise null.
259192/// Asserts not undefined.
260pub fn getUnsignedIntInner(
261 val: Value,
262 comptime strat: ResolveStrat,
263 zcu: strat.ZcuPtr(),
264 tid: strat.Tid(),
265) !?u64 {
193pub fn getUnsignedInt(val: Value, zcu: *const Zcu) ?u64 {
266194 return switch (val.toIntern()) {
267195 .undef => unreachable,
196 .null_value => 0,
268197 .bool_false => 0,
269198 .bool_true => 1,
270199 else => switch (zcu.intern_pool.indexToKey(val.toIntern())) {
......@@ -273,37 +202,28 @@ pub fn getUnsignedIntInner(
273202 .big_int => |big_int| big_int.toInt(u64) catch null,
274203 .u64 => |x| x,
275204 .i64 => |x| std.math.cast(u64, x),
276 .lazy_align => |ty| (try Type.fromInterned(ty).abiAlignmentInner(strat.toLazy(), zcu, tid)).scalar.toByteUnits() orelse 0,
277 .lazy_size => |ty| (try Type.fromInterned(ty).abiSizeInner(strat.toLazy(), zcu, tid)).scalar,
278205 },
279206 .ptr => |ptr| switch (ptr.base_addr) {
280207 .int => ptr.byte_offset,
281208 .field => |field| {
282 const base_addr = (try Value.fromInterned(field.base).getUnsignedIntInner(strat, zcu, tid)) orelse return null;
209 const base_addr = Value.fromInterned(field.base).getUnsignedInt(zcu) orelse return null;
283210 const struct_ty = Value.fromInterned(field.base).typeOf(zcu).childType(zcu);
284 if (strat == .sema) {
285 const pt = strat.pt(zcu, tid);
286 try struct_ty.resolveLayout(pt);
287 }
288211 return base_addr + struct_ty.structFieldOffset(@intCast(field.index), zcu) + ptr.byte_offset;
289212 },
290213 else => null,
291214 },
292215 .opt => |opt| switch (opt.val) {
293216 .none => 0,
294 else => |payload| Value.fromInterned(payload).getUnsignedIntInner(strat, zcu, tid),
217 else => |payload| Value.fromInterned(payload).getUnsignedInt(zcu),
295218 },
296 .enum_tag => |enum_tag| return Value.fromInterned(enum_tag.int).getUnsignedIntInner(strat, zcu, tid),
219 .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).getUnsignedInt(zcu),
220 .bitpack => |bitpack| Value.fromInterned(bitpack.backing_int_val).getUnsignedInt(zcu),
221 .err => |err| zcu.intern_pool.getErrorValueIfExists(err.name).?,
297222 else => null,
298223 },
299224 };
300225}
301226
302/// Asserts the value is an integer and it fits in a u64
303pub fn toUnsignedIntSema(val: Value, pt: Zcu.PerThread) !u64 {
304 return (try getUnsignedIntInner(val, .sema, pt.zcu, pt.tid)).?;
305}
306
307227/// Asserts the value is an integer and it fits in a i64
308228pub fn toSignedInt(val: Value, zcu: *const Zcu) i64 {
309229 return switch (val.toIntern()) {
......@@ -314,8 +234,6 @@ pub fn toSignedInt(val: Value, zcu: *const Zcu) i64 {
314234 .big_int => |big_int| big_int.toInt(i64) catch unreachable,
315235 .i64 => |x| x,
316236 .u64 => |x| @intCast(x),
317 .lazy_align => |ty| @intCast(Type.fromInterned(ty).abiAlignment(zcu).toByteUnits() orelse 0),
318 .lazy_size => |ty| @intCast(Type.fromInterned(ty).abiSize(zcu)),
319237 },
320238 else => unreachable,
321239 },
......@@ -393,7 +311,7 @@ pub fn writeToMemory(val: Value, pt: Zcu.PerThread, buffer: []u8) error{
393311 // We use byte_count instead of abi_size here, so that any padding bytes
394312 // follow the data bytes, on both big- and little-endian systems.
395313 const byte_count = (@as(usize, @intCast(ty.bitSize(zcu))) + 7) / 8;
396 return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0);
314 return writeToPackedMemory(val, pt, buffer[0..byte_count], 0);
397315 },
398316 .@"struct" => {
399317 const struct_type = zcu.typeToStruct(ty) orelse return error.IllDefinedMemoryLayout;
......@@ -412,8 +330,8 @@ pub fn writeToMemory(val: Value, pt: Zcu.PerThread, buffer: []u8) error{
412330 try writeToMemory(field_val, pt, buffer[off..]);
413331 },
414332 .@"packed" => {
415 const byte_count = (@as(usize, @intCast(ty.bitSize(zcu))) + 7) / 8;
416 return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0);
333 const int_index = ip.indexToKey(val.toIntern()).bitpack.backing_int_val;
334 return Value.fromInterned(int_index).writeToMemory(pt, buffer);
417335 },
418336 }
419337 },
......@@ -428,15 +346,14 @@ pub fn writeToMemory(val: Value, pt: Zcu.PerThread, buffer: []u8) error{
428346 const byte_count: usize = @intCast(field_type.abiSize(zcu));
429347 return writeToMemory(field_val, pt, buffer[0..byte_count]);
430348 } else {
431 const backing_ty = try ty.unionBackingType(pt);
349 const backing_ty = try ty.externUnionBackingType(pt);
432350 const byte_count: usize = @intCast(backing_ty.abiSize(zcu));
433 return writeToMemory(val.unionValue(zcu), pt, buffer[0..byte_count]);
351 return writeToMemory(val.unionPayload(zcu), pt, buffer[0..byte_count]);
434352 }
435353 },
436354 .@"packed" => {
437 const backing_ty = try ty.unionBackingType(pt);
438 const byte_count: usize = @intCast(backing_ty.abiSize(zcu));
439 return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0);
355 const int_val: Value = .fromInterned(ip.indexToKey(val.toIntern()).bitpack.backing_int_val);
356 return writeToMemory(int_val, pt, buffer);
440357 },
441358 },
442359 .optional => {
......@@ -458,7 +375,6 @@ pub fn writeToMemory(val: Value, pt: Zcu.PerThread, buffer: []u8) error{
458375/// big-endian packed memory layouts start at the end of the buffer.
459376pub fn writeToPackedMemory(
460377 val: Value,
461 ty: Type,
462378 pt: Zcu.PerThread,
463379 buffer: []u8,
464380 bit_offset: usize,
......@@ -467,6 +383,7 @@ pub fn writeToPackedMemory(
467383 const ip = &zcu.intern_pool;
468384 const target = zcu.getTarget();
469385 const endian = target.cpu.arch.endian();
386 const ty = val.typeOf(zcu);
470387 if (val.isUndef(zcu)) {
471388 const bit_size: usize = @intCast(ty.bitSize(zcu));
472389 if (bit_size != 0) {
......@@ -487,22 +404,22 @@ pub fn writeToPackedMemory(
487404 buffer[byte_index] &= ~(@as(u8, 1) << @as(u3, @intCast(bit_offset % 8)));
488405 }
489406 },
490 .int, .@"enum" => {
491 if (buffer.len == 0) return;
407 .@"enum" => {
408 const int_val = val.intFromEnum(zcu);
409 return int_val.writeToPackedMemory(pt, buffer, bit_offset);
410 },
411 .pointer => {
412 assert(!ty.isSlice(zcu)); // No well defined layout.
413 if (ip.getBackingAddrTag(val.toIntern()).? != .int) return error.ReinterpretDeclRef;
414 const addr = val.toUnsignedInt(zcu);
415 std.mem.writeVarPackedInt(buffer, bit_offset, zcu.getTarget().ptrBitWidth(), addr, endian);
416 },
417 .int => {
492418 const bits = ty.intInfo(zcu).bits;
493 if (bits == 0) return;
494
495 switch (ip.indexToKey((try val.intFromEnum(ty, pt)).toIntern()).int.storage) {
419 if (bits == 0 or buffer.len == 0) return;
420 switch (ip.indexToKey(val.toIntern()).int.storage) {
496421 inline .u64, .i64 => |int| std.mem.writeVarPackedInt(buffer, bit_offset, bits, int, endian),
497422 .big_int => |bigint| bigint.writePackedTwosComplement(buffer, bit_offset, bits, endian),
498 .lazy_align => |lazy_align| {
499 const num = Type.fromInterned(lazy_align).abiAlignment(zcu).toByteUnits() orelse 0;
500 std.mem.writeVarPackedInt(buffer, bit_offset, bits, num, endian);
501 },
502 .lazy_size => |lazy_size| {
503 const num = Type.fromInterned(lazy_size).abiSize(zcu);
504 std.mem.writeVarPackedInt(buffer, bit_offset, bits, num, endian);
505 },
506423 }
507424 },
508425 .float => switch (ty.floatBits(target)) {
......@@ -524,58 +441,21 @@ pub fn writeToPackedMemory(
524441 // On big-endian systems, LLVM reverses the element order of vectors by default
525442 const tgt_elem_i = if (endian == .big) len - elem_i - 1 else elem_i;
526443 const elem_val = try val.elemValue(pt, tgt_elem_i);
527 try elem_val.writeToPackedMemory(elem_ty, pt, buffer, bit_offset + bits);
444 try elem_val.writeToPackedMemory(pt, buffer, bit_offset + bits);
528445 bits += elem_bit_size;
529446 }
530447 },
531 .@"struct" => {
532 const struct_type = ip.loadStructType(ty.toIntern());
533 // Sema is supposed to have emitted a compile error already in the case of Auto,
534 // and Extern is handled in non-packed writeToMemory.
535 assert(struct_type.layout == .@"packed");
536 var bits: u16 = 0;
537 for (0..struct_type.field_types.len) |i| {
538 const field_val = Value.fromInterned(switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
539 .bytes => unreachable,
540 .elems => |elems| elems[i],
541 .repeated_elem => |elem| elem,
542 });
543 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
544 const field_bits: u16 = @intCast(field_ty.bitSize(zcu));
545 try field_val.writeToPackedMemory(field_ty, pt, buffer, bit_offset + bits);
546 bits += field_bits;
547 }
548 },
549 .@"union" => {
550 const union_obj = zcu.typeToUnion(ty).?;
551 switch (union_obj.flagsUnordered(ip).layout) {
552 .auto, .@"extern" => unreachable, // Handled in non-packed writeToMemory
553 .@"packed" => {
554 if (val.unionTag(zcu)) |union_tag| {
555 const field_index = zcu.unionTagFieldIndex(union_obj, union_tag).?;
556 const field_type = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
557 const field_val = try val.fieldValue(pt, field_index);
558 return field_val.writeToPackedMemory(field_type, pt, buffer, bit_offset);
559 } else {
560 const backing_ty = try ty.unionBackingType(pt);
561 return val.unionValue(zcu).writeToPackedMemory(backing_ty, pt, buffer, bit_offset);
562 }
563 },
564 }
565 },
566 .pointer => {
567 assert(!ty.isSlice(zcu)); // No well defined layout.
568 if (ip.getBackingAddrTag(val.toIntern()).? != .int) return error.ReinterpretDeclRef;
569 return val.writeToPackedMemory(Type.usize, pt, buffer, bit_offset);
448 .@"struct", .@"union" => {
449 assert(ty.containerLayout(zcu) == .@"packed");
450 const int_val: Value = .fromInterned(ip.indexToKey(val.toIntern()).bitpack.backing_int_val);
451 return int_val.writeToPackedMemory(pt, buffer, bit_offset);
570452 },
571453 .optional => {
572454 assert(ty.isPtrLikeOptional(zcu));
573 const child = ty.optionalChild(zcu);
574 const opt_val = val.optionalValue(zcu);
575 if (opt_val) |some| {
576 return some.writeToPackedMemory(child, pt, buffer, bit_offset);
455 if (val.optionalValue(zcu)) |ptr_val| {
456 return ptr_val.writeToPackedMemory(pt, buffer, bit_offset);
577457 } else {
578 return writeToPackedMemory(try pt.intValue(Type.usize, 0), Type.usize, pt, buffer, bit_offset);
458 return Value.zero_usize.writeToPackedMemory(pt, buffer, bit_offset);
579459 }
580460 },
581461 else => @panic("TODO implement writeToPackedMemory for more types"),
......@@ -625,13 +505,12 @@ pub fn readFromPackedMemory(
625505 pt: Zcu.PerThread,
626506 buffer: []const u8,
627507 bit_offset: usize,
628 arena: Allocator,
508 gpa: Allocator,
629509) error{
630510 IllDefinedMemoryLayout,
631511 OutOfMemory,
632512}!Value {
633513 const zcu = pt.zcu;
634 const ip = &zcu.intern_pool;
635514 const target = zcu.getTarget();
636515 const endian = target.cpu.arch.endian();
637516 switch (ty.zigTypeTag(zcu)) {
......@@ -665,7 +544,8 @@ pub fn readFromPackedMemory(
665544 const abi_size: usize = @intCast(ty.abiSize(zcu));
666545 const Limb = std.math.big.Limb;
667546 const limb_count = (abi_size + @sizeOf(Limb) - 1) / @sizeOf(Limb);
668 const limbs_buffer = try arena.alloc(Limb, limb_count);
547 const limbs_buffer = try gpa.alloc(Limb, limb_count);
548 defer gpa.free(limbs_buffer);
669549
670550 var bigint = BigIntMutable.init(limbs_buffer, 0);
671551 bigint.readPackedTwosComplement(buffer, bit_offset, bits, endian, int_info.signedness);
......@@ -673,7 +553,7 @@ pub fn readFromPackedMemory(
673553 },
674554 .@"enum" => {
675555 const int_ty = ty.intTagType(zcu);
676 const int_val = try Value.readFromPackedMemory(int_ty, pt, buffer, bit_offset, arena);
556 const int_val = try Value.readFromPackedMemory(int_ty, pt, buffer, bit_offset, gpa);
677557 return pt.getCoerced(int_val, ty);
678558 },
679559 .float => return Value.fromInterned(try pt.intern(.{ .float = .{
......@@ -689,64 +569,35 @@ pub fn readFromPackedMemory(
689569 } })),
690570 .vector => {
691571 const elem_ty = ty.childType(zcu);
692 const elems = try arena.alloc(InternPool.Index, @intCast(ty.arrayLen(zcu)));
572 const elems = try gpa.alloc(InternPool.Index, @intCast(ty.arrayLen(zcu)));
573 defer gpa.free(elems);
693574
694575 var bits: u16 = 0;
695576 const elem_bit_size: u16 = @intCast(elem_ty.bitSize(zcu));
696577 for (elems, 0..) |_, i| {
697578 // On big-endian systems, LLVM reverses the element order of vectors by default
698579 const tgt_elem_i = if (endian == .big) elems.len - i - 1 else i;
699 elems[tgt_elem_i] = (try readFromPackedMemory(elem_ty, pt, buffer, bit_offset + bits, arena)).toIntern();
580 elems[tgt_elem_i] = (try readFromPackedMemory(elem_ty, pt, buffer, bit_offset + bits, gpa)).toIntern();
700581 bits += elem_bit_size;
701582 }
702583 return pt.aggregateValue(ty, elems);
703584 },
704 .@"struct" => {
705 // Sema is supposed to have emitted a compile error already for Auto layout structs,
706 // and Extern is handled by non-packed readFromMemory.
707 const struct_type = zcu.typeToPackedStruct(ty).?;
708 var bits: u16 = 0;
709 const field_vals = try arena.alloc(InternPool.Index, struct_type.field_types.len);
710 for (field_vals, 0..) |*field_val, i| {
711 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
712 const field_bits: u16 = @intCast(field_ty.bitSize(zcu));
713 field_val.* = (try readFromPackedMemory(field_ty, pt, buffer, bit_offset + bits, arena)).toIntern();
714 bits += field_bits;
715 }
716 return pt.aggregateValue(ty, field_vals);
717 },
718 .@"union" => switch (ty.containerLayout(zcu)) {
719 .auto, .@"extern" => unreachable, // Handled by non-packed readFromMemory
720 .@"packed" => {
721 const backing_ty = try ty.unionBackingType(pt);
722 const val = (try readFromPackedMemory(backing_ty, pt, buffer, bit_offset, arena)).toIntern();
723 return Value.fromInterned(try pt.internUnion(.{
724 .ty = ty.toIntern(),
725 .tag = .none,
726 .val = val,
727 }));
728 },
585 .@"struct", .@"union" => {
586 assert(ty.containerLayout(zcu) == .@"packed");
587 const int_val: Value = try .readFromPackedMemory(ty.bitpackBackingInt(zcu), pt, buffer, bit_offset, gpa);
588 return pt.bitpackValue(ty, int_val);
729589 },
730590 .pointer => {
731591 assert(!ty.isSlice(zcu)); // No well defined layout.
732 const int_val = try readFromPackedMemory(Type.usize, pt, buffer, bit_offset, arena);
733 return Value.fromInterned(try pt.intern(.{ .ptr = .{
734 .ty = ty.toIntern(),
735 .base_addr = .int,
736 .byte_offset = int_val.toUnsignedInt(zcu),
737 } }));
592 const addr = (try readFromPackedMemory(Type.usize, pt, buffer, bit_offset, gpa)).toUnsignedInt(zcu);
593 return pt.ptrIntValue(ty, addr);
738594 },
739595 .optional => {
740596 assert(ty.isPtrLikeOptional(zcu));
741 const child_ty = ty.optionalChild(zcu);
742 const child_val = try readFromPackedMemory(child_ty, pt, buffer, bit_offset, arena);
743 return Value.fromInterned(try pt.intern(.{ .opt = .{
597 const addr = (try readFromPackedMemory(Type.usize, pt, buffer, bit_offset, gpa)).toUnsignedInt(zcu);
598 return .fromInterned(try pt.intern(.{ .opt = .{
744599 .ty = ty.toIntern(),
745 .val = switch (child_val.orderAgainstZero(zcu)) {
746 .lt => unreachable,
747 .eq => .none,
748 .gt => child_val.toIntern(),
749 },
600 .val = if (addr == 0) .none else (try pt.ptrIntValue(ty.childType(zcu), addr)).toIntern(),
750601 } }));
751602 },
752603 else => @panic("TODO implement readFromPackedMemory for more types"),
......@@ -764,8 +615,6 @@ pub fn toFloat(val: Value, comptime T: type, zcu: *const Zcu) T {
764615 }
765616 return @floatFromInt(x);
766617 },
767 .lazy_align => |ty| @floatFromInt(Type.fromInterned(ty).abiAlignment(zcu).toByteUnits() orelse 0),
768 .lazy_size => |ty| @floatFromInt(Type.fromInterned(ty).abiSize(zcu)),
769618 },
770619 .float => |float| switch (float.storage) {
771620 inline else => |x| @floatCast(x),
......@@ -819,110 +668,8 @@ pub fn floatCast(val: Value, dest_ty: Type, pt: Zcu.PerThread) !Value {
819668 } }));
820669}
821670
822pub fn orderAgainstZero(lhs: Value, zcu: *Zcu) std.math.Order {
823 return orderAgainstZeroInner(lhs, .normal, zcu, {}) catch unreachable;
824}
825
826pub fn orderAgainstZeroSema(lhs: Value, pt: Zcu.PerThread) !std.math.Order {
827 return try orderAgainstZeroInner(lhs, .sema, pt.zcu, pt.tid);
828}
829
830pub fn orderAgainstZeroInner(
831 lhs: Value,
832 comptime strat: ResolveStrat,
833 zcu: *Zcu,
834 tid: strat.Tid(),
835) Zcu.SemaError!std.math.Order {
836 return switch (lhs.toIntern()) {
837 .bool_false => .eq,
838 .bool_true => .gt,
839 else => switch (zcu.intern_pool.indexToKey(lhs.toIntern())) {
840 .ptr => |ptr| if (ptr.byte_offset > 0) .gt else switch (ptr.base_addr) {
841 .nav, .comptime_alloc, .comptime_field => .gt,
842 .int => .eq,
843 else => unreachable,
844 },
845 .int => |int| switch (int.storage) {
846 .big_int => |big_int| big_int.orderAgainstScalar(0),
847 inline .u64, .i64 => |x| std.math.order(x, 0),
848 .lazy_align => .gt, // alignment is never 0
849 .lazy_size => |ty| return if (Type.fromInterned(ty).hasRuntimeBitsInner(
850 false,
851 strat.toLazy(),
852 zcu,
853 tid,
854 ) catch |err| switch (err) {
855 error.NeedLazy => unreachable,
856 else => |e| return e,
857 }) .gt else .eq,
858 },
859 .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).orderAgainstZeroInner(strat, zcu, tid),
860 .float => |float| switch (float.storage) {
861 inline else => |x| std.math.order(x, 0),
862 },
863 .err => .gt, // error values cannot be 0
864 else => unreachable,
865 },
866 };
867}
868
869/// Asserts the value is comparable.
870pub fn order(lhs: Value, rhs: Value, zcu: *Zcu) std.math.Order {
871 return orderAdvanced(lhs, rhs, .normal, zcu, {}) catch unreachable;
872}
873
874/// Asserts the value is comparable.
875pub fn orderAdvanced(
876 lhs: Value,
877 rhs: Value,
878 comptime strat: ResolveStrat,
879 zcu: *Zcu,
880 tid: strat.Tid(),
881) !std.math.Order {
882 const lhs_against_zero = try lhs.orderAgainstZeroInner(strat, zcu, tid);
883 const rhs_against_zero = try rhs.orderAgainstZeroInner(strat, zcu, tid);
884 switch (lhs_against_zero) {
885 .lt => if (rhs_against_zero != .lt) return .lt,
886 .eq => return rhs_against_zero.invert(),
887 .gt => {},
888 }
889 switch (rhs_against_zero) {
890 .lt => if (lhs_against_zero != .lt) return .gt,
891 .eq => return lhs_against_zero,
892 .gt => {},
893 }
894
895 if (lhs.isFloat(zcu) or rhs.isFloat(zcu)) {
896 const lhs_f128 = lhs.toFloat(f128, zcu);
897 const rhs_f128 = rhs.toFloat(f128, zcu);
898 return std.math.order(lhs_f128, rhs_f128);
899 }
900
901 var lhs_bigint_space: BigIntSpace = undefined;
902 var rhs_bigint_space: BigIntSpace = undefined;
903 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, strat, zcu, tid);
904 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, strat, zcu, tid);
905 return lhs_bigint.order(rhs_bigint);
906}
907
908/// Asserts the value is comparable. Does not take a type parameter because it supports
909/// comparisons between heterogeneous types.
910pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, zcu: *Zcu) bool {
911 return compareHeteroAdvanced(lhs, op, rhs, .normal, zcu, {}) catch unreachable;
912}
913
914pub fn compareHeteroSema(lhs: Value, op: std.math.CompareOperator, rhs: Value, pt: Zcu.PerThread) !bool {
915 return try compareHeteroAdvanced(lhs, op, rhs, .sema, pt.zcu, pt.tid);
916}
917
918pub fn compareHeteroAdvanced(
919 lhs: Value,
920 op: std.math.CompareOperator,
921 rhs: Value,
922 comptime strat: ResolveStrat,
923 zcu: *Zcu,
924 tid: strat.Tid(),
925) !bool {
671/// Asserts the value is comparable. Supports comparisons between heterogeneous types.
672pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, zcu: *const Zcu) bool {
926673 if (lhs.pointerNav(zcu)) |lhs_nav| {
927674 if (rhs.pointerNav(zcu)) |rhs_nav| {
928675 switch (op) {
......@@ -944,9 +691,21 @@ pub fn compareHeteroAdvanced(
944691 else => {},
945692 }
946693 }
947
948694 if (lhs.isNan(zcu) or rhs.isNan(zcu)) return op == .neq;
949 return (try orderAdvanced(lhs, rhs, strat, zcu, tid)).compare(op);
695 return order(lhs, rhs, zcu).compare(op);
696}
697
698pub fn order(lhs: Value, rhs: Value, zcu: *const Zcu) std.math.Order {
699 if (lhs.isFloat(zcu) or rhs.isFloat(zcu)) {
700 const lhs_f128 = lhs.toFloat(f128, zcu);
701 const rhs_f128 = rhs.toFloat(f128, zcu);
702 return std.math.order(lhs_f128, rhs_f128);
703 }
704 var lhs_bigint_space: BigIntSpace = undefined;
705 var rhs_bigint_space: BigIntSpace = undefined;
706 const lhs_bigint = lhs.toBigInt(&lhs_bigint_space, zcu);
707 const rhs_bigint = rhs.toBigInt(&rhs_bigint_space, zcu);
708 return lhs_bigint.order(rhs_bigint);
950709}
951710
952711/// Asserts the values are comparable. Both operands have type `ty`.
......@@ -988,55 +747,30 @@ pub fn compareScalar(
988747///
989748/// Note that `!compareAllWithZero(.eq, ...) != compareAllWithZero(.neq, ...)`
990749pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator, zcu: *Zcu) bool {
991 return compareAllWithZeroAdvancedExtra(lhs, op, .normal, zcu, {}) catch unreachable;
992}
993
994pub fn compareAllWithZeroSema(
995 lhs: Value,
996 op: std.math.CompareOperator,
997 pt: Zcu.PerThread,
998) Zcu.CompileError!bool {
999 return compareAllWithZeroAdvancedExtra(lhs, op, .sema, pt.zcu, pt.tid);
1000}
1001
1002pub fn compareAllWithZeroAdvancedExtra(
1003 lhs: Value,
1004 op: std.math.CompareOperator,
1005 comptime strat: ResolveStrat,
1006 zcu: *Zcu,
1007 tid: strat.Tid(),
1008) Zcu.CompileError!bool {
1009 if (lhs.isInf(zcu)) {
1010 switch (op) {
1011 .neq => return true,
1012 .eq => return false,
1013 .gt, .gte => return !lhs.isNegativeInf(zcu),
1014 .lt, .lte => return lhs.isNegativeInf(zcu),
1015 }
1016 }
1017
1018 switch (zcu.intern_pool.indexToKey(lhs.toIntern())) {
750 return switch (zcu.intern_pool.indexToKey(lhs.toIntern())) {
1019751 .float => |float| switch (float.storage) {
1020 inline else => |x| if (std.math.isNan(x)) return op == .neq,
752 inline else => |x| std.math.compare(x, op, 0),
1021753 },
1022 .aggregate => |aggregate| return switch (aggregate.storage) {
1023 .bytes => |bytes| for (bytes.toSlice(lhs.typeOf(zcu).arrayLenIncludingSentinel(zcu), &zcu.intern_pool)) |byte| {
1024 if (!std.math.order(byte, 0).compare(op)) break false;
754 .aggregate => |aggregate| switch (aggregate.storage) {
755 .bytes => |bytes| for (bytes.toSlice(
756 lhs.typeOf(zcu).arrayLenIncludingSentinel(zcu),
757 &zcu.intern_pool,
758 )) |byte| {
759 if (!std.math.compare(byte, op, 0)) break false;
1025760 } else true,
1026761 .elems => |elems| for (elems) |elem| {
1027 if (!try Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, strat, zcu, tid)) break false;
762 if (!Value.fromInterned(elem).compareAllWithZero(op, zcu)) break false;
1028763 } else true,
1029 .repeated_elem => |elem| Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, strat, zcu, tid),
764 .repeated_elem => |elem| Value.fromInterned(elem).compareAllWithZero(op, zcu),
1030765 },
1031 .undef => return false,
1032 else => {},
1033 }
1034 return (try orderAgainstZeroInner(lhs, strat, zcu, tid)).compare(op);
766 .undef => false,
767 else => order(lhs, .zero_comptime_int, zcu).compare(op),
768 };
1035769}
1036770
1037771pub fn eql(a: Value, b: Value, ty: Type, zcu: *Zcu) bool {
1038 assert(zcu.intern_pool.typeOf(a.toIntern()) == ty.toIntern());
1039 assert(zcu.intern_pool.typeOf(b.toIntern()) == ty.toIntern());
772 assert(a.typeOf(zcu).toIntern() == ty.toIntern());
773 assert(b.typeOf(zcu).toIntern() == ty.toIntern());
1040774 return a.toIntern() == b.toIntern();
1041775}
1042776
......@@ -1071,7 +805,7 @@ pub fn canMutateComptimeVarState(val: Value, zcu: *Zcu) bool {
1071805/// Gets the `Nav` referenced by this pointer. If the pointer does not point
1072806/// to a `Nav`, or if it points to some part of one (like a field or element),
1073807/// returns null.
1074pub fn pointerNav(val: Value, zcu: *Zcu) ?InternPool.Nav.Index {
808pub fn pointerNav(val: Value, zcu: *const Zcu) ?InternPool.Nav.Index {
1075809 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
1076810 // TODO: these 3 cases are weird; these aren't pointer values!
1077811 .variable => |v| v.owner_nav,
......@@ -1088,16 +822,13 @@ pub fn pointerNav(val: Value, zcu: *Zcu) ?InternPool.Nav.Index {
1088822pub const slice_ptr_index = 0;
1089823pub const slice_len_index = 1;
1090824
825pub fn sliceLen(val: Value, zcu: *Zcu) u64 {
826 return Value.fromInterned(zcu.intern_pool.sliceLen(val.toIntern())).toUnsignedInt(zcu);
827}
1091828pub fn slicePtr(val: Value, zcu: *Zcu) Value {
1092829 return Value.fromInterned(zcu.intern_pool.slicePtr(val.toIntern()));
1093830}
1094831
1095/// Gets the `len` field of a slice value as a `u64`.
1096/// Resolves the length using `Sema` if necessary.
1097pub fn sliceLen(val: Value, pt: Zcu.PerThread) !u64 {
1098 return Value.fromInterned(pt.zcu.intern_pool.sliceLen(val.toIntern())).toUnsignedIntSema(pt);
1099}
1100
1101832/// Asserts the value is an aggregate, and returns the element value at the given index.
1102833pub fn elemValue(val: Value, pt: Zcu.PerThread, index: usize) Allocator.Error!Value {
1103834 const zcu = pt.zcu;
......@@ -1123,62 +854,6 @@ pub fn elemValue(val: Value, pt: Zcu.PerThread, index: usize) Allocator.Error!Va
1123854 }
1124855}
1125856
1126pub fn isLazyAlign(val: Value, zcu: *Zcu) bool {
1127 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
1128 .int => |int| int.storage == .lazy_align,
1129 else => false,
1130 };
1131}
1132
1133pub fn isLazySize(val: Value, zcu: *Zcu) bool {
1134 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
1135 .int => |int| int.storage == .lazy_size,
1136 else => false,
1137 };
1138}
1139
1140// Asserts that the provided start/end are in-bounds.
1141pub fn sliceArray(
1142 val: Value,
1143 sema: *Sema,
1144 start: usize,
1145 end: usize,
1146) error{OutOfMemory}!Value {
1147 const pt = sema.pt;
1148 const ip = &pt.zcu.intern_pool;
1149 const io = pt.zcu.comp.io;
1150 return Value.fromInterned(try pt.intern(.{
1151 .aggregate = .{
1152 .ty = switch (pt.zcu.intern_pool.indexToKey(pt.zcu.intern_pool.typeOf(val.toIntern()))) {
1153 .array_type => |array_type| try pt.arrayType(.{
1154 .len = @intCast(end - start),
1155 .child = array_type.child,
1156 .sentinel = if (end == array_type.len) array_type.sentinel else .none,
1157 }),
1158 .vector_type => |vector_type| try pt.vectorType(.{
1159 .len = @intCast(end - start),
1160 .child = vector_type.child,
1161 }),
1162 else => unreachable,
1163 }.toIntern(),
1164 .storage = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
1165 .bytes => |bytes| storage: {
1166 try ip.string_bytes.ensureUnusedCapacity(sema.gpa, end - start + 1);
1167 break :storage .{ .bytes = try ip.getOrPutString(
1168 sema.gpa,
1169 io,
1170 bytes.toSlice(end, ip)[start..],
1171 .maybe_embedded_nulls,
1172 ) };
1173 },
1174 // TODO: write something like getCoercedInts to avoid needing to dupe
1175 .elems => |elems| .{ .elems = try sema.arena.dupe(InternPool.Index, elems[start..end]) },
1176 .repeated_elem => |elem| .{ .repeated_elem = elem },
1177 },
1178 },
1179 }));
1180}
1181
1182857pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value {
1183858 const zcu = pt.zcu;
1184859 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
......@@ -1193,8 +868,44 @@ pub fn fieldValue(val: Value, pt: Zcu.PerThread, index: usize) !Value {
1193868 .elems => |elems| elems[index],
1194869 .repeated_elem => |elem| elem,
1195870 }),
1196 // TODO assert the tag is correct
1197 .un => |un| Value.fromInterned(un.val),
871 .un => |un| {
872 switch (Type.fromInterned(un.ty).containerLayout(zcu)) {
873 .auto, .@"extern" => {}, // TODO assert the tag is correct
874 .@"packed" => unreachable,
875 }
876 return .fromInterned(un.val);
877 },
878 .bitpack => |bitpack| {
879 const ty: Type = .fromInterned(bitpack.ty);
880 assert(ty.containerLayout(zcu) == .@"packed");
881 const int_val: Value = .fromInterned(bitpack.backing_int_val);
882 assert(!int_val.isUndef(zcu));
883 const field_ty = ty.fieldType(index, zcu);
884 const field_bit_offset: u16 = switch (ty.zigTypeTag(zcu)) {
885 .@"union" => 0,
886 .@"struct" => off: {
887 var off: u16 = 0;
888 for (0..index) |preceding_field_index| {
889 off += @intCast(ty.fieldType(preceding_field_index, zcu).bitSize(zcu));
890 }
891 break :off off;
892 },
893 else => unreachable,
894 };
895 // Avoid hitting gpa for accesses to small packed structs
896 var sfba_state = std.heap.stackFallback(128, zcu.comp.gpa);
897 const sfba = sfba_state.get();
898 const buf = try sfba.alloc(u8, @intCast((ty.bitSize(zcu) + 7) / 8));
899 defer sfba.free(buf);
900 int_val.writeToPackedMemory(pt, buf, 0) catch |err| switch (err) {
901 error.ReinterpretDeclRef => unreachable, // it's an integer
902 error.OutOfMemory => |e| return e,
903 };
904 return Value.readFromPackedMemory(field_ty, pt, buf, field_bit_offset, sfba) catch |err| switch (err) {
905 error.IllDefinedMemoryLayout => unreachable, // it's a bitpack
906 error.OutOfMemory => |e| return e,
907 };
908 },
1198909 else => unreachable,
1199910 };
1200911}
......@@ -1207,7 +918,7 @@ pub fn unionTag(val: Value, zcu: *Zcu) ?Value {
1207918 };
1208919}
1209920
1210pub fn unionValue(val: Value, zcu: *Zcu) Value {
921pub fn unionPayload(val: Value, zcu: *Zcu) Value {
1211922 return switch (zcu.intern_pool.indexToKey(val.toIntern())) {
1212923 .un => |un| Value.fromInterned(un.val),
1213924 else => unreachable,
......@@ -1334,63 +1045,6 @@ pub fn isFloat(self: Value, zcu: *const Zcu) bool {
13341045 };
13351046}
13361047
1337pub fn floatFromInt(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, zcu: *Zcu) !Value {
1338 return floatFromIntAdvanced(val, arena, int_ty, float_ty, zcu, .normal) catch |err| switch (err) {
1339 error.OutOfMemory => return error.OutOfMemory,
1340 else => unreachable,
1341 };
1342}
1343
1344pub fn floatFromIntAdvanced(
1345 val: Value,
1346 arena: Allocator,
1347 int_ty: Type,
1348 float_ty: Type,
1349 pt: Zcu.PerThread,
1350 comptime strat: ResolveStrat,
1351) !Value {
1352 const zcu = pt.zcu;
1353 if (int_ty.zigTypeTag(zcu) == .vector) {
1354 const result_data = try arena.alloc(InternPool.Index, int_ty.vectorLen(zcu));
1355 const scalar_ty = float_ty.scalarType(zcu);
1356 for (result_data, 0..) |*scalar, i| {
1357 const elem_val = try val.elemValue(pt, i);
1358 scalar.* = (try floatFromIntScalar(elem_val, scalar_ty, pt, strat)).toIntern();
1359 }
1360 return pt.aggregateValue(float_ty, result_data);
1361 }
1362 return floatFromIntScalar(val, float_ty, pt, strat);
1363}
1364
1365pub fn floatFromIntScalar(val: Value, float_ty: Type, pt: Zcu.PerThread, comptime strat: ResolveStrat) !Value {
1366 return switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) {
1367 .undef => try pt.undefValue(float_ty),
1368 .int => |int| switch (int.storage) {
1369 .big_int => |big_int| pt.floatValue(float_ty, big_int.toFloat(f128, .nearest_even)[0]),
1370 inline .u64, .i64 => |x| floatFromIntInner(x, float_ty, pt),
1371 .lazy_align => |ty| floatFromIntInner((try Type.fromInterned(ty).abiAlignmentInner(strat.toLazy(), pt.zcu, pt.tid)).scalar.toByteUnits() orelse 0, float_ty, pt),
1372 .lazy_size => |ty| floatFromIntInner((try Type.fromInterned(ty).abiSizeInner(strat.toLazy(), pt.zcu, pt.tid)).scalar, float_ty, pt),
1373 },
1374 else => unreachable,
1375 };
1376}
1377
1378fn floatFromIntInner(x: anytype, dest_ty: Type, pt: Zcu.PerThread) !Value {
1379 const target = pt.zcu.getTarget();
1380 const storage: InternPool.Key.Float.Storage = switch (dest_ty.floatBits(target)) {
1381 16 => .{ .f16 = @floatFromInt(x) },
1382 32 => .{ .f32 = @floatFromInt(x) },
1383 64 => .{ .f64 = @floatFromInt(x) },
1384 80 => .{ .f80 = @floatFromInt(x) },
1385 128 => .{ .f128 = @floatFromInt(x) },
1386 else => unreachable,
1387 };
1388 return Value.fromInterned(try pt.intern(.{ .float = .{
1389 .ty = dest_ty.toIntern(),
1390 .storage = storage,
1391 } }));
1392}
1393
13941048fn calcLimbLenFloat(scalar: anytype) usize {
13951049 if (scalar == 0) {
13961050 return 1;
......@@ -1410,11 +1064,11 @@ pub fn numberMax(lhs: Value, rhs: Value, zcu: *Zcu) Value {
14101064 if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return undef;
14111065 if (lhs.isNan(zcu)) return rhs;
14121066 if (rhs.isNan(zcu)) return lhs;
1413
1414 return switch (order(lhs, rhs, zcu)) {
1415 .lt => rhs,
1416 .gt, .eq => lhs,
1417 };
1067 if (compareHetero(lhs, .gt, rhs, zcu)) {
1068 return lhs;
1069 } else {
1070 return rhs;
1071 }
14181072}
14191073
14201074/// Supports both floats and ints; handles undefined.
......@@ -1422,11 +1076,11 @@ pub fn numberMin(lhs: Value, rhs: Value, zcu: *Zcu) Value {
14221076 if (lhs.isUndef(zcu) or rhs.isUndef(zcu)) return undef;
14231077 if (lhs.isNan(zcu)) return rhs;
14241078 if (rhs.isNan(zcu)) return lhs;
1425
1426 return switch (order(lhs, rhs, zcu)) {
1427 .lt => lhs,
1428 .gt, .eq => rhs,
1429 };
1079 if (compareHetero(lhs, .lt, rhs, zcu)) {
1080 return lhs;
1081 } else {
1082 return rhs;
1083 }
14301084}
14311085
14321086/// Returns true if the value is a floating point type and is NaN. Returns false otherwise.
......@@ -2033,8 +1687,6 @@ pub fn makeBool(x: bool) Value {
20331687/// `parent_ptr` must be a single-pointer or C pointer to some optional.
20341688///
20351689/// Returns a pointer to the payload of the optional.
2036///
2037/// May perform type resolution.
20381690pub fn ptrOptPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
20391691 const zcu = pt.zcu;
20401692 const parent_ptr_ty = parent_ptr.typeOf(zcu);
......@@ -2044,7 +1696,7 @@ pub fn ptrOptPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
20441696 assert(ptr_size == .one or ptr_size == .c);
20451697 assert(opt_ty.zigTypeTag(zcu) == .optional);
20461698
2047 const result_ty = try pt.ptrTypeSema(info: {
1699 const result_ty = try pt.ptrType(info: {
20481700 var new = parent_ptr_ty.ptrInfo(zcu);
20491701 // We can correctly preserve alignment `.none`, since an optional has the same
20501702 // natural alignment as its child type.
......@@ -2060,7 +1712,7 @@ pub fn ptrOptPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
20601712 }
20611713
20621714 const base_ptr = try parent_ptr.canonicalizeBasePtr(.one, opt_ty, pt);
2063 return Value.fromInterned(try pt.intern(.{ .ptr = .{
1715 return .fromInterned(try pt.intern(.{ .ptr = .{
20641716 .ty = result_ty.toIntern(),
20651717 .base_addr = .{ .opt_payload = base_ptr.toIntern() },
20661718 .byte_offset = 0,
......@@ -2069,7 +1721,6 @@ pub fn ptrOptPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
20691721
20701722/// `parent_ptr` must be a single-pointer to some error union.
20711723/// Returns a pointer to the payload of the error union.
2072/// May perform type resolution.
20731724pub fn ptrEuPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
20741725 const zcu = pt.zcu;
20751726 const parent_ptr_ty = parent_ptr.typeOf(zcu);
......@@ -2078,7 +1729,7 @@ pub fn ptrEuPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
20781729 assert(parent_ptr_ty.ptrSize(zcu) == .one);
20791730 assert(eu_ty.zigTypeTag(zcu) == .error_union);
20801731
2081 const result_ty = try pt.ptrTypeSema(info: {
1732 const result_ty = try pt.ptrType(info: {
20821733 var new = parent_ptr_ty.ptrInfo(zcu);
20831734 // We can correctly preserve alignment `.none`, since an error union has a
20841735 // natural alignment greater than or equal to that of its payload type.
......@@ -2089,147 +1740,57 @@ pub fn ptrEuPayload(parent_ptr: Value, pt: Zcu.PerThread) !Value {
20891740 if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty);
20901741
20911742 const base_ptr = try parent_ptr.canonicalizeBasePtr(.one, eu_ty, pt);
2092 return Value.fromInterned(try pt.intern(.{ .ptr = .{
1743 return .fromInterned(try pt.intern(.{ .ptr = .{
20931744 .ty = result_ty.toIntern(),
20941745 .base_addr = .{ .eu_payload = base_ptr.toIntern() },
20951746 .byte_offset = 0,
20961747 } }));
20971748}
20981749
2099/// `parent_ptr` must be a single-pointer or c pointer to a struct, union, or slice.
1750/// `parent_ptr` must be a single-item pointer or C pointer to a struct, union, or slice.
21001751///
21011752/// Returns a pointer to the aggregate field at the specified index.
21021753///
21031754/// For slices, uses `slice_ptr_index` and `slice_len_index`.
21041755///
2105/// May perform type resolution.
1756/// Asserts that the layout of the aggregate type is resolved.
21061757pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value {
21071758 const zcu = pt.zcu;
21081759 const parent_ptr_ty = parent_ptr.typeOf(zcu);
21091760 const aggregate_ty = parent_ptr_ty.childType(zcu);
1761 aggregate_ty.assertHasLayout(zcu);
21101762
21111763 const parent_ptr_info = parent_ptr_ty.ptrInfo(zcu);
21121764 assert(parent_ptr_info.flags.size == .one or parent_ptr_info.flags.size == .c);
21131765
2114 // Exiting this `switch` indicates that the `field` pointer representation should be used.
2115 // `field_align` may be `.none` to represent the natural alignment of `field_ty`, but is not necessarily.
2116 const field_ty: Type, const field_align: InternPool.Alignment = switch (aggregate_ty.zigTypeTag(zcu)) {
2117 .@"struct" => field: {
2118 const field_ty = aggregate_ty.fieldType(field_idx, zcu);
2119 switch (aggregate_ty.containerLayout(zcu)) {
2120 .auto => break :field .{ field_ty, try aggregate_ty.fieldAlignmentSema(field_idx, pt) },
2121 .@"extern" => {
2122 // Well-defined layout, so just offset the pointer appropriately.
2123 try aggregate_ty.resolveLayout(pt);
2124 const byte_off = aggregate_ty.structFieldOffset(field_idx, zcu);
2125 const field_align = a: {
2126 const parent_align = if (parent_ptr_info.flags.alignment == .none) pa: {
2127 break :pa try aggregate_ty.abiAlignmentSema(pt);
2128 } else parent_ptr_info.flags.alignment;
2129 break :a InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(byte_off)));
2130 };
2131 const result_ty = try pt.ptrTypeSema(info: {
2132 var new = parent_ptr_info;
2133 new.child = field_ty.toIntern();
2134 new.flags.alignment = field_align;
2135 break :info new;
2136 });
2137 return parent_ptr.getOffsetPtr(byte_off, result_ty, pt);
2138 },
2139 .@"packed" => {
2140 const packed_offset = aggregate_ty.packedStructFieldPtrInfo(parent_ptr_ty, field_idx, pt);
2141 const result_ty = try pt.ptrType(info: {
2142 var new = parent_ptr_info;
2143 new.packed_offset = packed_offset;
2144 new.child = field_ty.toIntern();
2145 if (new.flags.alignment == .none) {
2146 new.flags.alignment = try aggregate_ty.abiAlignmentSema(pt);
2147 }
2148 break :info new;
2149 });
2150 return pt.getCoerced(parent_ptr, result_ty);
2151 },
2152 }
2153 },
2154 .@"union" => field: {
2155 const union_obj = zcu.typeToUnion(aggregate_ty).?;
2156 const field_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[field_idx]);
2157 switch (aggregate_ty.containerLayout(zcu)) {
2158 .auto => break :field .{ field_ty, try aggregate_ty.fieldAlignmentSema(field_idx, pt) },
2159 .@"extern" => {
2160 // Point to the same address.
2161 const result_ty = try pt.ptrTypeSema(info: {
2162 var new = parent_ptr_info;
2163 new.child = field_ty.toIntern();
2164 break :info new;
2165 });
2166 return pt.getCoerced(parent_ptr, result_ty);
2167 },
2168 .@"packed" => {
2169 // If the field has an ABI size matching its bit size, then we can continue to use a
2170 // non-bit pointer if the parent pointer is also a non-bit pointer.
2171 if (parent_ptr_info.packed_offset.host_size == 0 and (try field_ty.abiSizeInner(.sema, zcu, pt.tid)).scalar * 8 == try field_ty.bitSizeSema(pt)) {
2172 // We must offset the pointer on big-endian targets, since the bits of packed memory don't align nicely.
2173 const byte_offset = switch (zcu.getTarget().cpu.arch.endian()) {
2174 .little => 0,
2175 .big => (try aggregate_ty.abiSizeInner(.sema, zcu, pt.tid)).scalar - (try field_ty.abiSizeInner(.sema, zcu, pt.tid)).scalar,
2176 };
2177 const result_ty = try pt.ptrTypeSema(info: {
2178 var new = parent_ptr_info;
2179 new.child = field_ty.toIntern();
2180 new.flags.alignment = InternPool.Alignment.fromLog2Units(
2181 @ctz(byte_offset | (try parent_ptr_ty.ptrAlignmentSema(pt)).toByteUnits().?),
2182 );
2183 break :info new;
2184 });
2185 return parent_ptr.getOffsetPtr(byte_offset, result_ty, pt);
2186 } else {
2187 // The result must be a bit-pointer if it is not already.
2188 const result_ty = try pt.ptrTypeSema(info: {
2189 var new = parent_ptr_info;
2190 new.child = field_ty.toIntern();
2191 if (new.packed_offset.host_size == 0) {
2192 new.packed_offset.host_size = @intCast(((try aggregate_ty.bitSizeSema(pt)) + 7) / 8);
2193 assert(new.packed_offset.bit_offset == 0);
2194 }
2195 break :info new;
2196 });
2197 return pt.getCoerced(parent_ptr, result_ty);
2198 }
2199 },
2200 }
1766 const field_ptr_ty = try parent_ptr_ty.fieldPtrType(field_idx, pt);
1767
1768 switch (aggregate_ty.zigTypeTag(zcu)) {
1769 .pointer => assert(aggregate_ty.isSlice(zcu)),
1770 .@"struct" => switch (aggregate_ty.containerLayout(zcu)) {
1771 .auto => {},
1772 .@"extern" => return parent_ptr.getOffsetPtr(
1773 aggregate_ty.structFieldOffset(field_idx, zcu),
1774 field_ptr_ty,
1775 pt,
1776 ),
1777 .@"packed" => return pt.getCoerced(parent_ptr, field_ptr_ty),
22011778 },
2202 .pointer => field_ty: {
2203 assert(aggregate_ty.isSlice(zcu));
2204 break :field_ty switch (field_idx) {
2205 Value.slice_ptr_index => .{ aggregate_ty.slicePtrFieldType(zcu), Type.usize.abiAlignment(zcu) },
2206 Value.slice_len_index => .{ Type.usize, Type.usize.abiAlignment(zcu) },
2207 else => unreachable,
2208 };
1779 .@"union" => switch (aggregate_ty.containerLayout(zcu)) {
1780 .auto => {},
1781 .@"packed", .@"extern" => return pt.getCoerced(parent_ptr, field_ptr_ty),
22091782 },
22101783 else => unreachable,
2211 };
1784 }
22121785
2213 const new_align: InternPool.Alignment = if (parent_ptr_info.flags.alignment != .none) a: {
2214 const ty_align = (try field_ty.abiAlignmentInner(.sema, zcu, pt.tid)).scalar;
2215 const true_field_align = if (field_align == .none) ty_align else field_align;
2216 const new_align = true_field_align.min(parent_ptr_info.flags.alignment);
2217 if (new_align == ty_align) break :a .none;
2218 break :a new_align;
2219 } else field_align;
2220
2221 const result_ty = try pt.ptrTypeSema(info: {
2222 var new = parent_ptr_info;
2223 new.child = field_ty.toIntern();
2224 new.flags.alignment = new_align;
2225 break :info new;
2226 });
1786 // If we get here, we need to use the `.field` comptime pointer representation, because the
1787 // aggregate does not have a well-defined layout.
22271788
2228 if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty);
1789 if (parent_ptr.isUndef(zcu)) return pt.undefValue(field_ptr_ty);
22291790
22301791 const base_ptr = try parent_ptr.canonicalizeBasePtr(.one, aggregate_ty, pt);
2231 return Value.fromInterned(try pt.intern(.{ .ptr = .{
2232 .ty = result_ty.toIntern(),
1792 return .fromInterned(try pt.intern(.{ .ptr = .{
1793 .ty = field_ptr_ty.toIntern(),
22331794 .base_addr = .{ .field = .{
22341795 .base = base_ptr.toIntern(),
22351796 .index = field_idx,
......@@ -2238,9 +1799,9 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value {
22381799 } }));
22391800}
22401801
2241/// `orig_parent_ptr` must be either a single-pointer to an array or vector, or a many-pointer or C-pointer or slice.
1802/// `orig_parent_ptr` must be either a single-pointer to an array, a slice, a many-item pointer, or a C pointer.
22421803/// Returns a pointer to the element at the specified index.
2243/// May perform type resolution.
1804/// Asserts that the layout of the pointer element type is resolved.
22441805pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, pt: Zcu.PerThread) !Value {
22451806 const zcu = pt.zcu;
22461807 const parent_ptr = switch (orig_parent_ptr.typeOf(zcu).ptrSize(zcu)) {
......@@ -2249,79 +1810,50 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, pt: Zcu.PerThread) !Value
22491810 };
22501811
22511812 const parent_ptr_ty = parent_ptr.typeOf(zcu);
2252 const elem_ty = parent_ptr_ty.childType(zcu);
2253 const result_ty = try parent_ptr_ty.elemPtrType(@intCast(field_idx), pt);
1813 const result_ty = try parent_ptr_ty.elemPtrType(field_idx, pt);
1814 const elem_ty = result_ty.childType(zcu);
1815 elem_ty.assertHasLayout(zcu);
22541816
22551817 if (parent_ptr.isUndef(zcu)) return pt.undefValue(result_ty);
22561818
2257 if (result_ty.ptrInfo(zcu).packed_offset.host_size != 0) {
2258 // Since we have a bit-pointer, the pointer address should be unchanged.
2259 assert(elem_ty.zigTypeTag(zcu) == .vector);
2260 return pt.getCoerced(parent_ptr, result_ty);
1819 if (!elem_ty.comptimeOnly(zcu)) {
1820 const byte_offset = field_idx * elem_ty.abiSize(zcu);
1821 return parent_ptr.getOffsetPtr(byte_offset, result_ty, pt);
22611822 }
22621823
2263 const PtrStrat = union(enum) {
2264 offset: u64,
2265 elem_ptr: Type, // many-ptr elem ty
2266 };
2267
2268 const strat: PtrStrat = switch (parent_ptr_ty.ptrSize(zcu)) {
2269 .one => switch (elem_ty.zigTypeTag(zcu)) {
2270 .vector => .{ .offset = field_idx * @divExact(try elem_ty.childType(zcu).bitSizeSema(pt), 8) },
2271 .array => strat: {
2272 const arr_elem_ty = elem_ty.childType(zcu);
2273 if (try arr_elem_ty.comptimeOnlySema(pt)) {
2274 break :strat .{ .elem_ptr = arr_elem_ty };
2275 }
2276 break :strat .{ .offset = field_idx * (try arr_elem_ty.abiSizeInner(.sema, zcu, pt.tid)).scalar };
2277 },
2278 else => unreachable,
2279 },
1824 // Comptime-only element type.
22801825
2281 .many, .c => if (try elem_ty.comptimeOnlySema(pt))
2282 .{ .elem_ptr = elem_ty }
2283 else
2284 .{ .offset = field_idx * (try elem_ty.abiSizeInner(.sema, zcu, pt.tid)).scalar },
2285
2286 .slice => unreachable,
2287 };
1826 if (field_idx == 0) {
1827 return pt.getCoerced(parent_ptr, result_ty);
1828 }
22881829
2289 switch (strat) {
2290 .offset => |byte_offset| {
2291 return parent_ptr.getOffsetPtr(byte_offset, result_ty, pt);
2292 },
2293 .elem_ptr => |manyptr_elem_ty| if (field_idx == 0) {
2294 return pt.getCoerced(parent_ptr, result_ty);
2295 } else {
2296 const arr_base_ty, const arr_base_len = manyptr_elem_ty.arrayBase(zcu);
2297 const base_idx = arr_base_len * field_idx;
2298 const parent_info = zcu.intern_pool.indexToKey(parent_ptr.toIntern()).ptr;
2299 switch (parent_info.base_addr) {
2300 .arr_elem => |arr_elem| {
2301 if (Value.fromInterned(arr_elem.base).typeOf(zcu).childType(zcu).toIntern() == arr_base_ty.toIntern()) {
2302 // We already have a pointer to an element of an array of this type.
2303 // Just modify the index.
2304 return Value.fromInterned(try pt.intern(.{ .ptr = ptr: {
2305 var new = parent_info;
2306 new.base_addr.arr_elem.index += base_idx;
2307 new.ty = result_ty.toIntern();
2308 break :ptr new;
2309 } }));
2310 }
2311 },
2312 else => {},
1830 const arr_base_ty, const arr_base_len = elem_ty.arrayBase(zcu);
1831 const base_idx = arr_base_len * field_idx;
1832 const parent_info = zcu.intern_pool.indexToKey(parent_ptr.toIntern()).ptr;
1833 switch (parent_info.base_addr) {
1834 .arr_elem => |arr_elem| {
1835 if (Value.fromInterned(arr_elem.base).typeOf(zcu).childType(zcu).toIntern() == arr_base_ty.toIntern()) {
1836 // We already have a pointer to an element of an array of this type.
1837 // Just modify the index.
1838 return .fromInterned(try pt.intern(.{ .ptr = ptr: {
1839 var new = parent_info;
1840 new.base_addr.arr_elem.index += base_idx;
1841 new.ty = result_ty.toIntern();
1842 break :ptr new;
1843 } }));
23131844 }
2314 const base_ptr = try parent_ptr.canonicalizeBasePtr(.many, arr_base_ty, pt);
2315 return Value.fromInterned(try pt.intern(.{ .ptr = .{
2316 .ty = result_ty.toIntern(),
2317 .base_addr = .{ .arr_elem = .{
2318 .base = base_ptr.toIntern(),
2319 .index = base_idx,
2320 } },
2321 .byte_offset = 0,
2322 } }));
23231845 },
1846 else => {},
23241847 }
1848 const base_ptr = try parent_ptr.canonicalizeBasePtr(.many, arr_base_ty, pt);
1849 return .fromInterned(try pt.intern(.{ .ptr = .{
1850 .ty = result_ty.toIntern(),
1851 .base_addr = .{ .arr_elem = .{
1852 .base = base_ptr.toIntern(),
1853 .index = base_idx,
1854 } },
1855 .byte_offset = 0,
1856 } }));
23251857}
23261858
23271859fn canonicalizeBasePtr(base_ptr: Value, want_size: std.builtin.Type.Pointer.Size, want_child: Type, pt: Zcu.PerThread) !Value {
......@@ -2417,19 +1949,11 @@ pub const PointerDeriveStep = union(enum) {
24171949 }
24181950};
24191951
2420pub fn pointerDerivation(ptr_val: Value, arena: Allocator, pt: Zcu.PerThread) Allocator.Error!PointerDeriveStep {
2421 return ptr_val.pointerDerivationAdvanced(arena, pt, false, null) catch |err| switch (err) {
2422 error.OutOfMemory => |e| return e,
2423 error.Canceled => @panic("TODO"), // pls remove from error set mlugg
2424 error.AnalysisFail => unreachable,
2425 };
2426}
2427
24281952/// Given a pointer value, get the sequence of steps to derive it, ideally by taking
24291953/// only field and element pointers with no casts. This can be used by codegen backends
24301954/// which prefer field/elem accesses when lowering constant pointer values.
24311955/// It is also used by the Value printing logic for pointers.
2432pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerThread, comptime resolve_types: bool, opt_sema: ?*Sema) !PointerDeriveStep {
1956pub fn pointerDerivation(ptr_val: Value, arena: Allocator, pt: Zcu.PerThread, opt_sema: ?*Sema) Allocator.Error!PointerDeriveStep {
24331957 const zcu = pt.zcu;
24341958 const ptr = zcu.intern_pool.indexToKey(ptr_val.toIntern()).ptr;
24351959 const base_derive: PointerDeriveStep = switch (ptr.base_addr) {
......@@ -2454,7 +1978,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
24541978 .comptime_alloc => |idx| base: {
24551979 const sema = opt_sema.?;
24561980 const alloc = sema.getComptimeAlloc(idx);
2457 const val = try alloc.val.intern(pt, sema.arena);
1981 const val = try alloc.val.intern(pt, arena);
24581982 const ty = val.typeOf(zcu);
24591983 break :base .{ .comptime_alloc_ptr = .{
24601984 .idx = idx,
......@@ -2472,7 +1996,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
24721996 const base_ptr = Value.fromInterned(eu_ptr);
24731997 const base_ptr_ty = base_ptr.typeOf(zcu);
24741998 const parent_step = try arena.create(PointerDeriveStep);
2475 parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(eu_ptr), arena, pt, resolve_types, opt_sema);
1999 parent_step.* = try pointerDerivation(.fromInterned(eu_ptr), arena, pt, opt_sema);
24762000 break :base .{ .eu_payload_ptr = .{
24772001 .parent = parent_step,
24782002 .result_ptr_ty = try pt.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).errorUnionPayload(zcu)),
......@@ -2482,7 +2006,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
24822006 const base_ptr = Value.fromInterned(opt_ptr);
24832007 const base_ptr_ty = base_ptr.typeOf(zcu);
24842008 const parent_step = try arena.create(PointerDeriveStep);
2485 parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(opt_ptr), arena, pt, resolve_types, opt_sema);
2009 parent_step.* = try pointerDerivation(.fromInterned(opt_ptr), arena, pt, opt_sema);
24862010 break :base .{ .opt_payload_ptr = .{
24872011 .parent = parent_step,
24882012 .result_ptr_ty = try pt.adjustPtrTypeChild(base_ptr_ty, base_ptr_ty.childType(zcu).optionalChild(zcu)),
......@@ -2490,59 +2014,32 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
24902014 },
24912015 .field => |field| base: {
24922016 const base_ptr = Value.fromInterned(field.base);
2493 const base_ptr_ty = base_ptr.typeOf(zcu);
2494 const agg_ty = base_ptr_ty.childType(zcu);
2495 const field_ty, const field_align = switch (agg_ty.zigTypeTag(zcu)) {
2496 .@"struct" => .{ agg_ty.fieldType(@intCast(field.index), zcu), try agg_ty.fieldAlignmentInner(
2497 @intCast(field.index),
2498 if (resolve_types) .sema else .normal,
2499 pt.zcu,
2500 if (resolve_types) pt.tid else {},
2501 ) },
2502 .@"union" => .{ agg_ty.unionFieldTypeByIndex(@intCast(field.index), zcu), try agg_ty.fieldAlignmentInner(
2503 @intCast(field.index),
2504 if (resolve_types) .sema else .normal,
2505 pt.zcu,
2506 if (resolve_types) pt.tid else {},
2507 ) },
2508 .pointer => .{ switch (field.index) {
2509 Value.slice_ptr_index => agg_ty.slicePtrFieldType(zcu),
2510 Value.slice_len_index => Type.usize,
2511 else => unreachable,
2512 }, Type.usize.abiAlignment(zcu) },
2513 else => unreachable,
2514 };
2515 const base_align = base_ptr_ty.ptrAlignment(zcu);
2516 const result_align = field_align.minStrict(base_align);
2517 const result_ty = try pt.ptrType(.{
2518 .child = field_ty.toIntern(),
2519 .flags = flags: {
2520 var flags = base_ptr_ty.ptrInfo(zcu).flags;
2521 if (result_align == field_ty.abiAlignment(zcu)) {
2522 flags.alignment = .none;
2523 } else {
2524 flags.alignment = result_align;
2525 }
2526 break :flags flags;
2527 },
2017 const base_ptr_ty = try pt.ptrType(info: {
2018 var info = base_ptr.typeOf(zcu).ptrInfo(zcu);
2019 info.flags.size = .one;
2020 break :info info;
25282021 });
25292022 const parent_step = try arena.create(PointerDeriveStep);
2530 parent_step.* = try pointerDerivationAdvanced(base_ptr, arena, pt, resolve_types, opt_sema);
2023 parent_step.* = try pointerDerivation(base_ptr, arena, pt, opt_sema);
25312024 break :base .{ .field_ptr = .{
25322025 .parent = parent_step,
25332026 .field_idx = @intCast(field.index),
2534 .result_ptr_ty = result_ty,
2027 .result_ptr_ty = try base_ptr_ty.fieldPtrType(@intCast(field.index), pt),
25352028 } };
25362029 },
25372030 .arr_elem => |arr_elem| base: {
25382031 const parent_step = try arena.create(PointerDeriveStep);
2539 parent_step.* = try pointerDerivationAdvanced(Value.fromInterned(arr_elem.base), arena, pt, resolve_types, opt_sema);
2032 parent_step.* = try pointerDerivation(.fromInterned(arr_elem.base), arena, pt, opt_sema);
25402033 const parent_ptr_info = (try parent_step.ptrType(pt)).ptrInfo(zcu);
25412034 const result_ptr_ty = try pt.ptrType(.{
25422035 .child = parent_ptr_info.child,
25432036 .flags = flags: {
25442037 var flags = parent_ptr_info.flags;
25452038 flags.size = .one;
2039 if (flags.alignment != .none) flags.alignment = .minStrict(
2040 flags.alignment,
2041 Type.fromInterned(parent_ptr_info.child).abiAlignment(zcu),
2042 );
25462043 break :flags flags;
25472044 },
25482045 });
......@@ -2560,7 +2057,7 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
25602057
25612058 const ptr_ty_info = Type.fromInterned(ptr.ty).ptrInfo(zcu);
25622059 const need_child: Type = .fromInterned(ptr_ty_info.child);
2563 if (need_child.comptimeOnly(zcu)) {
2060 if (need_child.comptimeOnly(zcu) or need_child.zigTypeTag(zcu) == .@"opaque") {
25642061 // No refinement can happen - this pointer is presumably invalid.
25652062 // Just offset it.
25662063 const parent = try arena.create(PointerDeriveStep);
......@@ -2662,27 +2159,17 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
26622159 const start_off = cur_ty.structFieldOffset(field_idx, zcu);
26632160 const end_off = start_off + field_ty.abiSize(zcu);
26642161 if (cur_offset >= start_off and cur_offset + need_bytes <= end_off) {
2665 const old_ptr_ty = try cur_derive.ptrType(pt);
2666 const parent_align = old_ptr_ty.ptrAlignment(zcu);
2667 const field_align = InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(start_off)));
2162 const base_ptr_ty = try pt.ptrType(info: {
2163 var info = (try cur_derive.ptrType(pt)).ptrInfo(zcu);
2164 info.flags.size = .one;
2165 break :info info;
2166 });
26682167 const parent = try arena.create(PointerDeriveStep);
26692168 parent.* = cur_derive;
2670 const new_ptr_ty = try pt.ptrType(.{
2671 .child = field_ty.toIntern(),
2672 .flags = flags: {
2673 var flags = old_ptr_ty.ptrInfo(zcu).flags;
2674 if (field_align == field_ty.abiAlignment(zcu)) {
2675 flags.alignment = .none;
2676 } else {
2677 flags.alignment = field_align;
2678 }
2679 break :flags flags;
2680 },
2681 });
26822169 cur_derive = .{ .field_ptr = .{
26832170 .parent = parent,
26842171 .field_idx = @intCast(field_idx),
2685 .result_ptr_ty = new_ptr_ty,
2172 .result_ptr_ty = try base_ptr_ty.fieldPtrType(@intCast(field_idx), pt),
26862173 } };
26872174 cur_offset -= start_off;
26882175 break;
......@@ -2720,148 +2207,6 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, pt: Zcu.PerTh
27202207 } };
27212208}
27222209
2723pub fn resolveLazy(
2724 val: Value,
2725 arena: Allocator,
2726 pt: Zcu.PerThread,
2727) Zcu.SemaError!Value {
2728 switch (pt.zcu.intern_pool.indexToKey(val.toIntern())) {
2729 .int => |int| switch (int.storage) {
2730 .u64, .i64, .big_int => return val,
2731 .lazy_align, .lazy_size => return pt.intValue(
2732 Type.fromInterned(int.ty),
2733 try val.toUnsignedIntSema(pt),
2734 ),
2735 },
2736 .slice => |slice| {
2737 const ptr = try Value.fromInterned(slice.ptr).resolveLazy(arena, pt);
2738 const len = try Value.fromInterned(slice.len).resolveLazy(arena, pt);
2739 if (ptr.toIntern() == slice.ptr and len.toIntern() == slice.len) return val;
2740 return Value.fromInterned(try pt.intern(.{ .slice = .{
2741 .ty = slice.ty,
2742 .ptr = ptr.toIntern(),
2743 .len = len.toIntern(),
2744 } }));
2745 },
2746 .ptr => |ptr| {
2747 switch (ptr.base_addr) {
2748 .nav, .comptime_alloc, .uav, .int => return val,
2749 .comptime_field => |field_val| {
2750 const resolved_field_val = (try Value.fromInterned(field_val).resolveLazy(arena, pt)).toIntern();
2751 return if (resolved_field_val == field_val)
2752 val
2753 else
2754 Value.fromInterned(try pt.intern(.{ .ptr = .{
2755 .ty = ptr.ty,
2756 .base_addr = .{ .comptime_field = resolved_field_val },
2757 .byte_offset = ptr.byte_offset,
2758 } }));
2759 },
2760 .eu_payload, .opt_payload => |base| {
2761 const resolved_base = (try Value.fromInterned(base).resolveLazy(arena, pt)).toIntern();
2762 return if (resolved_base == base)
2763 val
2764 else
2765 Value.fromInterned(try pt.intern(.{ .ptr = .{
2766 .ty = ptr.ty,
2767 .base_addr = switch (ptr.base_addr) {
2768 .eu_payload => .{ .eu_payload = resolved_base },
2769 .opt_payload => .{ .opt_payload = resolved_base },
2770 else => unreachable,
2771 },
2772 .byte_offset = ptr.byte_offset,
2773 } }));
2774 },
2775 .arr_elem, .field => |base_index| {
2776 const resolved_base = (try Value.fromInterned(base_index.base).resolveLazy(arena, pt)).toIntern();
2777 return if (resolved_base == base_index.base)
2778 val
2779 else
2780 Value.fromInterned(try pt.intern(.{ .ptr = .{
2781 .ty = ptr.ty,
2782 .base_addr = switch (ptr.base_addr) {
2783 .arr_elem => .{ .arr_elem = .{
2784 .base = resolved_base,
2785 .index = base_index.index,
2786 } },
2787 .field => .{ .field = .{
2788 .base = resolved_base,
2789 .index = base_index.index,
2790 } },
2791 else => unreachable,
2792 },
2793 .byte_offset = ptr.byte_offset,
2794 } }));
2795 },
2796 }
2797 },
2798 .aggregate => |aggregate| switch (aggregate.storage) {
2799 .bytes => return val,
2800 .elems => |elems| {
2801 var resolved_elems: []InternPool.Index = &.{};
2802 for (elems, 0..) |elem, i| {
2803 const resolved_elem = (try Value.fromInterned(elem).resolveLazy(arena, pt)).toIntern();
2804 if (resolved_elems.len == 0 and resolved_elem != elem) {
2805 resolved_elems = try arena.alloc(InternPool.Index, elems.len);
2806 @memcpy(resolved_elems[0..i], elems[0..i]);
2807 }
2808 if (resolved_elems.len > 0) resolved_elems[i] = resolved_elem;
2809 }
2810 return if (resolved_elems.len == 0)
2811 val
2812 else
2813 pt.aggregateValue(.fromInterned(aggregate.ty), resolved_elems);
2814 },
2815 .repeated_elem => |elem| {
2816 const resolved_elem = try Value.fromInterned(elem).resolveLazy(arena, pt);
2817 return if (resolved_elem.toIntern() == elem)
2818 val
2819 else
2820 pt.aggregateSplatValue(.fromInterned(aggregate.ty), resolved_elem);
2821 },
2822 },
2823 .un => |un| {
2824 const resolved_tag = if (un.tag == .none)
2825 .none
2826 else
2827 (try Value.fromInterned(un.tag).resolveLazy(arena, pt)).toIntern();
2828 const resolved_val = (try Value.fromInterned(un.val).resolveLazy(arena, pt)).toIntern();
2829 return if (resolved_tag == un.tag and resolved_val == un.val)
2830 val
2831 else
2832 Value.fromInterned(try pt.internUnion(.{
2833 .ty = un.ty,
2834 .tag = resolved_tag,
2835 .val = resolved_val,
2836 }));
2837 },
2838 .error_union => |eu| switch (eu.val) {
2839 .err_name => return val,
2840 .payload => |payload| {
2841 const resolved_payload = try Value.fromInterned(payload).resolveLazy(arena, pt);
2842 if (resolved_payload.toIntern() == payload) return val;
2843 return .fromInterned(try pt.intern(.{ .error_union = .{
2844 .ty = eu.ty,
2845 .val = .{ .payload = resolved_payload.toIntern() },
2846 } }));
2847 },
2848 },
2849 .opt => |opt| switch (opt.val) {
2850 .none => return val,
2851 else => |payload| {
2852 const resolved_payload = try Value.fromInterned(payload).resolveLazy(arena, pt);
2853 if (resolved_payload.toIntern() == payload) return val;
2854 return .fromInterned(try pt.intern(.{ .opt = .{
2855 .ty = opt.ty,
2856 .val = resolved_payload.toIntern(),
2857 } }));
2858 },
2859 },
2860
2861 else => return val,
2862 }
2863}
2864
28652210const InterpretMode = enum {
28662211 /// In this mode, types are assumed to match what the compiler was built with in terms of field
28672212 /// order, field types, etc. This improves compiler performance. However, it means that certain
......@@ -2878,7 +2223,6 @@ const interpret_mode: InterpretMode = @field(InterpretMode, @tagName(build_optio
28782223
28792224/// Given a `Value` representing a comptime-known value of type `T`, unwrap it into an actual `T` known to the compiler.
28802225/// This is useful for accessing `std.builtin` structures received from comptime logic.
2881/// `val` must be fully resolved.
28822226pub fn interpret(val: Value, comptime T: type, pt: Zcu.PerThread) error{ OutOfMemory, UndefinedValue, TypeMismatch }!T {
28832227 const zcu = pt.zcu;
28842228 const io = zcu.comp.io;
......@@ -2917,7 +2261,6 @@ pub fn interpret(val: Value, comptime T: type, pt: Zcu.PerThread) error{ OutOfMe
29172261 },
29182262
29192263 .int => switch (ip.indexToKey(val.toIntern()).int.storage) {
2920 .lazy_align, .lazy_size => unreachable, // `val` is fully resolved
29212264 inline .u64, .i64 => |x| std.math.cast(T, x) orelse return error.TypeMismatch,
29222265 .big_int => |big| big.toInt(T) catch return error.TypeMismatch,
29232266 },
......@@ -2949,7 +2292,7 @@ pub fn interpret(val: Value, comptime T: type, pt: Zcu.PerThread) error{ OutOfMe
29492292 inline else => |tag_comptime| @unionInit(
29502293 T,
29512294 @tagName(tag_comptime),
2952 try val.unionValue(zcu).interpret(@FieldType(T, @tagName(tag_comptime)), pt),
2295 try val.unionPayload(zcu).interpret(@FieldType(T, @tagName(tag_comptime)), pt),
29532296 ),
29542297 };
29552298 },
......@@ -3076,7 +2419,7 @@ pub fn uninterpret(val: anytype, ty: Type, pt: Zcu.PerThread) error{ OutOfMemory
30762419 }
30772420 for (field_vals, 0..) |*field_val, field_idx| {
30782421 if (field_val.* == .none) {
3079 const default_init = struct_obj.field_inits.get(ip)[field_idx];
2422 const default_init = struct_obj.field_defaults.get(ip)[field_idx];
30802423 if (default_init == .none) return error.TypeMismatch;
30812424 field_val.* = default_init;
30822425 }
......@@ -3092,8 +2435,8 @@ pub fn uninterpret(val: anytype, ty: Type, pt: Zcu.PerThread) error{ OutOfMemory
30922435pub fn doPointersOverlap(ptr_val_a: Value, ptr_val_b: Value, elem_count: u64, zcu: *const Zcu) bool {
30932436 const ip = &zcu.intern_pool;
30942437
3095 const a_elem_ty = ptr_val_a.typeOf(zcu).indexablePtrElem(zcu);
3096 const b_elem_ty = ptr_val_b.typeOf(zcu).indexablePtrElem(zcu);
2438 const a_elem_ty = ptr_val_a.typeOf(zcu).indexableElem(zcu);
2439 const b_elem_ty = ptr_val_b.typeOf(zcu).indexableElem(zcu);
30972440
30982441 const a_ptr = ip.indexToKey(ptr_val_a.toIntern()).ptr;
30992442 const b_ptr = ip.indexToKey(ptr_val_b.toIntern()).ptr;
......@@ -3179,3 +2522,58 @@ pub fn eqlScalarNum(lhs: Value, rhs: Value, zcu: *Zcu) bool {
31792522 const rhs_bigint = rhs.toBigInt(&rhs_bigint_space, zcu);
31802523 return lhs_bigint.eql(rhs_bigint);
31812524}
2525
2526/// Asserts the value is an integer, and the destination type is ComptimeInt or Int.
2527/// Vectors are also accepted. Vector results are reduced with AND.
2528///
2529/// If provided, `vector_index` reports the first element that failed the range check.
2530pub fn intFitsInType(
2531 val: Value,
2532 ty: Type,
2533 vector_index: ?*usize,
2534 zcu: *const Zcu,
2535) bool {
2536 if (ty.toIntern() == .comptime_int_type) return true;
2537 const info = ty.intInfo(zcu);
2538 switch (val.toIntern()) {
2539 .zero_usize, .zero_u8 => return true,
2540 else => switch (zcu.intern_pool.indexToKey(val.toIntern())) {
2541 .undef => return true,
2542 .variable, .@"extern", .func, .ptr => {
2543 const target = zcu.getTarget();
2544 const ptr_bits = target.ptrBitWidth();
2545 return switch (info.signedness) {
2546 .signed => info.bits > ptr_bits,
2547 .unsigned => info.bits >= ptr_bits,
2548 };
2549 },
2550 .int => |int| {
2551 var buffer: InternPool.Key.Int.Storage.BigIntSpace = undefined;
2552 const big_int = int.storage.toBigInt(&buffer);
2553 return big_int.fitsInTwosComp(info.signedness, info.bits);
2554 },
2555 .aggregate => |aggregate| {
2556 assert(ty.zigTypeTag(zcu) == .vector);
2557 return switch (aggregate.storage) {
2558 .bytes => |bytes| for (bytes.toSlice(ty.vectorLen(zcu), &zcu.intern_pool), 0..) |byte, i| {
2559 if (byte == 0) continue;
2560 const actual_needed_bits = std.math.log2(byte) + 1 + @intFromBool(info.signedness == .signed);
2561 if (info.bits >= actual_needed_bits) continue;
2562 if (vector_index) |vi| vi.* = i;
2563 break false;
2564 } else true,
2565 .elems, .repeated_elem => for (switch (aggregate.storage) {
2566 .bytes => unreachable,
2567 .elems => |elems| elems,
2568 .repeated_elem => |elem| @as(*const [1]InternPool.Index, &elem),
2569 }, 0..) |elem, i| {
2570 if (Value.fromInterned(elem).intFitsInType(ty.scalarType(zcu), null, zcu)) continue;
2571 if (vector_index) |vi| vi.* = i;
2572 break false;
2573 } else true,
2574 };
2575 },
2576 else => unreachable,
2577 },
2578 }
2579}
src/Zcu.zig+778-370
......@@ -14,6 +14,8 @@ const mem = std.mem;
1414const Allocator = std.mem.Allocator;
1515const assert = std.debug.assert;
1616const log = std.log.scoped(.zcu);
17const deps_log = std.log.scoped(.zcu_deps);
18const refs_log = std.log.scoped(.zcu_refs);
1719const BigIntConst = std.math.big.int.Const;
1820const BigIntMutable = std.math.big.int.Mutable;
1921const Target = std.Target;
......@@ -117,7 +119,7 @@ module_roots: std.AutoArrayHashMapUnmanaged(*Package.Module, File.Index.Optional
117119///
118120/// Always accessed through `ImportTableAdapter`, where keys are fully resolved
119121/// file paths in order to ensure files are properly deduplicated. This table owns
120/// the keys and values.
122/// the keysand values.
121123///
122124/// Protected by Compilation's mutex.
123125///
......@@ -175,7 +177,9 @@ embed_table: std.ArrayHashMapUnmanaged(
175177/// is not yet implemented.
176178intern_pool: InternPool = .empty,
177179
178analysis_in_progress: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .empty,
180/// Value explains why this `AnalUnit` is being analyzed. It is `null` for the topmost analysis
181/// (index 0), and non-`null` for all others.
182analysis_in_progress: std.AutoArrayHashMapUnmanaged(AnalUnit, ?*const DependencyReason) = .empty,
179183/// The ErrorMsg memory is owned by the `AnalUnit`, using Module's general purpose allocator.
180184failed_analysis: std.AutoArrayHashMapUnmanaged(AnalUnit, *ErrorMsg) = .empty,
181185/// This `AnalUnit` failed semantic analysis because it required analysis of another `AnalUnit` which itself failed.
......@@ -187,6 +191,19 @@ transitive_failed_analysis: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .emp
187191/// codegen and linking run on a separate thread.
188192failed_codegen: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, *ErrorMsg) = .empty,
189193failed_types: std.AutoArrayHashMapUnmanaged(InternPool.Index, *ErrorMsg) = .empty,
194
195/// Key is an `AnalUnit` which is in `dependency_loop_nodes`. For each dependency loop, exactly one
196/// unit in the loop is in this map, though the choice is arbitrary and not necessarily reproducible
197/// between compilations. So, instead of (for instance) defining where the dependency loop "starts",
198/// this map simply exists to allow easily iterating all dependency loops exactly once.
199dependency_loops: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .empty,
200/// Key is an `AnalUnit`, value is the `AnalUnit` which the key references and why it does so.
201/// All units in here form loops. To iterate loops, see `dependency_loops`.
202dependency_loop_nodes: std.AutoArrayHashMapUnmanaged(AnalUnit, struct {
203 unit: AnalUnit,
204 reason: DependencyReason,
205}) = .empty,
206
190207/// Keep track of `@compileLog`s per `AnalUnit`.
191208/// We track the source location of the first `@compileLog` call, and all logged lines as a linked list.
192209/// The list is singly linked, but we do track its tail for fast appends (optimizing many logs in one unit).
......@@ -247,6 +264,10 @@ cimport_errors: std.AutoArrayHashMapUnmanaged(AnalUnit, std.zig.ErrorBundle) = .
247264/// Maximum amount of distinct error values, set by --error-limit
248265error_limit: ErrorInt,
249266
267/// In safe builds, `Type.assertHasLayout` may be called cross-thread, so this lock
268/// guards accesses to `outdated` and `potentially_outdated`. In unsafe builds, the
269/// lock is not needed and is compiled out.
270outdated_lock: if (std.debug.runtime_safety) std.Io.RwLock else void = if (std.debug.runtime_safety) .init,
250271/// Value is the number of PO dependencies of this AnalUnit.
251272/// This value will decrease as we perform semantic analysis to learn what is outdated.
252273/// If any of these PO deps is outdated, this value will be moved to `outdated`.
......@@ -254,19 +275,22 @@ potentially_outdated: std.AutoArrayHashMapUnmanaged(AnalUnit, u32) = .empty,
254275/// Value is the number of PO dependencies of this AnalUnit.
255276/// Once this value drops to 0, the AnalUnit is a candidate for re-analysis.
256277outdated: std.AutoArrayHashMapUnmanaged(AnalUnit, u32) = .empty,
257/// This contains all `AnalUnit`s in `outdated` whose PO dependency count is 0.
278/// This is the set of all `AnalUnit`s in `outdated` whose PO dependency count is 0.
258279/// Such `AnalUnit`s are ready for immediate re-analysis.
259280/// See `findOutdatedToAnalyze` for details.
260outdated_ready: std.AutoArrayHashMapUnmanaged(AnalUnit, void) = .empty,
281outdated_ready: struct {
282 /// These are separate from other units because it allows `findOutdatedToAnalyze` to prioritize
283 /// functions, which is useful because it means they will be sent to codegen more quickly.
284 funcs: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
285 /// Does not contain `.func` units.
286 other: std.AutoArrayHashMapUnmanaged(AnalUnit, void),
287} = .{ .funcs = .empty, .other = .empty },
261288/// This contains a list of AnalUnit whose analysis or codegen failed, but the
262289/// failure was something like running out of disk space, and trying again may
263290/// succeed. On the next update, we will flush this list, marking all members of
264291/// it as outdated.
265292retryable_failures: std.ArrayList(AnalUnit) = .empty,
266293
267func_body_analysis_queued: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .empty,
268nav_val_analysis_queued: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void) = .empty,
269
270294/// These are the modules which we initially queue for analysis in `Compilation.update`.
271295/// `resolveReferences` will use these as the root of its reachability traversal.
272296analysis_roots_buffer: [5]*Package.Module,
......@@ -322,6 +346,12 @@ codegen_task_pool: CodegenTaskPool,
322346
323347generation: u32 = 0,
324348
349pub const DependencyReason = struct {
350 src: LazySrcLoc,
351 /// Only populated if this is for a `.type_layout` unit.
352 type_layout_reason: Sema.type_resolution.LayoutResolveReason,
353};
354
325355pub const IncrementalDebugState = struct {
326356 /// All container types in the ZCU, even dead ones.
327357 /// Value is the generation the type was created on.
......@@ -1220,6 +1250,15 @@ pub const ErrorMsg = struct {
12201250 notes: []ErrorMsg = &.{},
12211251 reference_trace_root: AnalUnit.Optional = .none,
12221252
1253 pub fn order(lhs: *const ErrorMsg, rhs: *const ErrorMsg, zcu: *Zcu) std.math.Order {
1254 return lhs.src_loc.order(rhs.src_loc, zcu).differ() orelse
1255 std.mem.order(u8, lhs.msg, rhs.msg).differ() orelse
1256 std.math.order(lhs.notes.len, rhs.notes.len).differ() orelse
1257 for (lhs.notes, rhs.notes) |*lhs_note, *rhs_note| {
1258 if (order(lhs_note, rhs_note, zcu).differ()) |o| break o;
1259 } else .eq;
1260 }
1261
12231262 pub fn create(
12241263 gpa: Allocator,
12251264 src_loc: LazySrcLoc,
......@@ -1910,40 +1949,6 @@ pub const SrcLoc = struct {
19101949 const full = tree.fullPtrType(parent_node).?;
19111950 return tree.nodeToSpan(full.ast.bit_range_end.unwrap().?);
19121951 },
1913 .node_offset_container_tag => |node_off| {
1914 const tree = try src_loc.file_scope.getTree(zcu);
1915 const parent_node = node_off.toAbsolute(src_loc.base_node);
1916
1917 switch (tree.nodeTag(parent_node)) {
1918 .container_decl_arg, .container_decl_arg_trailing => {
1919 const full = tree.containerDeclArg(parent_node);
1920 const arg_node = full.ast.arg.unwrap().?;
1921 return tree.nodeToSpan(arg_node);
1922 },
1923 .tagged_union_enum_tag, .tagged_union_enum_tag_trailing => {
1924 const full = tree.taggedUnionEnumTag(parent_node);
1925 const arg_node = full.ast.arg.unwrap().?;
1926
1927 return tree.tokensToSpan(
1928 tree.firstToken(arg_node) - 2,
1929 tree.lastToken(arg_node) + 1,
1930 tree.nodeMainToken(arg_node),
1931 );
1932 },
1933 else => unreachable,
1934 }
1935 },
1936 .node_offset_field_default => |node_off| {
1937 const tree = try src_loc.file_scope.getTree(zcu);
1938 const parent_node = node_off.toAbsolute(src_loc.base_node);
1939
1940 const full: Ast.full.ContainerField = switch (tree.nodeTag(parent_node)) {
1941 .container_field => tree.containerField(parent_node),
1942 .container_field_init => tree.containerFieldInit(parent_node),
1943 else => unreachable,
1944 };
1945 return tree.nodeToSpan(full.ast.value_expr.unwrap().?);
1946 },
19471952 .node_offset_init_ty => |node_off| {
19481953 const tree = try src_loc.file_scope.getTree(zcu);
19491954 const parent_node = node_off.toAbsolute(src_loc.base_node);
......@@ -2019,6 +2024,20 @@ pub const SrcLoc = struct {
20192024 }
20202025 return tree.nodeToSpan(node);
20212026 },
2027 .container_arg => {
2028 const tree = try src_loc.file_scope.getTree(zcu);
2029 const node = src_loc.base_node;
2030 var buf: [2]Ast.Node.Index = undefined;
2031 if (tree.fullContainerDecl(&buf, node)) |container_decl| {
2032 const arg_node = container_decl.ast.arg.unwrap() orelse return tree.nodeToSpan(node);
2033 return tree.nodeToSpan(arg_node);
2034 } else if (tree.builtinCallParams(&buf, node)) |args| {
2035 // Builtin calls (`@Enum` etc) should use the first argument.
2036 return tree.nodeToSpan(if (args.len > 0) args[0] else node);
2037 } else {
2038 return tree.nodeToSpan(node);
2039 }
2040 },
20222041 .container_field_name,
20232042 .container_field_value,
20242043 .container_field_type,
......@@ -2027,8 +2046,38 @@ pub const SrcLoc = struct {
20272046 const tree = try src_loc.file_scope.getTree(zcu);
20282047 const node = src_loc.base_node;
20292048 var buf: [2]Ast.Node.Index = undefined;
2030 const container_decl = tree.fullContainerDecl(&buf, node) orelse
2049 const container_decl = tree.fullContainerDecl(&buf, node) orelse {
2050 // This could be a reification builtin. These are the args we care about:
2051 // * `@Enum(_, _, names, values)`
2052 // * `@Struct(_, _, names, types, values_and_aligns)`
2053 // * `@Union(_, _, names, types, aligns)`
2054 if (tree.builtinCallParams(&buf, node)) |args| {
2055 const builtin_name = tree.tokenSlice(tree.firstToken(node));
2056 const arg_index: ?u3 = if (std.mem.eql(u8, builtin_name, "@Enum")) switch (src_loc.lazy) {
2057 .container_field_name => 2,
2058 .container_field_value => 3,
2059 .container_field_type => null,
2060 .container_field_align => null,
2061 else => unreachable,
2062 } else if (std.mem.eql(u8, builtin_name, "@Struct")) switch (src_loc.lazy) {
2063 .container_field_name => 2,
2064 .container_field_value => 4,
2065 .container_field_type => 3,
2066 .container_field_align => 4,
2067 else => unreachable,
2068 } else if (std.mem.eql(u8, builtin_name, "@Union")) switch (src_loc.lazy) {
2069 .container_field_name => 2,
2070 .container_field_value => 4,
2071 .container_field_type => 3,
2072 .container_field_align => null,
2073 else => unreachable,
2074 } else null;
2075 if (arg_index) |i| {
2076 if (args.len >= i) return tree.nodeToSpan(args[i]);
2077 }
2078 }
20312079 return tree.nodeToSpan(node);
2080 };
20322081
20332082 var cur_field_idx: usize = 0;
20342083 for (container_decl.ast.members) |member_node| {
......@@ -2260,7 +2309,11 @@ pub const SrcLoc = struct {
22602309 var param_it = full.iterate(tree);
22612310 for (0..param_idx) |_| assert(param_it.next() != null);
22622311 const param = param_it.next().?;
2263 return tree.nodeToSpan(param.type_expr.?);
2312 if (param.anytype_ellipsis3) |tok| {
2313 return tree.tokenToSpan(tok);
2314 } else {
2315 return tree.nodeToSpan(param.type_expr.?);
2316 }
22642317 },
22652318 }
22662319 }
......@@ -2482,10 +2535,6 @@ pub const LazySrcLoc = struct {
24822535 node_offset_ptr_bitoffset: Ast.Node.Offset,
24832536 /// The source location points to the host size of a pointer.
24842537 node_offset_ptr_hostsize: Ast.Node.Offset,
2485 /// The source location points to the tag type of an union or an enum.
2486 node_offset_container_tag: Ast.Node.Offset,
2487 /// The source location points to the default value of a field.
2488 node_offset_field_default: Ast.Node.Offset,
24892538 /// The source location points to the type of an array or struct initializer.
24902539 node_offset_init_ty: Ast.Node.Offset,
24912540 /// The source location points to the LHS of an assignment (or assign-op, e.g. `+=`).
......@@ -2530,6 +2579,11 @@ pub const LazySrcLoc = struct {
25302579 fn_proto_param_type: FnProtoParam,
25312580 array_cat_lhs: ArrayCat,
25322581 array_cat_rhs: ArrayCat,
2582 /// The source location points to the backing or tag type expression of
2583 /// the container type declaration at the base node.
2584 ///
2585 /// For 'union(enum(T))', this points to 'T', not 'enum(T)'.
2586 container_arg,
25332587 /// The source location points to the name of the field at the given index
25342588 /// of the container type declaration at the base node.
25352589 container_field_name: u32,
......@@ -2685,10 +2739,10 @@ pub const LazySrcLoc = struct {
26852739 .struct_init, .struct_init_ref => zir.extraData(Zir.Inst.StructInit, inst.data.pl_node.payload_index).data.abs_node,
26862740 .struct_init_anon => zir.extraData(Zir.Inst.StructInitAnon, inst.data.pl_node.payload_index).data.abs_node,
26872741 .extended => switch (inst.data.extended.opcode) {
2688 .struct_decl => zir.extraData(Zir.Inst.StructDecl, inst.data.extended.operand).data.src_node,
2689 .union_decl => zir.extraData(Zir.Inst.UnionDecl, inst.data.extended.operand).data.src_node,
2690 .enum_decl => zir.extraData(Zir.Inst.EnumDecl, inst.data.extended.operand).data.src_node,
2691 .opaque_decl => zir.extraData(Zir.Inst.OpaqueDecl, inst.data.extended.operand).data.src_node,
2742 .struct_decl => zir.getStructDecl(zir_inst).src_node,
2743 .union_decl => zir.getUnionDecl(zir_inst).src_node,
2744 .enum_decl => zir.getEnumDecl(zir_inst).src_node,
2745 .opaque_decl => zir.getOpaqueDecl(zir_inst).src_node,
26922746 .reify_enum => zir.extraData(Zir.Inst.ReifyEnum, inst.data.extended.operand).data.node,
26932747 .reify_struct => zir.extraData(Zir.Inst.ReifyStruct, inst.data.extended.operand).data.node,
26942748 .reify_union => zir.extraData(Zir.Inst.ReifyUnion, inst.data.extended.operand).data.node,
......@@ -2715,36 +2769,34 @@ pub const LazySrcLoc = struct {
27152769 };
27162770 }
27172771
2718 /// Used to sort error messages, so that they're printed in a consistent order.
2719 /// If an error is returned, a file could not be read in order to resolve a source location.
2720 /// In that case, `bad_file_out` is populated, and sorting is impossible.
2721 pub fn lessThan(lhs_lazy: LazySrcLoc, rhs_lazy: LazySrcLoc, zcu: *Zcu, bad_file_out: **Zcu.File) File.GetSourceError!bool {
2722 const lhs_src = lhs_lazy.upgradeOrLost(zcu) orelse {
2772 pub fn order(lhs: LazySrcLoc, rhs: LazySrcLoc, zcu: *Zcu) std.math.Order {
2773 const lhs_resolved = lhs.upgradeOrLost(zcu) orelse {
27232774 // LHS source location lost, so should never be referenced. Just sort it to the end.
2724 return false;
2775 return .gt;
27252776 };
2726 const rhs_src = rhs_lazy.upgradeOrLost(zcu) orelse {
2777 const rhs_resolved = rhs.upgradeOrLost(zcu) orelse {
27272778 // RHS source location lost, so should never be referenced. Just sort it to the end.
2728 return true;
2779 return .lt;
27292780 };
2730 if (lhs_src.file_scope != rhs_src.file_scope) {
2731 const lhs_path = lhs_src.file_scope.path;
2732 const rhs_path = rhs_src.file_scope.path;
2733 if (lhs_path.root != rhs_path.root) {
2734 return @intFromEnum(lhs_path.root) < @intFromEnum(rhs_path.root);
2735 }
2736 return std.mem.order(u8, lhs_path.sub_path, rhs_path.sub_path).compare(.lt);
2781 if (lhs_resolved.file_scope != rhs_resolved.file_scope) {
2782 const lhs_path = lhs_resolved.file_scope.path;
2783 const rhs_path = rhs_resolved.file_scope.path;
2784 return std.math.order(@intFromEnum(lhs_path.root), @intFromEnum(rhs_path.root)).differ() orelse
2785 std.mem.order(u8, lhs_path.sub_path, rhs_path.sub_path).differ().?;
27372786 }
2738
2739 const lhs_span = lhs_src.span(zcu) catch |err| {
2740 bad_file_out.* = lhs_src.file_scope;
2741 return err;
2787 const prev_prot = zcu.comp.io.swapCancelProtection(.blocked);
2788 defer _ = zcu.comp.io.swapCancelProtection(prev_prot);
2789 const lhs_span = lhs_resolved.span(zcu) catch |err| {
2790 assert(err != error.Canceled); // we're protected
2791 // Failed to read LHS, so we'll get a transient error. Just sort it to the end.
2792 return .gt;
27422793 };
2743 const rhs_span = rhs_src.span(zcu) catch |err| {
2744 bad_file_out.* = rhs_src.file_scope;
2745 return err;
2794 const rhs_span = rhs_resolved.span(zcu) catch |err| {
2795 assert(err != error.Canceled); // we're protected
2796 // Failed to read RHS, so we'll get a transient error. Just sort it to the end.
2797 return .lt;
27462798 };
2747 return lhs_span.main < rhs_span.main;
2799 return std.math.order(lhs_span.main, rhs_span.main);
27482800 }
27492801};
27502802
......@@ -2800,6 +2852,8 @@ pub fn deinit(zcu: *Zcu) void {
28002852 zcu.analysis_in_progress.deinit(gpa);
28012853 zcu.failed_analysis.deinit(gpa);
28022854 zcu.transitive_failed_analysis.deinit(gpa);
2855 zcu.dependency_loops.deinit(gpa);
2856 zcu.dependency_loop_nodes.deinit(gpa);
28032857 zcu.failed_codegen.deinit(gpa);
28042858 zcu.failed_types.deinit(gpa);
28052859
......@@ -2830,12 +2884,10 @@ pub fn deinit(zcu: *Zcu) void {
28302884
28312885 zcu.potentially_outdated.deinit(gpa);
28322886 zcu.outdated.deinit(gpa);
2833 zcu.outdated_ready.deinit(gpa);
2887 zcu.outdated_ready.funcs.deinit(gpa);
2888 zcu.outdated_ready.other.deinit(gpa);
28342889 zcu.retryable_failures.deinit(gpa);
28352890
2836 zcu.func_body_analysis_queued.deinit(gpa);
2837 zcu.nav_val_analysis_queued.deinit(gpa);
2838
28392891 zcu.test_functions.deinit(gpa);
28402892
28412893 for (zcu.global_assembly.values()) |s| {
......@@ -3063,18 +3115,24 @@ pub fn markDependeeOutdated(
30633115 marked_po: enum { not_marked_po, marked_po },
30643116 dependee: InternPool.Dependee,
30653117) !void {
3066 log.debug("outdated dependee: {f}", .{zcu.fmtDependee(dependee)});
3118 const gpa = zcu.comp.gpa;
3119 deps_log.debug("outdated dependee: {f}", .{zcu.fmtDependee(dependee)});
30673120 var it = zcu.intern_pool.dependencyIterator(dependee);
3121 if (std.debug.runtime_safety) zcu.outdated_lock.lockUncancelable(zcu.comp.io);
3122 defer if (std.debug.runtime_safety) zcu.outdated_lock.unlock(zcu.comp.io);
30683123 while (it.next()) |depender| {
30693124 if (zcu.outdated.getPtr(depender)) |po_dep_count| {
30703125 switch (marked_po) {
30713126 .not_marked_po => {},
30723127 .marked_po => {
30733128 po_dep_count.* -= 1;
3074 log.debug("outdated {f} => already outdated {f} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender), po_dep_count.* });
3129 deps_log.debug("outdated {f} => already outdated {f} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender), po_dep_count.* });
30753130 if (po_dep_count.* == 0) {
3076 log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)});
3077 try zcu.outdated_ready.put(zcu.gpa, depender, {});
3131 deps_log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)});
3132 switch (depender.unwrap()) {
3133 .func => |func| try zcu.outdated_ready.funcs.put(gpa, func, {}),
3134 else => try zcu.outdated_ready.other.put(gpa, depender, {}),
3135 }
30783136 }
30793137 },
30803138 }
......@@ -3090,14 +3148,17 @@ pub fn markDependeeOutdated(
30903148 },
30913149 };
30923150 try zcu.outdated.putNoClobber(
3093 zcu.gpa,
3151 gpa,
30943152 depender,
30953153 new_po_dep_count,
30963154 );
3097 log.debug("outdated {f} => new outdated {f} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender), new_po_dep_count });
3155 deps_log.debug("outdated {f} => new outdated {f} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender), new_po_dep_count });
30983156 if (new_po_dep_count == 0) {
3099 log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)});
3100 try zcu.outdated_ready.put(zcu.gpa, depender, {});
3157 deps_log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)});
3158 switch (depender.unwrap()) {
3159 .func => |func| try zcu.outdated_ready.funcs.put(gpa, func, {}),
3160 else => try zcu.outdated_ready.other.put(gpa, depender, {}),
3161 }
31013162 }
31023163 // If this is a Decl and was not previously PO, we must recursively
31033164 // mark dependencies on its tyval as PO.
......@@ -3109,17 +3170,27 @@ pub fn markDependeeOutdated(
31093170}
31103171
31113172pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {
3112 log.debug("up-to-date dependee: {f}", .{zcu.fmtDependee(dependee)});
3173 if (std.debug.runtime_safety) zcu.outdated_lock.lockUncancelable(zcu.comp.io);
3174 defer if (std.debug.runtime_safety) zcu.outdated_lock.unlock(zcu.comp.io);
3175 return markPoDependeeUpToDateInner(zcu, dependee);
3176}
3177/// Assumes that `zcu.outdated_lock` is already held exclusively.
3178fn markPoDependeeUpToDateInner(zcu: *Zcu, dependee: InternPool.Dependee) !void {
3179 const gpa = zcu.comp.gpa;
3180 deps_log.debug("up-to-date dependee: {f}", .{zcu.fmtDependee(dependee)});
31133181 var it = zcu.intern_pool.dependencyIterator(dependee);
31143182 while (it.next()) |depender| {
31153183 if (zcu.outdated.getPtr(depender)) |po_dep_count| {
31163184 // This depender is already outdated, but it now has one
31173185 // less PO dependency!
31183186 po_dep_count.* -= 1;
3119 log.debug("up-to-date {f} => {f} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender), po_dep_count.* });
3187 deps_log.debug("up-to-date {f} => {f} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender), po_dep_count.* });
31203188 if (po_dep_count.* == 0) {
3121 log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)});
3122 try zcu.outdated_ready.put(zcu.gpa, depender, {});
3189 deps_log.debug("outdated ready: {f}", .{zcu.fmtAnalUnit(depender)});
3190 switch (depender.unwrap()) {
3191 .func => |func| try zcu.outdated_ready.funcs.put(gpa, func, {}),
3192 else => try zcu.outdated_ready.other.put(gpa, depender, {}),
3193 }
31233194 }
31243195 continue;
31253196 }
......@@ -3132,11 +3203,11 @@ pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {
31323203 };
31333204 if (ptr.* > 1) {
31343205 ptr.* -= 1;
3135 log.debug("up-to-date {f} => {f} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender), ptr.* });
3206 deps_log.debug("up-to-date {f} => {f} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender), ptr.* });
31363207 continue;
31373208 }
31383209
3139 log.debug("up-to-date {f} => {f} po_deps=0 (up-to-date)", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender) });
3210 deps_log.debug("up-to-date {f} => {f} po_deps=0 (up-to-date)", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(depender) });
31403211
31413212 // This dependency is no longer PO, i.e. is known to be up-to-date.
31423213 assert(zcu.potentially_outdated.swapRemove(depender));
......@@ -3144,139 +3215,120 @@ pub fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void {
31443215 // as no longer PO.
31453216 switch (depender.unwrap()) {
31463217 .@"comptime" => {},
3147 .nav_val => |nav| try zcu.markPoDependeeUpToDate(.{ .nav_val = nav }),
3148 .nav_ty => |nav| try zcu.markPoDependeeUpToDate(.{ .nav_ty = nav }),
3149 .type => |ty| try zcu.markPoDependeeUpToDate(.{ .interned = ty }),
3150 .func => |func| try zcu.markPoDependeeUpToDate(.{ .interned = func }),
3151 .memoized_state => |stage| try zcu.markPoDependeeUpToDate(.{ .memoized_state = stage }),
3218 .nav_val => |nav| try zcu.markPoDependeeUpToDateInner(.{ .nav_val = nav }),
3219 .nav_ty => |nav| try zcu.markPoDependeeUpToDateInner(.{ .nav_ty = nav }),
3220 .type_layout => |ty| try zcu.markPoDependeeUpToDateInner(.{ .type_layout = ty }),
3221 .struct_defaults => |ty| try zcu.markPoDependeeUpToDateInner(.{ .struct_defaults = ty }),
3222 .func => |func| try zcu.markPoDependeeUpToDateInner(.{ .func_ies = func }),
3223 .memoized_state => |stage| try zcu.markPoDependeeUpToDateInner(.{ .memoized_state = stage }),
31523224 }
31533225 }
31543226}
31553227
31563228/// Given a AnalUnit which is newly outdated or PO, mark all AnalUnits which may
31573229/// in turn be PO, due to a dependency on the original AnalUnit's tyval or IES.
3158fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUnit) !void {
3230///
3231/// Assumes that `zcu.outdated_lock` is already held exclusively.
3232fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: AnalUnit) Allocator.Error!void {
3233 const gpa = zcu.comp.gpa;
31593234 const ip = &zcu.intern_pool;
31603235 const dependee: InternPool.Dependee = switch (maybe_outdated.unwrap()) {
31613236 .@"comptime" => return, // analysis of a comptime decl can't outdate any dependencies
31623237 .nav_val => |nav| .{ .nav_val = nav },
31633238 .nav_ty => |nav| .{ .nav_ty = nav },
3164 .type => |ty| .{ .interned = ty },
3165 .func => |func_index| .{ .interned = func_index }, // IES
3239 .type_layout => |ty| .{ .type_layout = ty },
3240 .struct_defaults => |ty| .{ .struct_defaults = ty },
3241 .func => |func_index| .{ .func_ies = func_index },
31663242 .memoized_state => |stage| .{ .memoized_state = stage },
31673243 };
3168 log.debug("potentially outdated dependee: {f}", .{zcu.fmtDependee(dependee)});
3244 deps_log.debug("potentially outdated dependee: {f}", .{zcu.fmtDependee(dependee)});
31693245 var it = ip.dependencyIterator(dependee);
31703246 while (it.next()) |po| {
31713247 if (zcu.outdated.getPtr(po)) |po_dep_count| {
3172 // This dependency is already outdated, but it now has one more PO
3173 // dependency.
3248 // This dependency is already outdated, but it now has one more PO dependency.
31743249 if (po_dep_count.* == 0) {
3175 _ = zcu.outdated_ready.swapRemove(po);
3250 switch (po.unwrap()) {
3251 .func => |func| _ = zcu.outdated_ready.funcs.swapRemove(func),
3252 else => _ = zcu.outdated_ready.other.swapRemove(po),
3253 }
31763254 }
31773255 po_dep_count.* += 1;
3178 log.debug("po {f} => {f} [outdated] po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(po), po_dep_count.* });
3256 deps_log.debug("po {f} => {f} [outdated] po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(po), po_dep_count.* });
31793257 continue;
31803258 }
31813259 if (zcu.potentially_outdated.getPtr(po)) |n| {
31823260 // There is now one more PO dependency.
31833261 n.* += 1;
3184 log.debug("po {f} => {f} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(po), n.* });
3262 deps_log.debug("po {f} => {f} po_deps={}", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(po), n.* });
31853263 continue;
31863264 }
3187 try zcu.potentially_outdated.putNoClobber(zcu.gpa, po, 1);
3188 log.debug("po {f} => {f} po_deps=1", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(po) });
3265 try zcu.potentially_outdated.putNoClobber(gpa, po, 1);
3266 deps_log.debug("po {f} => {f} po_deps=1", .{ zcu.fmtDependee(dependee), zcu.fmtAnalUnit(po) });
31893267 // This AnalUnit was not already PO, so we must recursively mark its dependers as also PO.
31903268 try zcu.markTransitiveDependersPotentiallyOutdated(po);
31913269 }
31923270}
31933271
3272/// Selects an outdated `AnalUnit` to analyze next. Called from the main semantic analysis loop when
3273/// there is no work immediately queued. The unit is chosen such that it is unlikely to require any
3274/// recursive analysis (all of its previously-marked dependencies are already up-to-date), because
3275/// recursive analysis can cause over-analysis on incremental updates.
31943276pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?AnalUnit {
3195 if (!zcu.comp.config.incremental) return null;
3196
3197 if (zcu.outdated.count() == 0) {
3198 // Any units in `potentially_outdated` must just be stuck in loops with one another: none of those
3199 // units have had any outdated dependencies so far, and all of their remaining PO deps are triggered
3200 // by other units in `potentially_outdated`. So, we can safety assume those units up-to-date.
3201 zcu.potentially_outdated.clearRetainingCapacity();
3202 log.debug("findOutdatedToAnalyze: no outdated depender", .{});
3203 return null;
3277 // We prioritize functions, because the sooner they get analyzed, the sooner they can be send to
3278 // the codegen backend and linker, which are usually running in parallel (so this can increase
3279 // parallelism).
3280 // TODO: perhaps we should also experiment with *avoiding* functions if the codegen/link queue
3281 // is backed up (for instance due to a very large function). That could help minimize blocking
3282 // on the main thread in `CodegenTaskPool.start` waiting for the linker to catch up.
3283 if (zcu.outdated_ready.funcs.count() > 0) {
3284 const unit: AnalUnit = .wrap(.{ .func = zcu.outdated_ready.funcs.keys()[0] });
3285 log.debug("findOutdatedToAnalyze: {f}", .{zcu.fmtAnalUnit(unit)});
3286 return unit;
32043287 }
32053288
3206 // Our goal is to find an outdated AnalUnit which itself has no outdated or
3207 // PO dependencies. Most of the time, such an AnalUnit will exist - we track
3208 // them in the `outdated_ready` set for efficiency. However, this is not
3209 // necessarily the case, since the Decl dependency graph may contain loops
3210 // via mutually recursive definitions:
3211 // pub const A = struct { b: *B };
3212 // pub const B = struct { b: *A };
3213 // In this case, we must defer to more complex logic below.
3214
3215 if (zcu.outdated_ready.count() > 0) {
3216 const unit = zcu.outdated_ready.keys()[0];
3217 log.debug("findOutdatedToAnalyze: trivial {f}", .{zcu.fmtAnalUnit(unit)});
3289 if (zcu.outdated_ready.other.count() > 0) {
3290 const unit = zcu.outdated_ready.other.keys()[0];
3291 log.debug("findOutdatedToAnalyze: {f}", .{zcu.fmtAnalUnit(unit)});
32183292 return unit;
32193293 }
32203294
3221 // There is no single AnalUnit which is ready for re-analysis. Instead, we must assume that some
3222 // AnalUnit with PO dependencies is outdated -- e.g. in the above example we arbitrarily pick one of
3223 // A or B. We should definitely not select a function, since a function can't be responsible for the
3224 // loop (IES dependencies can't have loops). We should also, of course, not select a `comptime`
3225 // declaration, since you can't depend on those!
3226
3227 // The choice of this unit could have a big impact on how much total analysis we perform, since
3228 // if analysis concludes any dependencies on its result are up-to-date, then other PO AnalUnit
3229 // may be resolved as up-to-date. To hopefully avoid doing too much work, let's find a unit
3230 // which the most things depend on - the idea is that this will resolve a lot of loops (but this
3231 // is only a heuristic).
3232
3233 log.debug("findOutdatedToAnalyze: no trivial ready, using heuristic; {d} outdated, {d} PO", .{
3234 zcu.outdated.count(),
3235 zcu.potentially_outdated.count(),
3236 });
3237
3238 const ip = &zcu.intern_pool;
3295 // Usually, getting here means that everything is up-to-date, so there is no more work to do. We
3296 // will see that `zcu.outdated` and `zcu.potentially_outdated` are both empty.
3297 //
3298 // However, if a previous update had a dependency loop compile error, there is a cycle in the
3299 // dependency graph (which is usually acyclic), which can cause a scenario where no unit appears
3300 // to be ready, because they're all waiting for the next in the loop to be up-to-date. In that
3301 // case, we usually have to just bite the bullet and analyze one of them. An exception is if
3302 // `zcu.outdated` is empty but `zcu.potentially_outdated` is non-empty: in that case, the only
3303 // possible situation is a cycle where everything is actually up-to-date, so we can clear out
3304 // `zcu.potentially_outdated` and we are done.
32393305
3240 var chosen_unit: ?AnalUnit = null;
3241 var chosen_unit_dependers: u32 = undefined;
3242
3243 inline for (.{ zcu.outdated.keys(), zcu.potentially_outdated.keys() }) |outdated_units| {
3244 for (outdated_units) |unit| {
3245 var n: u32 = 0;
3246 var it = ip.dependencyIterator(switch (unit.unwrap()) {
3247 .func => continue, // a `func` definitely can't be causing the loop so it is a bad choice
3248 .@"comptime" => continue, // a `comptime` block can't even be depended on so it is a terrible choice
3249 .type => |ty| .{ .interned = ty },
3250 .nav_val => |nav| .{ .nav_val = nav },
3251 .nav_ty => |nav| .{ .nav_ty = nav },
3252 .memoized_state => {
3253 // If we've hit a loop and some `.memoized_state` is outdated, we should make that choice eagerly.
3254 // In general, it's good to resolve this early on, since -- for instance -- almost every function
3255 // references the panic handler.
3256 return unit;
3257 },
3258 });
3259 while (it.next()) |_| n += 1;
3306 if (std.debug.runtime_safety) zcu.outdated_lock.lockUncancelable(zcu.comp.io);
3307 defer if (std.debug.runtime_safety) zcu.outdated_lock.unlock(zcu.comp.io);
32603308
3261 if (chosen_unit == null or n > chosen_unit_dependers) {
3262 chosen_unit = unit;
3263 chosen_unit_dependers = n;
3264 }
3265 }
3309 if (zcu.outdated.count() == 0) {
3310 // Everything is up-to-date. There could be lingering entries in `zcu.potentially_outdated`
3311 // from a dependency loop on a previous update.
3312 zcu.potentially_outdated.clearRetainingCapacity();
3313 log.debug("findOutdatedToAnalyze: all up-to-date", .{});
3314 return null;
32663315 }
32673316
3268 log.debug("findOutdatedToAnalyze: heuristic returned '{f}' ({d} dependers)", .{
3269 zcu.fmtAnalUnit(chosen_unit.?),
3270 chosen_unit_dependers,
3317 const unit = zcu.outdated.keys()[0];
3318 log.debug("findOutdatedToAnalyze: dependency loop affecting {d} units, selected {f}", .{
3319 zcu.outdated.count(),
3320 zcu.fmtAnalUnit(unit),
32713321 });
3272
3273 return chosen_unit.?;
3322 return unit;
32743323}
32753324
32763325/// During an incremental update, before semantic analysis, call this to flush all values from
32773326/// `retryable_failures` and mark them as outdated so they get re-analyzed.
32783327pub fn flushRetryableFailures(zcu: *Zcu) !void {
3279 const gpa = zcu.gpa;
3328 const comp = zcu.comp;
3329 const gpa = comp.gpa;
3330 if (std.debug.runtime_safety) zcu.outdated_lock.lockUncancelable(comp.io);
3331 defer if (std.debug.runtime_safety) zcu.outdated_lock.unlock(comp.io);
32803332 for (zcu.retryable_failures.items) |depender| {
32813333 if (zcu.outdated.contains(depender)) continue;
32823334 if (zcu.potentially_outdated.fetchSwapRemove(depender)) |kv| {
......@@ -3350,12 +3402,59 @@ pub fn mapOldZirToNew(
33503402 }
33513403
33523404 while (match_stack.pop()) |match_item| {
3353 // First, a check: if the number of captures of this type has changed, we can't map it, because
3354 // we wouldn't know how to correlate type information with the last update.
3355 // Synchronizes with logic in `Zcu.PerThread.recreateStructType` etc.
3356 if (old_zir.typeCapturesLen(match_item.old_inst) != new_zir.typeCapturesLen(match_item.new_inst)) {
3357 // Don't map this type or anything within it.
3358 continue;
3405 // There are some properties of type declarations which cannot change across incremental
3406 // updates. If they have, we need to ignore this mapping. These properties are essentially
3407 // everything passed into `InternPool.getDeclaredStructType` (likewise for unions, enums,
3408 // and opaques).
3409 const old_tag = old_zir.instructions.items(.data)[@intFromEnum(match_item.old_inst)].extended.opcode;
3410 const new_tag = new_zir.instructions.items(.data)[@intFromEnum(match_item.new_inst)].extended.opcode;
3411 if (old_tag != new_tag) continue;
3412 switch (old_tag) {
3413 .struct_decl => {
3414 const old = old_zir.getStructDecl(match_item.old_inst);
3415 const new = new_zir.getStructDecl(match_item.new_inst);
3416 if (old.captures.len != new.captures.len) continue;
3417 if (old.field_names.len != new.field_names.len) continue;
3418 if (old.layout != new.layout) continue;
3419 const old_any_field_aligns = old.field_align_body_lens != null;
3420 const old_any_field_defaults = old.field_default_body_lens != null;
3421 const old_any_comptime_fields = old.field_comptime_bits != null;
3422 const old_explicit_backing_int = old.backing_int_type_body != null;
3423 const new_any_field_aligns = new.field_align_body_lens != null;
3424 const new_any_field_defaults = new.field_default_body_lens != null;
3425 const new_any_comptime_fields = new.field_comptime_bits != null;
3426 const new_explicit_backing_int = new.backing_int_type_body != null;
3427 if (old_any_field_aligns != new_any_field_aligns) continue;
3428 if (old_any_field_defaults != new_any_field_defaults) continue;
3429 if (old_any_comptime_fields != new_any_comptime_fields) continue;
3430 if (old_explicit_backing_int != new_explicit_backing_int) continue;
3431 },
3432 .union_decl => {
3433 const old = old_zir.getUnionDecl(match_item.old_inst);
3434 const new = new_zir.getUnionDecl(match_item.new_inst);
3435 if (old.captures.len != new.captures.len) continue;
3436 if (old.field_names.len != new.field_names.len) continue;
3437 if (old.kind != new.kind) continue;
3438 const old_any_field_aligns = old.field_align_body_lens != null;
3439 const new_any_field_aligns = new.field_align_body_lens != null;
3440 if (old_any_field_aligns != new_any_field_aligns) continue;
3441 },
3442 .enum_decl => {
3443 const old = old_zir.getEnumDecl(match_item.old_inst);
3444 const new = new_zir.getEnumDecl(match_item.new_inst);
3445 if (old.captures.len != new.captures.len) continue;
3446 if (old.field_names.len != new.field_names.len) continue;
3447 if (old.nonexhaustive != new.nonexhaustive) continue;
3448 const old_explicit_tag_type = old.tag_type_body != null;
3449 const new_explicit_tag_type = new.tag_type_body != null;
3450 if (old_explicit_tag_type != new_explicit_tag_type) continue;
3451 },
3452 .opaque_decl => {
3453 const old = old_zir.getOpaqueDecl(match_item.old_inst);
3454 const new = new_zir.getOpaqueDecl(match_item.new_inst);
3455 if (old.captures.len != new.captures.len) continue;
3456 },
3457 else => unreachable,
33593458 }
33603459
33613460 // Match the namespace declaration itself
......@@ -3377,25 +3476,21 @@ pub fn mapOldZirToNew(
33773476 var comptime_decls: std.ArrayList(Zir.Inst.Index) = .empty;
33783477 defer comptime_decls.deinit(gpa);
33793478
3380 {
3381 var old_decl_it = old_zir.declIterator(match_item.old_inst);
3382 while (old_decl_it.next()) |old_decl_inst| {
3383 const old_decl = old_zir.getDeclaration(old_decl_inst);
3384 switch (old_decl.kind) {
3385 .@"comptime" => try comptime_decls.append(gpa, old_decl_inst),
3386 .unnamed_test => try unnamed_tests.append(gpa, old_decl_inst),
3387 .@"test" => try named_tests.put(gpa, old_zir.nullTerminatedString(old_decl.name), old_decl_inst),
3388 .decltest => try named_decltests.put(gpa, old_zir.nullTerminatedString(old_decl.name), old_decl_inst),
3389 .@"const", .@"var" => try named_decls.put(gpa, old_zir.nullTerminatedString(old_decl.name), old_decl_inst),
3390 }
3479 for (old_zir.typeDecls(match_item.old_inst)) |old_decl_inst| {
3480 const old_decl = old_zir.getDeclaration(old_decl_inst);
3481 switch (old_decl.kind) {
3482 .@"comptime" => try comptime_decls.append(gpa, old_decl_inst),
3483 .unnamed_test => try unnamed_tests.append(gpa, old_decl_inst),
3484 .@"test" => try named_tests.put(gpa, old_zir.nullTerminatedString(old_decl.name), old_decl_inst),
3485 .decltest => try named_decltests.put(gpa, old_zir.nullTerminatedString(old_decl.name), old_decl_inst),
3486 .@"const", .@"var" => try named_decls.put(gpa, old_zir.nullTerminatedString(old_decl.name), old_decl_inst),
33913487 }
33923488 }
33933489
33943490 var unnamed_test_idx: u32 = 0;
33953491 var comptime_decl_idx: u32 = 0;
33963492
3397 var new_decl_it = new_zir.declIterator(match_item.new_inst);
3398 while (new_decl_it.next()) |new_decl_inst| {
3493 for (new_zir.typeDecls(match_item.new_inst)) |new_decl_inst| {
33993494 const new_decl = new_zir.getDeclaration(new_decl_inst);
34003495 // Attempt to match this to a declaration in the old ZIR:
34013496 // * For named declarations (`const`/`var`/`fn`), we match based on name.
......@@ -3474,47 +3569,93 @@ pub fn mapOldZirToNew(
34743569/// The caller is responsible for ensuring the function decl itself is already
34753570/// analyzed, and for ensuring it can exist at runtime (see
34763571/// `Type.fnHasRuntimeBitsSema`). This function does *not* guarantee that the body
3477/// will be analyzed when it returns: for that, see `ensureFuncBodyAnalyzed`.
3478pub fn ensureFuncBodyAnalysisQueued(zcu: *Zcu, func_index: InternPool.Index) !void {
3572/// will be analyzed when it returns: for that, see `PerThread.ensureFuncBodyUpToDate`.
3573pub fn ensureFuncBodyAnalysisQueued(zcu: *Zcu, func: InternPool.Index) !void {
3574 const comp = zcu.comp;
3575 const gpa = comp.gpa;
3576 const io = comp.io;
34793577 const ip = &zcu.intern_pool;
3578 assert(func == ip.unwrapCoercedFunc(func)); // analyze the body of the original function, not a coerced one
3579 if (ip.setWantRuntimeFnAnalysis(io, func)) {
3580 // This is the first reference to this function, so we must ensure it will be analyzed.
3581 if (std.debug.runtime_safety) zcu.outdated_lock.lockUncancelable(zcu.comp.io);
3582 defer if (std.debug.runtime_safety) zcu.outdated_lock.unlock(zcu.comp.io);
3583 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
3584 try zcu.outdated_ready.funcs.ensureUnusedCapacity(gpa, 1);
3585 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .func = func }), 0);
3586 zcu.outdated_ready.funcs.putAssumeCapacityNoClobber(func, {});
3587 }
3588}
34803589
3481 const func = zcu.funcInfo(func_index);
3482
3483 assert(func.ty == func.uncoerced_ty); // analyze the body of the original function, not a coerced one
3590pub fn ensureNavValAnalysisQueued(zcu: *Zcu, nav: InternPool.Nav.Index) !void {
3591 const comp = zcu.comp;
3592 const gpa = comp.gpa;
3593 const io = comp.io;
3594 const ip = &zcu.intern_pool;
3595 if (ip.setWantNavAnalysis(io, nav)) {
3596 // This is the first reference to this function, so we must ensure it will be analyzed.
3597 if (std.debug.runtime_safety) zcu.outdated_lock.lockUncancelable(zcu.comp.io);
3598 defer if (std.debug.runtime_safety) zcu.outdated_lock.unlock(zcu.comp.io);
3599 try zcu.outdated.ensureUnusedCapacity(gpa, 2);
3600 try zcu.outdated_ready.other.ensureUnusedCapacity(gpa, 2);
3601 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .nav_val = nav }), 0);
3602 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .nav_ty = nav }), 0);
3603 zcu.outdated_ready.other.putAssumeCapacityNoClobber(.wrap(.{ .nav_val = nav }), {});
3604 zcu.outdated_ready.other.putAssumeCapacityNoClobber(.wrap(.{ .nav_ty = nav }), {});
3605 }
3606}
34843607
3485 if (zcu.func_body_analysis_queued.contains(func_index)) return;
3608/// Called when an `InternPool.ComptimeUnit` is first created to mark it as outdated so that it will
3609/// be semantically analyzed.
3610pub fn queueComptimeUnitAnalysis(zcu: *Zcu, cu: InternPool.ComptimeUnit.Id) Allocator.Error!void {
3611 const comp = zcu.comp;
3612 const gpa = comp.gpa;
3613 const io = comp.io;
3614 const unit: AnalUnit = .wrap(.{ .@"comptime" = cu });
3615 if (std.debug.runtime_safety) zcu.outdated_lock.lockUncancelable(io);
3616 defer if (std.debug.runtime_safety) zcu.outdated_lock.unlock(io);
3617 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
3618 try zcu.outdated_ready.other.ensureUnusedCapacity(gpa, 1);
3619 zcu.outdated.putAssumeCapacityNoClobber(unit, 0);
3620 zcu.outdated_ready.other.putAssumeCapacityNoClobber(unit, {});
3621}
34863622
3487 if (func.analysisUnordered(ip).is_analyzed) {
3488 if (!zcu.outdated.contains(.wrap(.{ .func = func_index })) and
3489 !zcu.potentially_outdated.contains(.wrap(.{ .func = func_index })))
3490 {
3491 // This function has been analyzed before and is definitely up-to-date.
3492 return;
3623/// If `unit` was marked as outdated or porentially outdated, clears that status and returns `true`.
3624/// Otherwise, returns `false`.
3625pub fn clearOutdatedState(zcu: *Zcu, unit: AnalUnit) bool {
3626 const io = zcu.comp.io;
3627 if (std.debug.runtime_safety) zcu.outdated_lock.lockUncancelable(io);
3628 defer if (std.debug.runtime_safety) zcu.outdated_lock.unlock(io);
3629 if (zcu.outdated.fetchSwapRemove(unit)) |kv| {
3630 const was_ready = switch (unit.unwrap()) {
3631 .func => |func| zcu.outdated_ready.funcs.swapRemove(func),
3632 else => zcu.outdated_ready.other.swapRemove(unit),
3633 };
3634 if (kv.value == 0) {
3635 assert(was_ready);
3636 } else {
3637 assert(!was_ready);
34933638 }
3639 return true;
3640 } else if (zcu.potentially_outdated.swapRemove(unit)) {
3641 return true;
3642 } else {
3643 return false;
34943644 }
3495
3496 try zcu.func_body_analysis_queued.ensureUnusedCapacity(zcu.gpa, 1);
3497 try zcu.comp.queueJob(.{ .analyze_func = func_index });
3498 zcu.func_body_analysis_queued.putAssumeCapacityNoClobber(func_index, {});
34993645}
35003646
3501pub fn ensureNavValAnalysisQueued(zcu: *Zcu, nav_id: InternPool.Nav.Index) !void {
3502 const ip = &zcu.intern_pool;
3647/// This function takes a `*const Zcu` and `@constCast`s it so that it can be called from functions
3648/// in `Type` which otherwise do not modify the `Zcu`.
3649pub fn assertUpToDate(zcu: *const Zcu, unit: AnalUnit) void {
3650 if (!std.debug.runtime_safety) return;
35033651
3504 if (zcu.nav_val_analysis_queued.contains(nav_id)) return;
3652 const io = zcu.comp.io;
35053653
3506 if (ip.getNav(nav_id).status == .fully_resolved) {
3507 if (!zcu.outdated.contains(.wrap(.{ .nav_val = nav_id })) and
3508 !zcu.potentially_outdated.contains(.wrap(.{ .nav_val = nav_id })))
3509 {
3510 // This `Nav` has been analyzed before and is definitely up-to-date.
3511 return;
3512 }
3513 }
3654 @constCast(zcu).outdated_lock.lockSharedUncancelable(io);
3655 defer @constCast(zcu).outdated_lock.unlockShared(io);
35143656
3515 try zcu.nav_val_analysis_queued.ensureUnusedCapacity(zcu.gpa, 1);
3516 try zcu.comp.queueJob(.{ .analyze_comptime_unit = .wrap(.{ .nav_val = nav_id }) });
3517 zcu.nav_val_analysis_queued.putAssumeCapacityNoClobber(nav_id, {});
3657 assert(!zcu.outdated.contains(unit));
3658 assert(!zcu.potentially_outdated.contains(unit));
35183659}
35193660
35203661pub const ImportResult = struct {
......@@ -3533,56 +3674,83 @@ pub const ImportResult = struct {
35333674 module: ?*Package.Module,
35343675};
35353676
3536/// Delete all the Export objects that are caused by this `AnalUnit`. Re-analysis of
3537/// this `AnalUnit` will cause them to be re-created (or not).
3538pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void {
3539 const gpa = zcu.gpa;
3677/// Prepares `unit` for re-analysis by clearing all of the following state:
3678/// * Compile errors associated with `unit`
3679/// * Compile logs associated with `unit`
3680/// * Exports performed by `unit`
3681/// * Dependencies from `unit` on other things
3682/// * References from `unit` to other units
3683/// Delete all references in `reference_table` which are caused by `unit`, and all dependencies it
3684/// has. Called in preparation for re-analysis, which will recreate references and dependencies.
3685/// Re-analysis of the `AnalUnit` will cause appropriate references to be recreated.
3686pub fn resetUnit(zcu: *Zcu, unit: AnalUnit) void {
3687 const gpa = zcu.comp.gpa;
35403688
3541 const exports_base, const exports_len = if (zcu.single_exports.fetchSwapRemove(anal_unit)) |kv|
3542 .{ @intFromEnum(kv.value), 1 }
3543 else if (zcu.multi_exports.fetchSwapRemove(anal_unit)) |info|
3544 .{ info.value.index, info.value.len }
3545 else
3689 if (!dev.env.supports(.incremental)) {
3690 // This is the first time `unit` is being analyzed, so there is no stale data to clear.
35463691 return;
3692 }
35473693
3548 const exports = zcu.all_exports.items[exports_base..][0..exports_len];
3694 // Compile errors
3695 if (zcu.failed_analysis.fetchSwapRemove(unit)) |kv| {
3696 kv.value.destroy(gpa);
3697 } else if (zcu.dependency_loop_nodes.swapRemove(unit)) {
3698 _ = zcu.dependency_loops.swapRemove(unit);
3699 _ = zcu.transitive_failed_analysis.swapRemove(unit);
3700 } else {
3701 _ = zcu.transitive_failed_analysis.swapRemove(unit);
3702 }
35493703
3550 // In an only-c build, we're guaranteed to never use incremental compilation, so there are
3551 // guaranteed not to be any exports in the output file that need deleting (since we only call
3552 // `updateExports` on flush).
3553 // This case is needed because in some rare edge cases, `Sema` wants to add and delete exports
3554 // within a single update.
3555 if (dev.env.supports(.incremental)) {
3556 for (exports, exports_base..) |exp, export_index_usize| {
3557 const export_idx: Export.Index = @enumFromInt(export_index_usize);
3704 // Compile logs
3705 if (zcu.compile_logs.fetchSwapRemove(unit)) |kv| {
3706 var opt_line_idx = kv.value.first_line.toOptional();
3707 while (opt_line_idx.unwrap()) |line_idx| {
3708 zcu.free_compile_log_lines.append(gpa, line_idx) catch {
3709 // This space will be reused eventually, so we need not propagate this error.
3710 // Just leak it for now, and let GC reclaim it later on.
3711 break;
3712 };
3713 opt_line_idx = line_idx.get(zcu).next;
3714 }
3715 }
3716
3717 // Exports
3718 exports: {
3719 const base: u32, const len: u32 = index: {
3720 if (zcu.single_exports.fetchSwapRemove(unit)) |kv| {
3721 break :index .{ @intFromEnum(kv.value), 1 };
3722 }
3723 if (zcu.multi_exports.fetchSwapRemove(unit)) |kv| {
3724 break :index .{ kv.value.index, kv.value.len };
3725 }
3726 break :exports;
3727 };
3728 for (zcu.all_exports.items[base..][0..len], base..) |exp, exp_index_usize| {
3729 const exp_index: Export.Index = @enumFromInt(exp_index_usize);
35583730 if (zcu.comp.bin_file) |lf| {
35593731 lf.deleteExport(exp.exported, exp.opts.name);
35603732 }
3561 if (zcu.failed_exports.fetchSwapRemove(export_idx)) |failed_kv| {
3733 if (zcu.failed_exports.fetchSwapRemove(exp_index)) |failed_kv| {
35623734 failed_kv.value.destroy(gpa);
35633735 }
35643736 }
3737 zcu.free_exports.ensureUnusedCapacity(gpa, len) catch {
3738 // This space will be reused eventually, so we need not propagate this error.
3739 // Just leak it for now, and let GC reclaim it later on.
3740 break :exports;
3741 };
3742 for (base..base + len) |exp_index| {
3743 zcu.free_exports.appendAssumeCapacity(@enumFromInt(exp_index));
3744 }
35653745 }
35663746
3567 zcu.free_exports.ensureUnusedCapacity(gpa, exports_len) catch {
3568 // This space will be reused eventually, so we need not propagate this error.
3569 // Just leak it for now, and let GC reclaim it later on.
3570 return;
3571 };
3572 for (exports_base..exports_base + exports_len) |export_idx| {
3573 zcu.free_exports.appendAssumeCapacity(@enumFromInt(export_idx));
3574 }
3575}
3576
3577/// Delete all references in `reference_table` which are caused by this `AnalUnit`.
3578/// Re-analysis of the `AnalUnit` will cause appropriate references to be recreated.
3579pub fn deleteUnitReferences(zcu: *Zcu, anal_unit: AnalUnit) void {
3580 const gpa = zcu.gpa;
3747 // Dependencies
3748 zcu.intern_pool.removeDependenciesForDepender(gpa, unit);
35813749
3750 // References
35823751 zcu.clearCachedResolvedReferences();
3583
35843752 unit_refs: {
3585 const kv = zcu.reference_table.fetchSwapRemove(anal_unit) orelse break :unit_refs;
3753 const kv = zcu.reference_table.fetchSwapRemove(unit) orelse break :unit_refs;
35863754 var idx = kv.value;
35873755
35883756 while (idx != std.math.maxInt(u32)) {
......@@ -3610,9 +3778,8 @@ pub fn deleteUnitReferences(zcu: *Zcu, anal_unit: AnalUnit) void {
36103778 }
36113779 }
36123780 }
3613
36143781 type_refs: {
3615 const kv = zcu.type_reference_table.fetchSwapRemove(anal_unit) orelse break :type_refs;
3782 const kv = zcu.type_reference_table.fetchSwapRemove(unit) orelse break :type_refs;
36163783 var idx = kv.value;
36173784
36183785 while (idx != std.math.maxInt(u32)) {
......@@ -3626,22 +3793,6 @@ pub fn deleteUnitReferences(zcu: *Zcu, anal_unit: AnalUnit) void {
36263793 }
36273794}
36283795
3629/// Delete all compile logs performed by this `AnalUnit`.
3630/// Re-analysis of the `AnalUnit` will cause logs to be rediscovered.
3631pub fn deleteUnitCompileLogs(zcu: *Zcu, anal_unit: AnalUnit) void {
3632 const kv = zcu.compile_logs.fetchSwapRemove(anal_unit) orelse return;
3633 const gpa = zcu.gpa;
3634 var opt_line_idx = kv.value.first_line.toOptional();
3635 while (opt_line_idx.unwrap()) |line_idx| {
3636 zcu.free_compile_log_lines.append(gpa, line_idx) catch {
3637 // This space will be reused eventually, so we need not propagate this error.
3638 // Just leak it for now, and let GC reclaim it later on.
3639 return;
3640 };
3641 opt_line_idx = line_idx.get(zcu).next;
3642 }
3643}
3644
36453796pub fn addInlineReferenceFrame(zcu: *Zcu, frame: InlineReferenceFrame) Allocator.Error!Zcu.InlineReferenceFrame.Index {
36463797 const frame_idx: InlineReferenceFrame.Index = zcu.free_inline_reference_frames.pop() orelse idx: {
36473798 _ = try zcu.inline_reference_frames.addOne(zcu.gpa);
......@@ -3851,9 +4002,9 @@ pub const AtomicPtrAlignmentDiagnostics = struct {
38514002 max_bits: u16 = undefined,
38524003};
38534004
3854/// If ABI alignment of `ty` is OK for atomic operations, returns 0.
3855/// Otherwise returns the alignment required on a pointer for the target
3856/// to perform atomic operations.
4005/// Returns the alignment required for the target to perform atomic operations on type `ty` (that
4006/// is, the required align attribute on the pointer). If the ABI alignment of `ty` is sufficient,
4007/// returns `.none`.
38574008// TODO this function does not take into account CPU features, which can affect
38584009// this value. Audit this!
38594010pub fn atomicPtrAlignment(
......@@ -3908,8 +4059,7 @@ pub fn atomicPtrAlignment(
39084059 return error.BadType;
39094060}
39104061
3911/// Returns null in the following cases:
3912/// * Not a struct.
4062/// Returns null if `ty` is not a struct.
39134063pub fn typeToStruct(zcu: *const Zcu, ty: Type) ?InternPool.LoadedStructType {
39144064 if (ty.ip_index == .none) return null;
39154065 const ip = &zcu.intern_pool;
......@@ -3936,7 +4086,6 @@ pub fn structPackedFieldBitOffset(
39364086) u16 {
39374087 const ip = &zcu.intern_pool;
39384088 assert(struct_type.layout == .@"packed");
3939 assert(struct_type.haveLayout(ip));
39404089 var bit_sum: u64 = 0;
39414090 for (0..struct_type.field_types.len) |i| {
39424091 if (i == field_index) {
......@@ -3995,8 +4144,10 @@ pub const UnionLayout = struct {
39954144pub fn unionTagFieldIndex(zcu: *const Zcu, loaded_union: InternPool.LoadedUnionType, enum_tag: Value) ?u32 {
39964145 const ip = &zcu.intern_pool;
39974146 if (enum_tag.toIntern() == .none) return null;
3998 assert(ip.typeOf(enum_tag.toIntern()) == loaded_union.enum_tag_ty);
3999 return loaded_union.loadTagType(ip).tagValueIndex(ip, enum_tag.toIntern());
4147 const enum_tag_key = ip.indexToKey(enum_tag.toIntern()).enum_tag;
4148 assert(enum_tag_key.ty == loaded_union.enum_tag_type);
4149 const loaded_enum = ip.loadEnumType(loaded_union.enum_tag_type);
4150 return loaded_enum.tagValueIndex(ip, enum_tag_key.int);
40004151}
40014152
40024153pub const ResolvedReference = struct {
......@@ -4012,13 +4163,13 @@ pub const ResolvedReference = struct {
40124163/// If an `AnalUnit` is not in the returned map, it is unreferenced.
40134164/// The returned hashmap is owned by the `Zcu`, so should not be freed by the caller.
40144165/// This hashmap is cached, so repeated calls to this function are cheap.
4015pub fn resolveReferences(zcu: *Zcu) !*const std.AutoArrayHashMapUnmanaged(AnalUnit, ?ResolvedReference) {
4166pub fn resolveReferences(zcu: *Zcu) Allocator.Error!*const std.AutoArrayHashMapUnmanaged(AnalUnit, ?ResolvedReference) {
40164167 if (zcu.resolved_references == null) {
40174168 zcu.resolved_references = try zcu.resolveReferencesInner();
40184169 }
40194170 return &zcu.resolved_references.?;
40204171}
4021fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?ResolvedReference) {
4172fn resolveReferencesInner(zcu: *Zcu) Allocator.Error!std.AutoArrayHashMapUnmanaged(AnalUnit, ?ResolvedReference) {
40224173 const gpa = zcu.gpa;
40234174 const comp = zcu.comp;
40244175 const ip = &zcu.intern_pool;
......@@ -4049,32 +4200,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
40494200 const referencer = types.values()[type_idx];
40504201 type_idx += 1;
40514202
4052 log.debug("handle type '{f}'", .{Type.fromInterned(ty).containerTypeName(ip).fmt(ip)});
4053
4054 // If this type undergoes type resolution, the corresponding `AnalUnit` is automatically referenced.
4055 const has_resolution: bool = switch (ip.indexToKey(ty)) {
4056 .struct_type, .union_type => true,
4057 .enum_type => |k| k != .generated_tag,
4058 .opaque_type => false,
4059 else => unreachable,
4060 };
4061 if (has_resolution) {
4062 // this should only be referenced by the type
4063 const unit: AnalUnit = .wrap(.{ .type = ty });
4064 try units.putNoClobber(gpa, unit, referencer);
4065 }
4066
4067 // If this is a union with a generated tag, its tag type is automatically referenced.
4068 // We don't add this reference for non-generated tags, as those will already be referenced via the union's type resolution, with a better source location.
4069 if (zcu.typeToUnion(Type.fromInterned(ty))) |union_obj| {
4070 const tag_ty = union_obj.enum_tag_ty;
4071 if (tag_ty != .none) {
4072 if (ip.indexToKey(tag_ty).enum_type == .generated_tag) {
4073 const gop = try types.getOrPut(gpa, tag_ty);
4074 if (!gop.found_existing) gop.value_ptr.* = referencer;
4075 }
4076 }
4077 }
4203 refs_log.debug("handle type '{f}'", .{Type.fromInterned(ty).containerTypeName(ip).fmt(ip)});
40784204
40794205 // Queue any decls within this type which would be automatically analyzed.
40804206 // Keep in sync with analysis queueing logic in `Zcu.PerThread.ScanDeclIter.scanDecl`.
......@@ -4084,7 +4210,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
40844210 const unit: AnalUnit = .wrap(.{ .@"comptime" = cu });
40854211 const gop = try units.getOrPut(gpa, unit);
40864212 if (!gop.found_existing) {
4087 log.debug("type '{f}': ref comptime %{}", .{
4213 refs_log.debug("type '{f}': ref comptime %{}", .{
40884214 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
40894215 @intFromEnum(ip.getComptimeUnit(cu).zir_index.resolve(ip) orelse continue),
40904216 });
......@@ -4118,7 +4244,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
41184244 {
41194245 const gop = try units.getOrPut(gpa, .wrap(.{ .nav_val = nav_id }));
41204246 if (!gop.found_existing) {
4121 log.debug("type '{f}': ref test %{}", .{
4247 refs_log.debug("type '{f}': ref test %{}", .{
41224248 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
41234249 @intFromEnum(inst_info.inst),
41244250 });
......@@ -4141,7 +4267,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
41414267 const unit: AnalUnit = .wrap(.{ .nav_val = nav });
41424268 const gop = try units.getOrPut(gpa, unit);
41434269 if (!gop.found_existing) {
4144 log.debug("type '{f}': ref named %{}", .{
4270 refs_log.debug("type '{f}': ref named %{}", .{
41454271 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
41464272 @intFromEnum(inst_info.inst),
41474273 });
......@@ -4158,7 +4284,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
41584284 const unit: AnalUnit = .wrap(.{ .nav_val = nav });
41594285 const gop = try units.getOrPut(gpa, unit);
41604286 if (!gop.found_existing) {
4161 log.debug("type '{f}': ref named %{}", .{
4287 refs_log.debug("type '{f}': ref named %{}", .{
41624288 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
41634289 @intFromEnum(inst_info.inst),
41644290 });
......@@ -4173,18 +4299,25 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
41734299 unit_idx += 1;
41744300
41754301 // `nav_val` and `nav_ty` reference each other *implicitly* to save memory.
4302 // Likewise for `type_layout` and `struct_defaults` of a struct type.
41764303 queue_paired: {
41774304 const other: AnalUnit = .wrap(switch (unit.unwrap()) {
41784305 .nav_val => |n| .{ .nav_ty = n },
41794306 .nav_ty => |n| .{ .nav_val = n },
4180 .@"comptime", .type, .func, .memoized_state => break :queue_paired,
4307 .struct_defaults => |ty| .{ .type_layout = ty },
4308 .type_layout => |ty| switch (ip.indexToKey(ty)) {
4309 .struct_type => .{ .struct_defaults = ty },
4310 .union_type, .enum_type, .opaque_type => break :queue_paired,
4311 else => unreachable,
4312 },
4313 .@"comptime", .func, .memoized_state => break :queue_paired,
41814314 });
41824315 const gop = try units.getOrPut(gpa, other);
41834316 if (gop.found_existing) break :queue_paired;
4184 gop.value_ptr.* = units.values()[unit_idx]; // same reference location
4317 gop.value_ptr.* = units.values()[unit_idx - 1]; // same reference location
41854318 }
41864319
4187 log.debug("handle unit '{f}'", .{zcu.fmtAnalUnit(unit)});
4320 refs_log.debug("handle unit '{f}'", .{zcu.fmtAnalUnit(unit)});
41884321
41894322 if (zcu.reference_table.get(unit)) |first_ref_idx| {
41904323 assert(first_ref_idx != std.math.maxInt(u32));
......@@ -4193,7 +4326,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
41934326 const ref = zcu.all_references.items[ref_idx];
41944327 const gop = try units.getOrPut(gpa, ref.referenced);
41954328 if (!gop.found_existing) {
4196 log.debug("unit '{f}': ref unit '{f}'", .{
4329 refs_log.debug("unit '{f}': ref unit '{f}'", .{
41974330 zcu.fmtAnalUnit(unit),
41984331 zcu.fmtAnalUnit(ref.referenced),
41994332 });
......@@ -4213,7 +4346,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoArrayHashMapUnmanaged(AnalUnit, ?R
42134346 const ref = zcu.all_type_references.items[ref_idx];
42144347 const gop = try types.getOrPut(gpa, ref.referenced);
42154348 if (!gop.found_existing) {
4216 log.debug("unit '{f}': ref type '{f}'", .{
4349 refs_log.debug("unit '{f}': ref type '{f}'", .{
42174350 zcu.fmtAnalUnit(unit),
42184351 Type.fromInterned(ref.referenced).containerTypeName(ip).fmt(ip),
42194352 });
......@@ -4298,6 +4431,16 @@ pub fn navFileScope(zcu: *Zcu, nav: InternPool.Nav.Index) *File {
42984431 return zcu.fileByIndex(zcu.navFileScopeIndex(nav));
42994432}
43004433
4434pub fn navAlignment(zcu: *Zcu, nav_index: InternPool.Nav.Index) InternPool.Alignment {
4435 const ty: Type, const alignment = switch (zcu.intern_pool.getNav(nav_index).status) {
4436 .unresolved => unreachable,
4437 .type_resolved => |r| .{ .fromInterned(r.type), r.alignment },
4438 .fully_resolved => |r| .{ Value.fromInterned(r.val).typeOf(zcu), r.alignment },
4439 };
4440 if (alignment != .none) return alignment;
4441 return ty.abiAlignment(zcu);
4442}
4443
43014444pub fn fmtAnalUnit(zcu: *Zcu, unit: AnalUnit) std.fmt.Alt(FormatAnalUnit, formatAnalUnit) {
43024445 return .{ .data = .{ .unit = unit, .zcu = zcu } };
43034446}
......@@ -4305,11 +4448,7 @@ pub fn fmtDependee(zcu: *Zcu, d: InternPool.Dependee) std.fmt.Alt(FormatDependee
43054448 return .{ .data = .{ .dependee = d, .zcu = zcu } };
43064449}
43074450
4308const FormatAnalUnit = struct {
4309 unit: AnalUnit,
4310 zcu: *Zcu,
4311};
4312
4451const FormatAnalUnit = struct { unit: AnalUnit, zcu: *const Zcu };
43134452fn formatAnalUnit(data: FormatAnalUnit, writer: *Io.Writer) Io.Writer.Error!void {
43144453 const zcu = data.zcu;
43154454 const ip = &zcu.intern_pool;
......@@ -4323,9 +4462,8 @@ fn formatAnalUnit(data: FormatAnalUnit, writer: *Io.Writer) Io.Writer.Error!void
43234462 return writer.print("comptime(inst=<lost> [{}])", .{@intFromEnum(cu_id)});
43244463 }
43254464 },
4326 .nav_val => |nav| return writer.print("nav_val('{f}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(nav) }),
4327 .nav_ty => |nav| return writer.print("nav_ty('{f}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(nav) }),
4328 .type => |ty| return writer.print("ty('{f}' [{}])", .{ Type.fromInterned(ty).containerTypeName(ip).fmt(ip), @intFromEnum(ty) }),
4465 .nav_val, .nav_ty => |nav, tag| return writer.print("{t}('{f}' [{}])", .{ tag, ip.getNav(nav).fqn.fmt(ip), @intFromEnum(nav) }),
4466 .type_layout, .struct_defaults => |ty, tag| return writer.print("{t}('{f}' [{}])", .{ tag, Type.fromInterned(ty).containerTypeName(ip).fmt(ip), @intFromEnum(ty) }),
43294467 .func => |func| {
43304468 const nav = zcu.funcInfo(func).owner_nav;
43314469 return writer.print("func('{f}' [{}])", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(func) });
......@@ -4334,8 +4472,7 @@ fn formatAnalUnit(data: FormatAnalUnit, writer: *Io.Writer) Io.Writer.Error!void
43344472 }
43354473}
43364474
4337const FormatDependee = struct { dependee: InternPool.Dependee, zcu: *Zcu };
4338
4475const FormatDependee = struct { dependee: InternPool.Dependee, zcu: *const Zcu };
43394476fn formatDependee(data: FormatDependee, writer: *Io.Writer) Io.Writer.Error!void {
43404477 const zcu = data.zcu;
43414478 const ip = &zcu.intern_pool;
......@@ -4347,18 +4484,17 @@ fn formatDependee(data: FormatDependee, writer: *Io.Writer) Io.Writer.Error!void
43474484 const file_path = zcu.fileByIndex(info.file).path;
43484485 return writer.print("inst('{f}', %{d})", .{ file_path.fmt(zcu.comp), @intFromEnum(info.inst) });
43494486 },
4350 .nav_val => |nav| {
4487 .nav_val, .nav_ty => |nav, tag| {
43514488 const fqn = ip.getNav(nav).fqn;
4352 return writer.print("nav_val('{f}')", .{fqn.fmt(ip)});
4489 return writer.print("{t}('{f}')", .{ tag, fqn.fmt(ip) });
43534490 },
4354 .nav_ty => |nav| {
4355 const fqn = ip.getNav(nav).fqn;
4356 return writer.print("nav_ty('{f}')", .{fqn.fmt(ip)});
4491 .type_layout, .struct_defaults => |ip_index, tag| {
4492 const name = Type.fromInterned(ip_index).containerTypeName(ip);
4493 return writer.print("{t}('{f}')", .{ tag, name.fmt(ip) });
43574494 },
4358 .interned => |ip_index| switch (ip.indexToKey(ip_index)) {
4359 .struct_type, .union_type, .enum_type => return writer.print("type('{f}')", .{Type.fromInterned(ip_index).containerTypeName(ip).fmt(ip)}),
4360 .func => |f| return writer.print("ies('{f}')", .{ip.getNav(f.owner_nav).fqn.fmt(ip)}),
4361 else => unreachable,
4495 .func_ies => |ip_index| {
4496 const fqn = ip.getNav(ip.indexToKey(ip_index).func.owner_nav).fqn;
4497 return writer.print("func_ies('{f}')", .{fqn.fmt(ip)});
43624498 },
43634499 .zon_file => |file| {
43644500 const file_path = zcu.fileByIndex(file).path;
......@@ -4386,32 +4522,6 @@ fn formatDependee(data: FormatDependee, writer: *Io.Writer) Io.Writer.Error!void
43864522 }
43874523}
43884524
4389/// Given the `InternPool.Index` of a function, set its resolved IES to `.none` if it
4390/// may be outdated. `Sema` should do this before ever loading a resolved IES.
4391pub fn maybeUnresolveIes(zcu: *Zcu, func_index: InternPool.Index) !void {
4392 const unit = AnalUnit.wrap(.{ .func = func_index });
4393 if (zcu.outdated.contains(unit) or zcu.potentially_outdated.contains(unit)) {
4394 // We're consulting the resolved IES now, but the function is outdated, so its
4395 // IES may have changed. We have to assume the IES is outdated and set the resolved
4396 // set back to `.none`.
4397 //
4398 // This will cause `PerThread.analyzeFnBody` to mark the IES as outdated when it's
4399 // eventually hit.
4400 //
4401 // Since the IES needs to be resolved, the function body will now definitely need
4402 // re-analysis (even if the IES turns out to be the same!), so mark it as
4403 // definitely-outdated if it's only PO.
4404 if (zcu.potentially_outdated.fetchSwapRemove(unit)) |kv| {
4405 const gpa = zcu.gpa;
4406 try zcu.outdated.putNoClobber(gpa, unit, kv.value);
4407 if (kv.value == 0) {
4408 try zcu.outdated_ready.put(gpa, unit, {});
4409 }
4410 }
4411 zcu.intern_pool.funcSetIesResolved(zcu.comp.io, func_index, .none);
4412 }
4413}
4414
44154525pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enum) {
44164526 ok,
44174527 bad_arch: []const std.Target.Cpu.Arch, // value is allowed archs for cc
......@@ -4747,6 +4857,304 @@ fn explainWhyFileIsInModule(
47474857 }
47484858}
47494859
4860pub fn addDependencyLoopErrors(zcu: *Zcu, eb: *std.zig.ErrorBundle.Wip) Allocator.Error!void {
4861 const gpa = zcu.comp.gpa;
4862
4863 const all_references = try zcu.resolveReferences();
4864
4865 var units: std.ArrayList(AnalUnit) = .empty;
4866 defer units.deinit(gpa);
4867
4868 // TODO: sort the dependency loops somehow to make the error bundle reproducible
4869 for (zcu.dependency_loops.keys()) |arbitrary_unit| {
4870 units.clearRetainingCapacity();
4871
4872 var cur = arbitrary_unit;
4873 while (true) {
4874 try units.append(gpa, cur);
4875 cur = zcu.dependency_loop_nodes.get(cur).?.unit;
4876 if (cur == arbitrary_unit) break;
4877 }
4878
4879 // `units` now contains all units in the loop. We need to pick a starting point somewhere
4880 // along that loop to begin. We will pick whichever node has the shortest reference trace,
4881 // because the other units may well just be referenced *by* that one! This is also likely
4882 // to match the user's intuition for where the loop "starts".
4883 var start_index: usize = 0;
4884 var start_depth: u32 = depth: {
4885 var depth: u32 = 0;
4886 var opt_ref = all_references.get(units.items[0]) orelse {
4887 // This dependency loop is actually unreferenced, so we don't need to emit a compile
4888 // error at all! Move onto the next dependency loop.
4889 continue;
4890 };
4891 while (opt_ref) |ref| : (opt_ref = all_references.get(ref.referencer).?) depth += 1;
4892 break :depth depth;
4893 };
4894 for (units.items[1..], 1..) |unit, index| {
4895 var depth: u32 = 0;
4896 var opt_ref = all_references.get(unit).?;
4897 while (opt_ref) |ref| : (opt_ref = all_references.get(ref.referencer).?) depth += 1;
4898 if (depth < start_depth) {
4899 start_index = index;
4900 start_depth = depth;
4901 }
4902 }
4903
4904 // Collect a reference trace for the start of the loop.
4905 var ref_trace: std.ArrayList(std.zig.ErrorBundle.ReferenceTrace) = .empty;
4906 defer ref_trace.deinit(gpa);
4907 const frame_limit = zcu.comp.reference_trace orelse 0;
4908 try zcu.populateReferenceTrace(units.items[start_index], frame_limit, eb, &ref_trace);
4909
4910 if (units.items.len == 1) {
4911 // Don't do a complicated message with multiple notes, just do a single error message.
4912 assert(start_index == 0);
4913 const root_msg = addDependencyLoopErrorLine(zcu, eb, units.items[start_index], ref_trace.items) catch |err| switch (err) {
4914 error.AlreadyReported => return, // give up on the dep loop error
4915 error.OutOfMemory => |e| return e,
4916 };
4917 try eb.root_list.append(eb.gpa, root_msg);
4918 continue;
4919 }
4920
4921 // Collect all notes first so we don't leave an incomplete root error message on `error.AlreadyReported`.
4922 const note_buf = try gpa.alloc(std.zig.ErrorBundle.MessageIndex, units.items.len + 1);
4923 defer gpa.free(note_buf);
4924 note_buf[0] = addDependencyLoopErrorLine(zcu, eb, units.items[start_index], ref_trace.items) catch |err| switch (err) {
4925 error.AlreadyReported => return, // give up on the dep loop error
4926 error.OutOfMemory => |e| return e,
4927 };
4928 for (units.items[start_index + 1 ..], note_buf[1 .. units.items.len - start_index]) |unit, *note| {
4929 note.* = addDependencyLoopErrorLine(zcu, eb, unit, &.{}) catch |err| switch (err) {
4930 error.AlreadyReported => return, // give up on the dep loop error
4931 error.OutOfMemory => |e| return e,
4932 };
4933 }
4934 for (units.items[0..start_index], note_buf[units.items.len - start_index .. units.items.len]) |unit, *note| {
4935 note.* = addDependencyLoopErrorLine(zcu, eb, unit, &.{}) catch |err| switch (err) {
4936 error.AlreadyReported => return, // give up on the dep loop error
4937 error.OutOfMemory => |e| return e,
4938 };
4939 }
4940 note_buf[units.items.len] = try eb.addErrorMessage(.{
4941 .msg = try eb.addString("eliminate any one of these dependencies to break the loop"),
4942 .src_loc = .none,
4943 });
4944
4945 try eb.addRootErrorMessage(.{
4946 .msg = try eb.printString("dependency loop with length {d}", .{units.items.len}),
4947 .src_loc = .none,
4948 .notes_len = @intCast(units.items.len + 1),
4949 });
4950 const notes_start = try eb.reserveNotes(@intCast(units.items.len + 1));
4951 const notes: []std.zig.ErrorBundle.MessageIndex = @ptrCast(eb.extra.items[notes_start..]);
4952 @memcpy(notes, note_buf);
4953 }
4954}
4955fn addDependencyLoopErrorLine(
4956 zcu: *Zcu,
4957 eb: *std.zig.ErrorBundle.Wip,
4958 source_unit: AnalUnit,
4959 ref_trace: []const std.zig.ErrorBundle.ReferenceTrace,
4960) (Allocator.Error || error{AlreadyReported})!std.zig.ErrorBundle.MessageIndex {
4961 const ip = &zcu.intern_pool;
4962 const comp = zcu.comp;
4963
4964 const fmt_source: std.fmt.Alt(FormatAnalUnit, formatDependencyLoopSourceUnit) = .{ .data = .{
4965 .unit = source_unit,
4966 .zcu = zcu,
4967 } };
4968
4969 const dep_node = zcu.dependency_loop_nodes.get(source_unit).?;
4970
4971 const msg: std.zig.ErrorBundle.String = if (dep_node.unit == source_unit) switch (source_unit.unwrap()) {
4972 .@"comptime" => unreachable, // cannot be involved in a dependency loop
4973 .nav_ty, .nav_val => try eb.printString("{f} depends on itself here", .{fmt_source}),
4974 .memoized_state => unreachable, // memoized_state definitely does not *directly* depend on itself
4975 .func => try eb.printString("{f} uses its own inferred error set here", .{fmt_source}),
4976 .type_layout => try eb.printString("{f} depends on itself {s}", .{
4977 fmt_source,
4978 dep_node.reason.type_layout_reason.msg(),
4979 }),
4980 .struct_defaults => |ty| try eb.printString(
4981 "default field values of '{f}' depend on themselves for initialization here",
4982 .{Type.fromInterned(ty).containerTypeName(ip).fmt(ip)},
4983 ),
4984 } else switch (dep_node.unit.unwrap()) {
4985 .@"comptime" => unreachable, // cannot be involved in a dependency loop
4986 .nav_val => |nav| try eb.printString("{f} uses value of declaration '{f}' here", .{
4987 fmt_source, ip.getNav(nav).fqn.fmt(ip),
4988 }),
4989 .nav_ty => |nav| try eb.printString("{f} uses type of declaration '{f}' here", .{
4990 fmt_source, ip.getNav(nav).fqn.fmt(ip),
4991 }),
4992 .memoized_state => |stage| switch (stage) {
4993 .panic => try eb.printString("{f} requires panic handler for call here", .{fmt_source}),
4994 else => try eb.printString("{f} requires 'std.builtin' declarations here", .{fmt_source}),
4995 },
4996 .func => |func| try eb.printString("{f} uses inferred error set of function '{f}' here", .{
4997 fmt_source, ip.getNav(zcu.funcInfo(func).owner_nav).fqn.fmt(ip),
4998 }),
4999 .type_layout => |ty| try eb.printString("{f} depends on type '{f}' {s}", .{
5000 fmt_source,
5001 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
5002 dep_node.reason.type_layout_reason.msg(),
5003 }),
5004 .struct_defaults => |ty| try eb.printString(
5005 "{f} uses default field values of '{f}' here",
5006 .{ fmt_source, Type.fromInterned(ty).containerTypeName(ip).fmt(ip) },
5007 ),
5008 };
5009
5010 const src_loc = dep_node.reason.src.upgrade(zcu);
5011 const source = src_loc.file_scope.getSource(zcu) catch |err| {
5012 try Compilation.unableToLoadZcuFile(zcu, eb, src_loc.file_scope, err);
5013 return error.AlreadyReported;
5014 };
5015 const span = src_loc.span(zcu) catch |err| {
5016 try Compilation.unableToLoadZcuFile(zcu, eb, src_loc.file_scope, err);
5017 return error.AlreadyReported;
5018 };
5019 const loc = std.zig.findLineColumn(source, span.main);
5020 const eb_src = try eb.addSourceLocation(.{
5021 .src_path = try eb.printString("{f}", .{src_loc.file_scope.path.fmt(comp)}),
5022 .span_start = span.start,
5023 .span_main = span.main,
5024 .span_end = span.end,
5025 .line = @intCast(loc.line),
5026 .column = @intCast(loc.column),
5027 .source_line = try eb.addString(loc.source_line),
5028 .reference_trace_len = @intCast(ref_trace.len),
5029 });
5030 for (ref_trace) |rt| try eb.addReferenceTrace(rt);
5031 return eb.addErrorMessage(.{
5032 .msg = msg,
5033 .src_loc = eb_src,
5034 });
5035}
5036fn formatDependencyLoopSourceUnit(data: FormatAnalUnit, w: *Io.Writer) Io.Writer.Error!void {
5037 const zcu = data.zcu;
5038 const ip = &zcu.intern_pool;
5039 switch (data.unit.unwrap()) {
5040 .@"comptime" => unreachable, // cannot be involved in a dependency loop
5041 .nav_val => |nav| try w.print("value of declaration '{f}'", .{ip.getNav(nav).fqn.fmt(ip)}),
5042 .nav_ty => |nav| try w.print("type of declaration '{f}'", .{ip.getNav(nav).fqn.fmt(ip)}),
5043 .memoized_state => |stage| switch (stage) {
5044 .panic => try w.writeAll("panic handler"),
5045 else => try w.writeAll("'std.builtin' declarations"),
5046 },
5047 .type_layout => |ty| try w.print("type '{f}'", .{
5048 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
5049 }),
5050 .struct_defaults => |ty| try w.print("default field value of '{f}'", .{
5051 Type.fromInterned(ty).containerTypeName(ip).fmt(ip),
5052 }),
5053 .func => |func| try w.print("function '{f}'", .{
5054 ip.getNav(zcu.funcInfo(func).owner_nav).fqn.fmt(ip),
5055 }),
5056 }
5057}
5058
5059pub fn populateReferenceTrace(
5060 zcu: *Zcu,
5061 root: AnalUnit,
5062 frame_limit: u32,
5063 eb: *std.zig.ErrorBundle.Wip,
5064 ref_trace: *std.ArrayList(std.zig.ErrorBundle.ReferenceTrace),
5065) Allocator.Error!void {
5066 const ip = &zcu.intern_pool;
5067 const gpa = zcu.comp.gpa;
5068
5069 if (frame_limit == 0) return;
5070
5071 const all_references = try zcu.resolveReferences();
5072
5073 var seen: std.AutoHashMapUnmanaged(InternPool.AnalUnit, void) = .empty;
5074 defer seen.deinit(gpa);
5075
5076 var referenced_by = root;
5077 while (all_references.get(referenced_by)) |maybe_ref| {
5078 const ref = maybe_ref orelse break;
5079 const gop = try seen.getOrPut(gpa, ref.referencer);
5080 if (gop.found_existing) break;
5081 if (ref_trace.items.len < frame_limit) {
5082 var last_call_src = ref.src;
5083 var opt_inline_frame = ref.inline_frame;
5084 while (opt_inline_frame.unwrap()) |inline_frame| {
5085 const f = inline_frame.ptr(zcu).*;
5086 const func_nav = ip.indexToKey(f.callee).func.owner_nav;
5087 const func_name = ip.getNav(func_nav).name.toSlice(ip);
5088 addReferenceTraceFrame(zcu, eb, ref_trace, func_name, last_call_src, true) catch |err| switch (err) {
5089 error.OutOfMemory => |e| return e,
5090 error.AlreadyReported => {
5091 // An incomplete reference trace isn't the end of the world; just cut it off.
5092 return;
5093 },
5094 };
5095 last_call_src = f.call_src;
5096 opt_inline_frame = f.parent;
5097 }
5098 const root_name: ?[]const u8 = switch (ref.referencer.unwrap()) {
5099 .@"comptime" => "comptime",
5100 .nav_val, .nav_ty => |nav| ip.getNav(nav).name.toSlice(ip),
5101 .type_layout, .struct_defaults => |ty| Type.fromInterned(ty).containerTypeName(ip).toSlice(ip),
5102 .func => |f| ip.getNav(zcu.funcInfo(f).owner_nav).name.toSlice(ip),
5103 .memoized_state => null,
5104 };
5105 if (root_name) |n| {
5106 addReferenceTraceFrame(zcu, eb, ref_trace, n, last_call_src, false) catch |err| switch (err) {
5107 error.OutOfMemory => |e| return e,
5108 error.AlreadyReported => {
5109 // An incomplete reference trace isn't the end of the world; just cut it off.
5110 return;
5111 },
5112 };
5113 }
5114 }
5115 referenced_by = ref.referencer;
5116 }
5117
5118 if (seen.count() > ref_trace.items.len) {
5119 try ref_trace.append(gpa, .{
5120 .decl_name = @intCast(seen.count() - ref_trace.items.len),
5121 .src_loc = .none,
5122 });
5123 }
5124}
5125fn addReferenceTraceFrame(
5126 zcu: *Zcu,
5127 eb: *std.zig.ErrorBundle.Wip,
5128 ref_trace: *std.ArrayList(std.zig.ErrorBundle.ReferenceTrace),
5129 name: []const u8,
5130 lazy_src: Zcu.LazySrcLoc,
5131 inlined: bool,
5132) error{ OutOfMemory, AlreadyReported }!void {
5133 const gpa = zcu.gpa;
5134 const src = lazy_src.upgrade(zcu);
5135 const source = src.file_scope.getSource(zcu) catch |err| {
5136 try Compilation.unableToLoadZcuFile(zcu, eb, src.file_scope, err);
5137 return error.AlreadyReported;
5138 };
5139 const span = src.span(zcu) catch |err| {
5140 try Compilation.unableToLoadZcuFile(zcu, eb, src.file_scope, err);
5141 return error.AlreadyReported;
5142 };
5143 const loc = std.zig.findLineColumn(source, span.main);
5144 try ref_trace.append(gpa, .{
5145 .decl_name = try eb.printString("{s}{s}", .{ name, if (inlined) " [inlined]" else "" }),
5146 .src_loc = try eb.addSourceLocation(.{
5147 .src_path = try eb.printString("{f}", .{src.file_scope.path.fmt(zcu.comp)}),
5148 .span_start = span.start,
5149 .span_main = span.main,
5150 .span_end = span.end,
5151 .line = @intCast(loc.line),
5152 .column = @intCast(loc.column),
5153 .source_line = 0,
5154 }),
5155 });
5156}
5157
47505158const TrackedUnitSema = struct {
47515159 /// `null` means we created the node, so should end it.
47525160 old_name: ?[std.Progress.Node.max_name_len]u8,
src/Zcu/PerThread.zig+1060-1109
......@@ -27,7 +27,9 @@ const introspect = @import("../introspect.zig");
2727const Module = @import("../Package.zig").Module;
2828const Sema = @import("../Sema.zig");
2929const target_util = @import("../target.zig");
30const trace = @import("../tracy.zig").trace;
30const tracy = @import("../tracy.zig");
31const trace = tracy.trace;
32const traceNamed = tracy.traceNamed;
3133const Type = @import("../Type.zig");
3234const Value = @import("../Value.zig");
3335const Zcu = @import("../Zcu.zig");
......@@ -125,6 +127,329 @@ pub fn deactivate(pt: Zcu.PerThread) void {
125127 pt.zcu.intern_pool.deactivate();
126128}
127129
130/// Called from `Compilation.performAllTheWork`. Performs one incremental update of the ZCU: detects
131/// changes to files, runs AstGen, and then enters the main semantic analysis loop, where we build
132/// up a graph of declarations, functions, etc, while also sending declarations and functions to
133/// codegen as they are analyzed.
134pub fn update(
135 pt: Zcu.PerThread,
136 main_progress_node: std.Progress.Node,
137 decl_work_timer: *?Compilation.Timer,
138) (Allocator.Error || Io.Cancelable)!void {
139 const zcu = pt.zcu;
140 const comp = zcu.comp;
141 const gpa = comp.gpa;
142 const io = comp.io;
143
144 {
145 const tracy_trace = traceNamed(@src(), "astgen");
146 defer tracy_trace.end();
147
148 const zir_prog_node = main_progress_node.start("AST Lowering", 0);
149 defer zir_prog_node.end();
150
151 var timer = comp.startTimer();
152 defer if (timer.finish(io)) |ns| {
153 comp.mutex.lockUncancelable(io);
154 defer comp.mutex.unlock(io);
155 comp.time_report.?.stats.real_ns_files = ns;
156 };
157
158 var astgen_group: Io.Group = .init;
159 defer astgen_group.cancel(io);
160
161 // We cannot reference `zcu.import_table` after we spawn any `workerUpdateFile` jobs,
162 // because on single-threaded targets the worker will be run eagerly, meaning the
163 // `import_table` could be mutated, and not even holding `comp.mutex` will save us. So,
164 // build up a list of the files to update *before* we spawn any jobs.
165 var astgen_work_items: std.MultiArrayList(struct {
166 file_index: Zcu.File.Index,
167 file: *Zcu.File,
168 }) = .empty;
169 defer astgen_work_items.deinit(gpa);
170 // Not every item in `import_table` will need updating, because some are builtin.zig
171 // files. However, most will, so let's just reserve sufficient capacity upfront.
172 try astgen_work_items.ensureTotalCapacity(gpa, zcu.import_table.count());
173 for (zcu.import_table.keys()) |file_index| {
174 const file = zcu.fileByIndex(file_index);
175 if (file.is_builtin) {
176 // This is a `builtin.zig`, so updating is redundant. However, we want to make
177 // sure the file contents are still correct on disk, since it can improve the
178 // debugging experience better. That job only needs `file`, so we can kick it
179 // off right now.
180 astgen_group.async(io, workerUpdateBuiltinFile, .{ comp, file });
181 continue;
182 }
183 astgen_work_items.appendAssumeCapacity(.{
184 .file_index = file_index,
185 .file = file,
186 });
187 }
188
189 // Now that we're not going to touch `zcu.import_table` again, we can spawn `workerUpdateFile` jobs.
190 for (astgen_work_items.items(.file_index), astgen_work_items.items(.file)) |file_index, file| {
191 astgen_group.async(io, workerUpdateFile, .{
192 comp, file, file_index, zir_prog_node, &astgen_group,
193 });
194 }
195
196 // On the other hand, it's fine to directly iterate `zcu.embed_table.keys()` here
197 // because `workerUpdateEmbedFile` can't invalidate it. The different here is that one
198 // `@embedFile` can't trigger analysis of a new `@embedFile`!
199 for (0.., zcu.embed_table.keys()) |ef_index_usize, ef| {
200 const ef_index: Zcu.EmbedFile.Index = @enumFromInt(ef_index_usize);
201 astgen_group.async(io, workerUpdateEmbedFile, .{
202 comp, ef_index, ef,
203 });
204 }
205
206 try astgen_group.await(io);
207 }
208
209 // On an incremental update, a source file might become "dead", in that all imports of
210 // the file were removed. This could even change what module the file belongs to! As such,
211 // we do a traversal over the files, to figure out which ones are alive and the modules
212 // they belong to.
213 const any_fatal_files = try pt.computeAliveFiles();
214
215 // If the cache mode is `whole`, add every alive source file to the manifest.
216 switch (comp.cache_use) {
217 .whole => |whole| if (whole.cache_manifest) |man| {
218 for (zcu.alive_files.keys()) |file_index| {
219 const file = zcu.fileByIndex(file_index);
220
221 switch (file.status) {
222 .never_loaded => unreachable, // AstGen tried to load it
223 .retryable_failure => continue, // the file cannot be read; this is a guaranteed error
224 .astgen_failure, .success => {}, // the file was read successfully
225 }
226
227 const path = try file.path.toAbsolute(comp.dirs, gpa);
228 defer gpa.free(path);
229
230 const result = res: {
231 try whole.cache_manifest_mutex.lock(io);
232 defer whole.cache_manifest_mutex.unlock(io);
233 if (file.source) |source| {
234 break :res man.addFilePostContents(path, source, file.stat);
235 } else {
236 break :res man.addFilePost(path);
237 }
238 };
239 result catch |err| switch (err) {
240 error.OutOfMemory => |e| return e,
241 else => {
242 try pt.reportRetryableFileError(file_index, "unable to update cache: {s}", .{@errorName(err)});
243 continue;
244 },
245 };
246 }
247 },
248 .none, .incremental => {},
249 }
250
251 if (comp.time_report) |*tr| {
252 tr.stats.n_reachable_files = @intCast(zcu.alive_files.count());
253 }
254
255 if (any_fatal_files or
256 zcu.multi_module_err != null or
257 zcu.failed_imports.items.len > 0 or
258 comp.alloc_failure_occurred)
259 {
260 // We give up right now! No updating of ZIR refs, no nothing. The idea is that this prevents
261 // us from invalidating lots of incremental dependencies due to files with e.g. parse errors.
262 // However, this means our analysis data is invalid, so we want to omit all analysis errors.
263 zcu.skip_analysis_this_update = true;
264 return;
265 }
266
267 if (comp.config.incremental) {
268 const update_zir_refs_node = main_progress_node.start("Update ZIR References", 0);
269 defer update_zir_refs_node.end();
270 try pt.updateZirRefs();
271 }
272
273 try zcu.flushRetryableFailures();
274
275 if (!zcu.backendSupportsFeature(.separate_thread)) {
276 // Close the ZCU task queue. Prelink may still be running, but the closed
277 // queue will cause the linker task to exit once prelink finishes. The
278 // closed queue also communicates to `enqueueZcu` that it should wait for
279 // the linker task to finish and then run ZCU tasks serially.
280 comp.link_queue.finishZcuQueue(comp);
281 }
282
283 zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
284 if (comp.bin_file != null) {
285 zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0);
286 }
287 // We increment `pending_codegen_jobs` so that it doesn't reach 0 until after analysis finishes.
288 // That prevents the "Code Generation" node from constantly disappearing and reappearing when
289 // we're probably going to analyze more functions at some point.
290 assert(zcu.pending_codegen_jobs.swap(1, .monotonic) == 0); // don't let this become 0 until analysis finishes
291
292 defer {
293 zcu.sema_prog_node.end();
294 zcu.sema_prog_node = .none;
295 if (zcu.pending_codegen_jobs.fetchSub(1, .monotonic) == 1) {
296 // Decremented to 0, so all done.
297 zcu.codegen_prog_node.end();
298 zcu.codegen_prog_node = .none;
299 }
300 }
301
302 // Start the timer for the "decls" part of the pipeline (Sema, CodeGen, link).
303 decl_work_timer.* = comp.startTimer();
304
305 // To kick off semantic analysis, populate the root source file of any module we have marked
306 // as an analysis root. Declarations in these files which want eager analysis---those being
307 // `comptime` declarations, any declarations marked `export`, and `test` declarations in the
308 // main module if this is a test compilation---become referenced, and so will be picked up
309 // up by the main semantic analysis loop below.
310 for (zcu.analysisRoots()) |analysis_root_mod| {
311 const analysis_root_file = zcu.module_roots.get(analysis_root_mod).?.unwrap().?;
312 try pt.ensureFilePopulated(analysis_root_file);
313 }
314
315 // This is the main semantic analysis loop, which is essentially the main loop of the whole
316 // Zig compilation pipeline. It selects some `AnalUnit` which we know needs to be analyzed,
317 // and analyzes it, which may in turn discover more `AnalUnit`s which we need to analyze.
318 while (try zcu.findOutdatedToAnalyze()) |unit| {
319 const tracy_trace = traceNamed(@src(), "analyze_outdated");
320 defer tracy_trace.end();
321
322 const maybe_err: Zcu.SemaError!void = switch (unit.unwrap()) {
323 .@"comptime" => |cu| pt.ensureComptimeUnitUpToDate(cu),
324 .nav_ty => |nav| pt.ensureNavTypeUpToDate(nav, null),
325 .nav_val => |nav| pt.ensureNavValUpToDate(nav, null),
326 .type_layout => |ty| pt.ensureTypeLayoutUpToDate(.fromInterned(ty), null),
327 .struct_defaults => |ty| res: {
328 // Unlike the other functions, this one requires that the type layout is resolved first.
329 pt.ensureTypeLayoutUpToDate(.fromInterned(ty), null) catch |err| switch (err) {
330 error.OutOfMemory,
331 error.Canceled,
332 => |e| return e,
333
334 error.AnalysisFail => {}, // already reported
335 };
336 break :res pt.ensureStructDefaultsUpToDate(.fromInterned(ty), null);
337 },
338 .memoized_state => |stage| pt.ensureMemoizedStateUpToDate(stage, null),
339 .func => |func| pt.ensureFuncBodyUpToDate(func, null),
340 };
341 maybe_err catch |err| switch (err) {
342 error.OutOfMemory,
343 error.Canceled,
344 => |e| return e,
345
346 error.AnalysisFail => {}, // already reported
347 };
348 }
349}
350fn workerUpdateBuiltinFile(comp: *Compilation, file: *Zcu.File) void {
351 Builtin.updateFileOnDisk(file, comp) catch |err| comp.lockAndSetMiscFailure(
352 .write_builtin_zig,
353 "unable to write '{f}': {s}",
354 .{ file.path.fmt(comp), @errorName(err) },
355 );
356}
357fn workerUpdateFile(
358 comp: *Compilation,
359 file: *Zcu.File,
360 file_index: Zcu.File.Index,
361 prog_node: std.Progress.Node,
362 group: *Io.Group,
363) void {
364 const io = comp.io;
365 const tid: Zcu.PerThread.Id = .acquire(io);
366 defer tid.release(io);
367
368 const child_prog_node = prog_node.start(std.fs.path.basename(file.path.sub_path), 0);
369 defer child_prog_node.end();
370
371 const pt: Zcu.PerThread = .activate(comp.zcu.?, tid);
372 defer pt.deactivate();
373 pt.updateFile(file_index, file) catch |err| {
374 pt.reportRetryableFileError(file_index, "unable to load '{s}': {s}", .{ std.fs.path.basename(file.path.sub_path), @errorName(err) }) catch |oom| switch (oom) {
375 error.OutOfMemory => {
376 comp.mutex.lockUncancelable(io);
377 defer comp.mutex.unlock(io);
378 comp.setAllocFailure();
379 },
380 };
381 return;
382 };
383
384 switch (file.getMode()) {
385 .zig => {}, // continue to logic below
386 .zon => return, // ZON can't import anything so we're done
387 }
388
389 // Discover all imports in the file. Imports of modules we ignore for now since we don't
390 // know which module we're in, but imports of file paths might need us to queue up other
391 // AstGen jobs.
392 const imports_index = file.zir.?.extra[@intFromEnum(Zir.ExtraIndex.imports)];
393 if (imports_index != 0) {
394 const extra = file.zir.?.extraData(Zir.Inst.Imports, imports_index);
395 var import_i: u32 = 0;
396 var extra_index = extra.end;
397
398 while (import_i < extra.data.imports_len) : (import_i += 1) {
399 const item = file.zir.?.extraData(Zir.Inst.Imports.Item, extra_index);
400 extra_index = item.end;
401
402 const import_path = file.zir.?.nullTerminatedString(item.data.name);
403
404 if (pt.discoverImport(file.path, import_path)) |res| switch (res) {
405 .module, .existing_file => {},
406 .new_file => |new| {
407 group.async(io, workerUpdateFile, .{
408 comp, new.file, new.index, prog_node, group,
409 });
410 },
411 } else |err| switch (err) {
412 error.OutOfMemory => {
413 comp.mutex.lockUncancelable(io);
414 defer comp.mutex.unlock(io);
415 comp.setAllocFailure();
416 },
417 }
418 }
419 }
420}
421fn workerUpdateEmbedFile(comp: *Compilation, ef_index: Zcu.EmbedFile.Index, ef: *Zcu.EmbedFile) void {
422 const io = comp.io;
423 const tid: Zcu.PerThread.Id = .acquire(io);
424 defer tid.release(io);
425 detectEmbedFileUpdate(comp, tid, ef_index, ef) catch |err| switch (err) {
426 error.OutOfMemory => {
427 comp.mutex.lockUncancelable(io);
428 defer comp.mutex.unlock(io);
429 comp.setAllocFailure();
430 },
431 };
432}
433fn detectEmbedFileUpdate(comp: *Compilation, tid: Zcu.PerThread.Id, ef_index: Zcu.EmbedFile.Index, ef: *Zcu.EmbedFile) !void {
434 const io = comp.io;
435 const zcu = comp.zcu.?;
436 const pt: Zcu.PerThread = .activate(zcu, tid);
437 defer pt.deactivate();
438
439 const old_val = ef.val;
440 const old_err = ef.err;
441
442 try pt.updateEmbedFile(ef, null);
443
444 if (ef.val != .none and ef.val == old_val) return; // success, value unchanged
445 if (ef.val == .none and old_val == .none and ef.err == old_err) return; // failure, error unchanged
446
447 comp.mutex.lockUncancelable(io);
448 defer comp.mutex.unlock(io);
449
450 try zcu.markDependeeOutdated(.not_marked_po, .{ .embed_file = ef_index });
451}
452
128453fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void {
129454 const zcu = pt.zcu;
130455 const gpa = zcu.gpa;
......@@ -156,8 +481,8 @@ pub fn updateFile(
156481) !void {
157482 dev.check(.ast_gen);
158483
159 const tracy = trace(@src());
160 defer tracy.end();
484 const tracy_trace = trace(@src());
485 defer tracy_trace.end();
161486
162487 const zcu = pt.zcu;
163488 const comp = zcu.comp;
......@@ -484,7 +809,7 @@ fn cleanupUpdatedFiles(gpa: Allocator, updated_files: *std.AutoArrayHashMapUnman
484809 updated_files.deinit(gpa);
485810}
486811
487pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
812fn updateZirRefs(pt: Zcu.PerThread) (Io.Cancelable || Allocator.Error)!void {
488813 assert(pt.tid == .main);
489814 const zcu = pt.zcu;
490815 const comp = zcu.comp;
......@@ -566,7 +891,7 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
566891 const old_line = old_zir.getDeclaration(old_inst).src_line;
567892 const new_line = new_zir.getDeclaration(new_inst).src_line;
568893 if (old_line != new_line) {
569 try comp.queueJob(.{ .update_line_number = tracked_inst_index });
894 try comp.link_queue.enqueueZcu(comp, pt.tid, .{ .debug_update_line_number = tracked_inst_index });
570895 }
571896 },
572897 else => {},
......@@ -598,44 +923,38 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
598923 // Value is whether the declaration is `pub`.
599924 var old_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, bool) = .empty;
600925 defer old_names.deinit(zcu.gpa);
601 {
602 var it = old_zir.declIterator(old_inst);
603 while (it.next()) |decl_inst| {
604 const old_decl = old_zir.getDeclaration(decl_inst);
605 if (old_decl.name == .empty) continue;
606 const name_ip = try zcu.intern_pool.getOrPutString(
607 zcu.gpa,
608 io,
609 pt.tid,
610 old_zir.nullTerminatedString(old_decl.name),
611 .no_embedded_nulls,
612 );
613 try old_names.put(zcu.gpa, name_ip, old_decl.is_pub);
614 }
926 for (old_zir.typeDecls(old_inst)) |decl_inst| {
927 const old_decl = old_zir.getDeclaration(decl_inst);
928 if (old_decl.name == .empty) continue;
929 const name_ip = try zcu.intern_pool.getOrPutString(
930 zcu.gpa,
931 io,
932 pt.tid,
933 old_zir.nullTerminatedString(old_decl.name),
934 .no_embedded_nulls,
935 );
936 try old_names.put(zcu.gpa, name_ip, old_decl.is_pub);
615937 }
616938 var any_change = false;
617 {
618 var it = new_zir.declIterator(new_inst);
619 while (it.next()) |decl_inst| {
620 const new_decl = new_zir.getDeclaration(decl_inst);
621 if (new_decl.name == .empty) continue;
622 const name_ip = try zcu.intern_pool.getOrPutString(
623 zcu.gpa,
624 io,
625 pt.tid,
626 new_zir.nullTerminatedString(new_decl.name),
627 .no_embedded_nulls,
628 );
629 if (old_names.fetchSwapRemove(name_ip)) |kv| {
630 if (kv.value == new_decl.is_pub) continue;
631 }
632 // Name added, or changed whether it's pub
633 any_change = true;
634 try zcu.markDependeeOutdated(.not_marked_po, .{ .namespace_name = .{
635 .namespace = tracked_inst_index,
636 .name = name_ip,
637 } });
939 for (new_zir.typeDecls(new_inst)) |decl_inst| {
940 const new_decl = new_zir.getDeclaration(decl_inst);
941 if (new_decl.name == .empty) continue;
942 const name_ip = try zcu.intern_pool.getOrPutString(
943 zcu.gpa,
944 io,
945 pt.tid,
946 new_zir.nullTerminatedString(new_decl.name),
947 .no_embedded_nulls,
948 );
949 if (old_names.fetchSwapRemove(name_ip)) |kv| {
950 if (kv.value == new_decl.is_pub) continue;
638951 }
952 // Name added, or changed whether it's pub
953 any_change = true;
954 try zcu.markDependeeOutdated(.not_marked_po, .{ .namespace_name = .{
955 .namespace = tracked_inst_index,
956 .name = name_ip,
957 } });
639958 }
640959 // The only elements remaining in `old_names` now are any names which were removed.
641960 for (old_names.keys()) |name_ip| {
......@@ -674,32 +993,74 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
674993 }
675994}
676995
677/// Ensures that `zcu.fileRootType` on this `file_index` gives an up-to-date answer.
678/// Returns `error.AnalysisFail` if the file has an error.
679pub fn ensureFileAnalyzed(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
680 const file_root_type = pt.zcu.fileRootType(file_index);
681 if (file_root_type != .none) {
682 if (pt.ensureTypeUpToDate(file_root_type)) |_| {
683 return;
684 } else |err| switch (err) {
685 error.AnalysisFail => {
686 // The file's root `struct_decl` has, at some point, been lost, because the file failed AstGen.
687 // Clear `file_root_type`, and try the `semaFile` call below, in case the instruction has since
688 // been discovered under a new `TrackedInst.Index`.
689 pt.zcu.setFileRootType(file_index, .none);
690 },
691 else => |e| return e,
692 }
693 }
694 return pt.semaFile(file_index);
996/// Ensures that `zcu.fileRootType` on this `file_index` is populated (not `.none`). This implies
997/// that the file's namespace is scanned, discovering declarations.
998///
999/// Typical Zig compilations begin by claling this function on the root source file of the standard
1000/// library, `lib/std/std.zig`. The resulting namespace scan discovers a `comptime` declaration in
1001/// that file, which is queued for analysis, and everything goes from there.
1002pub fn ensureFilePopulated(pt: Zcu.PerThread, file_index: Zcu.File.Index) (Allocator.Error || Io.Cancelable)!void {
1003 dev.check(.sema);
1004
1005 const tracy_trace = trace(@src());
1006 defer tracy_trace.end();
1007
1008 const zcu = pt.zcu;
1009 const comp = zcu.comp;
1010 const io = comp.io;
1011 const gpa = comp.gpa;
1012 const ip = &zcu.intern_pool;
1013
1014 if (zcu.fileRootType(file_index) != .none) return; // already good
1015
1016 if (zcu.comp.time_report) |*tr| tr.stats.n_imported_files += 1;
1017
1018 const file = zcu.fileByIndex(file_index);
1019 assert(file.getMode() == .zig);
1020 const struct_decl = file.zir.?.getStructDecl(.main_struct_inst);
1021 const tracked_inst = try ip.trackZir(gpa, io, pt.tid, .{
1022 .file = file_index,
1023 .inst = .main_struct_inst,
1024 });
1025 const wip: InternPool.WipContainerType = switch (try ip.getDeclaredStructType(gpa, io, pt.tid, .{
1026 .zir_index = tracked_inst,
1027 .captures = &.{},
1028 .fields_len = @intCast(struct_decl.field_names.len),
1029 .layout = struct_decl.layout,
1030 .any_comptime_fields = struct_decl.field_comptime_bits != null,
1031 .any_field_defaults = struct_decl.field_default_body_lens != null,
1032 .any_field_aligns = struct_decl.field_align_body_lens != null,
1033 .packed_backing_mode = if (struct_decl.backing_int_type_body != null) .explicit else .auto,
1034 })) {
1035 .existing => unreachable, // it would have been set as `zcu.fileRootType` already
1036 .wip => |wip| wip,
1037 };
1038 errdefer wip.cancel(ip, pt.tid);
1039
1040 wip.setName(ip, try file.internFullyQualifiedName(pt), .none);
1041 const new_namespace_index: InternPool.NamespaceIndex = try pt.createNamespace(.{
1042 .parent = .none,
1043 .owner_type = wip.index,
1044 .file_scope = file_index,
1045 .generation = zcu.generation,
1046 });
1047 errdefer pt.destroyNamespace(new_namespace_index);
1048 try pt.scanNamespace(new_namespace_index, struct_decl.decls);
1049 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip.index);
1050 zcu.setFileRootType(file_index, wip.finish(ip, new_namespace_index));
6951051}
6961052
6971053/// Ensures that all memoized state on `Zcu` is up-to-date, performing re-analysis if necessary.
6981054/// Returns `error.AnalysisFail` if an analysis error is encountered; the caller is free to ignore
6991055/// this, since the error is already registered, but it must not use the value of memoized fields.
700pub fn ensureMemoizedStateUpToDate(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage) Zcu.SemaError!void {
701 const tracy = trace(@src());
702 defer tracy.end();
1056pub fn ensureMemoizedStateUpToDate(
1057 pt: Zcu.PerThread,
1058 stage: InternPool.MemoizedStateStage,
1059 /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`.
1060 reason: ?*const Zcu.DependencyReason,
1061) Zcu.SemaError!void {
1062 const tracy_trace = trace(@src());
1063 defer tracy_trace.end();
7031064
7041065 const zcu = pt.zcu;
7051066 const gpa = zcu.gpa;
......@@ -710,19 +1071,11 @@ pub fn ensureMemoizedStateUpToDate(pt: Zcu.PerThread, stage: InternPool.Memoized
7101071
7111072 assert(!zcu.analysis_in_progress.contains(unit));
7121073
713 const was_outdated = zcu.outdated.swapRemove(unit) or zcu.potentially_outdated.swapRemove(unit);
1074 const was_outdated = zcu.clearOutdatedState(unit);
7141075 const prev_failed = zcu.failed_analysis.contains(unit) or zcu.transitive_failed_analysis.contains(unit);
7151076
7161077 if (was_outdated) {
717 dev.check(.incremental);
718 _ = zcu.outdated_ready.swapRemove(unit);
719 // No need for `deleteUnitExports` because we never export anything.
720 zcu.deleteUnitReferences(unit);
721 zcu.deleteUnitCompileLogs(unit);
722 if (zcu.failed_analysis.fetchSwapRemove(unit)) |kv| {
723 kv.value.destroy(gpa);
724 }
725 _ = zcu.transitive_failed_analysis.swapRemove(unit);
1078 zcu.resetUnit(unit);
7261079 } else {
7271080 if (prev_failed) return error.AnalysisFail;
7281081 // We use an arbitrary element to check if the state has been resolved yet.
......@@ -741,7 +1094,7 @@ pub fn ensureMemoizedStateUpToDate(pt: Zcu.PerThread, stage: InternPool.Memoized
7411094 info.deps.clearRetainingCapacity();
7421095 }
7431096
744 const any_changed: bool, const new_failed: bool = if (pt.analyzeMemoizedState(stage)) |any_changed|
1097 const any_changed: bool, const new_failed: bool = if (pt.analyzeMemoizedState(stage, reason)) |any_changed|
7451098 .{ any_changed or prev_failed, false }
7461099 else |err| switch (err) {
7471100 error.AnalysisFail => res: {
......@@ -774,39 +1127,20 @@ pub fn ensureMemoizedStateUpToDate(pt: Zcu.PerThread, stage: InternPool.Memoized
7741127 if (new_failed) return error.AnalysisFail;
7751128}
7761129
777fn analyzeMemoizedState(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage) Zcu.CompileError!bool {
1130fn analyzeMemoizedState(
1131 pt: Zcu.PerThread,
1132 stage: InternPool.MemoizedStateStage,
1133 reason: ?*const Zcu.DependencyReason,
1134) Zcu.CompileError!bool {
7781135 const zcu = pt.zcu;
779 const ip = &zcu.intern_pool;
7801136 const comp = zcu.comp;
7811137 const gpa = comp.gpa;
782 const io = comp.io;
7831138
7841139 const unit: AnalUnit = .wrap(.{ .memoized_state = stage });
7851140
786 try zcu.analysis_in_progress.putNoClobber(gpa, unit, {});
1141 try zcu.analysis_in_progress.putNoClobber(gpa, unit, reason);
7871142 defer assert(zcu.analysis_in_progress.swapRemove(unit));
7881143
789 // Before we begin, collect:
790 // * The type `std`, and its namespace
791 // * The type `std.builtin`, and its namespace
792 // * A semi-reasonable source location
793 const std_file_index = zcu.module_roots.get(zcu.std_mod).?.unwrap().?;
794 try pt.ensureFileAnalyzed(std_file_index);
795 const std_type: Type = .fromInterned(zcu.fileRootType(std_file_index));
796 const std_namespace = std_type.getNamespaceIndex(zcu);
797 try pt.ensureNamespaceUpToDate(std_namespace);
798 const builtin_str = try ip.getOrPutString(gpa, io, pt.tid, "builtin", .no_embedded_nulls);
799 const builtin_nav = zcu.namespacePtr(std_namespace).pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse
800 @panic("lib/std.zig is corrupt and missing 'builtin'");
801 try pt.ensureNavValUpToDate(builtin_nav);
802 const builtin_type: Type = .fromInterned(ip.getNav(builtin_nav).status.fully_resolved.val);
803 const builtin_namespace = builtin_type.getNamespaceIndex(zcu);
804 try pt.ensureNamespaceUpToDate(builtin_namespace);
805 const src: Zcu.LazySrcLoc = .{
806 .base_node_inst = builtin_type.typeDeclInst(zcu).?,
807 .offset = .{ .byte_abs = 0 },
808 };
809
8101144 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);
8111145 defer analysis_arena.deinit();
8121146
......@@ -827,30 +1161,15 @@ fn analyzeMemoizedState(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage)
8271161 };
8281162 defer sema.deinit();
8291163
830 var block: Sema.Block = .{
831 .parent = null,
832 .sema = &sema,
833 .namespace = std_namespace,
834 .instructions = .{},
835 .inlining = null,
836 .comptime_reason = .{ .reason = .{
837 .src = src,
838 .r = .{ .simple = .type },
839 } },
840 .src_base_inst = src.base_node_inst,
841 .type_name_ctx = .empty,
842 };
843 defer block.instructions.deinit(gpa);
844
845 return sema.analyzeMemoizedState(&block, src, builtin_namespace, stage);
1164 return sema.analyzeMemoizedState(stage);
8461165}
8471166
8481167/// Ensures that the state of the given `ComptimeUnit` is fully up-to-date, performing re-analysis
8491168/// if necessary. Returns `error.AnalysisFail` if an analysis error is encountered; the caller is
8501169/// free to ignore this, since the error is already registered.
8511170pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu.SemaError!void {
852 const tracy = trace(@src());
853 defer tracy.end();
1171 const tracy_trace = trace(@src());
1172 defer tracy_trace.end();
8541173
8551174 const zcu = pt.zcu;
8561175 const gpa = zcu.gpa;
......@@ -870,22 +1189,10 @@ pub fn ensureComptimeUnitUpToDate(pt: Zcu.PerThread, cu_id: InternPool.ComptimeU
8701189 // result in over-analysis if analysis occurs in a poor order; we do our best to avoid this by
8711190 // carefully choosing which units to re-analyze. See `Zcu.findOutdatedToAnalyze`.
8721191
873 const was_outdated = zcu.outdated.swapRemove(anal_unit) or
874 zcu.potentially_outdated.swapRemove(anal_unit);
1192 const was_outdated = zcu.clearOutdatedState(anal_unit);
8751193
8761194 if (was_outdated) {
877 _ = zcu.outdated_ready.swapRemove(anal_unit);
878 // `was_outdated` can be true in the initial update for comptime units, so this isn't a `dev.check`.
879 if (dev.env.supports(.incremental)) {
880 zcu.deleteUnitExports(anal_unit);
881 zcu.deleteUnitReferences(anal_unit);
882 zcu.deleteUnitCompileLogs(anal_unit);
883 if (zcu.failed_analysis.fetchSwapRemove(anal_unit)) |kv| {
884 kv.value.destroy(gpa);
885 }
886 _ = zcu.transitive_failed_analysis.swapRemove(anal_unit);
887 zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit);
888 }
1195 zcu.resetUnit(anal_unit);
8891196 } else {
8901197 // We can trust the current information about this unit.
8911198 if (zcu.failed_analysis.contains(anal_unit)) return error.AnalysisFail;
......@@ -950,7 +1257,7 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu
9501257 const file = zcu.fileByIndex(inst_resolved.file);
9511258 const zir = file.zir.?;
9521259
953 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, {});
1260 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, null);
9541261 defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));
9551262
9561263 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);
......@@ -980,7 +1287,7 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu
9801287 .parent = null,
9811288 .sema = &sema,
9821289 .namespace = comptime_unit.namespace,
983 .instructions = .{},
1290 .instructions = .empty,
9841291 .inlining = null,
9851292 .comptime_reason = .{ .reason = .{
9861293 .src = .{
......@@ -1012,33 +1319,262 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu
10121319 try sema.flushExports();
10131320}
10141321
1322/// Ensures that the layout of the given `struct`, `union`, or `enum` type is fully up-to-date,
1323/// performing re-analysis if necessary. Asserts that `ty` is a struct (not a tuple!), union, or
1324/// enum type. Returns `error.AnalysisFail` if an analysis error is encountered during type
1325/// resolution; the caller is free to ignore this, since the error is already registered.
1326pub fn ensureTypeLayoutUpToDate(
1327 pt: Zcu.PerThread,
1328 ty: Type,
1329 /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`.
1330 reason: ?*const Zcu.DependencyReason,
1331) Zcu.SemaError!void {
1332 const tracy_trace = trace(@src());
1333 defer tracy_trace.end();
1334
1335 const zcu = pt.zcu;
1336 const ip = &zcu.intern_pool;
1337 const comp = zcu.comp;
1338 const gpa = comp.gpa;
1339
1340 const anal_unit: AnalUnit = .wrap(.{ .type_layout = ty.toIntern() });
1341
1342 log.debug("ensureTypeLayoutUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});
1343
1344 assert(!zcu.analysis_in_progress.contains(anal_unit));
1345
1346 const was_outdated: bool = outdated: {
1347 if (zcu.clearOutdatedState(anal_unit)) break :outdated true;
1348 if (ip.setWantTypeLayout(comp.io, ty.toIntern())) {
1349 // We'll analyze the layout for the first time, but if this is a struct type then its
1350 // default field values also need to be analyzed.
1351 if (ip.indexToKey(ty.toIntern()) == .struct_type) {
1352 if (std.debug.runtime_safety) zcu.outdated_lock.lockUncancelable(zcu.comp.io);
1353 defer if (std.debug.runtime_safety) zcu.outdated_lock.unlock(zcu.comp.io);
1354 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
1355 try zcu.outdated_ready.other.ensureUnusedCapacity(gpa, 1);
1356 zcu.outdated.putAssumeCapacityNoClobber(.wrap(.{ .struct_defaults = ty.toIntern() }), 0);
1357 zcu.outdated_ready.other.putAssumeCapacityNoClobber(.wrap(.{ .struct_defaults = ty.toIntern() }), {});
1358 }
1359 break :outdated true;
1360 }
1361 break :outdated false;
1362 };
1363
1364 if (was_outdated) {
1365 zcu.resetUnit(anal_unit);
1366 // For types, we already know that we have to invalidate all dependees.
1367 // TODO: we actually *could* detect whether everything was the same. should we bother?
1368 try zcu.markDependeeOutdated(.marked_po, .{ .type_layout = ty.toIntern() });
1369 } else {
1370 // We can trust the current information about this unit.
1371 if (zcu.failed_analysis.contains(anal_unit)) return error.AnalysisFail;
1372 if (zcu.transitive_failed_analysis.contains(anal_unit)) return error.AnalysisFail;
1373 return;
1374 }
1375
1376 if (comp.debugIncremental()) {
1377 const info = try zcu.incremental_debug_state.getUnitInfo(gpa, anal_unit);
1378 info.last_update_gen = zcu.generation;
1379 info.deps.clearRetainingCapacity();
1380 }
1381
1382 const unit_tracking = zcu.trackUnitSema(ty.containerTypeName(ip).toSlice(ip), null);
1383 defer unit_tracking.end(zcu);
1384
1385 try zcu.analysis_in_progress.put(gpa, anal_unit, reason);
1386 defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));
1387
1388 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);
1389 defer analysis_arena.deinit();
1390
1391 var comptime_err_ret_trace: std.array_list.Managed(Zcu.LazySrcLoc) = .init(gpa);
1392 defer comptime_err_ret_trace.deinit();
1393
1394 const file = zcu.namespacePtr(ty.getNamespaceIndex(zcu)).fileScope(zcu);
1395
1396 var sema: Sema = .{
1397 .pt = pt,
1398 .gpa = gpa,
1399 .arena = analysis_arena.allocator(),
1400 .code = file.zir.?,
1401 .owner = anal_unit,
1402 .func_index = .none,
1403 .func_is_naked = false,
1404 .fn_ret_ty = .void,
1405 .fn_ret_ty_ies = null,
1406 .comptime_err_ret_trace = &comptime_err_ret_trace,
1407 };
1408 defer sema.deinit();
1409
1410 const result = switch (ty.zigTypeTag(zcu)) {
1411 .@"enum" => Sema.type_resolution.resolveEnumLayout(&sema, ty),
1412 .@"struct" => Sema.type_resolution.resolveStructLayout(&sema, ty),
1413 .@"union" => Sema.type_resolution.resolveUnionLayout(&sema, ty),
1414 else => unreachable,
1415 };
1416 const new_failed: bool = if (result) failed: {
1417 break :failed false;
1418 } else |err| switch (err) {
1419 error.AnalysisFail => failed: {
1420 if (!zcu.failed_analysis.contains(anal_unit)) {
1421 // If this unit caused the error, it would have an entry in `failed_analysis`.
1422 // Since it does not, this must be a transitive failure.
1423 try zcu.transitive_failed_analysis.put(gpa, anal_unit, {});
1424 log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(anal_unit)});
1425 }
1426 break :failed true;
1427 },
1428 error.OutOfMemory,
1429 error.Canceled,
1430 => |e| return e,
1431 error.ComptimeReturn => unreachable,
1432 error.ComptimeBreak => unreachable,
1433 };
1434
1435 sema.flushExports() catch |err| switch (err) {
1436 error.OutOfMemory => |e| return e,
1437 };
1438
1439 // We don't need to `markDependeeOutdated`/`markPoDependeeUpToDate` here, because we already
1440 // marked the layout as outdated at the top of this function. However, we do need to tell the
1441 // debug info logic in the backend about this type.
1442 comp.link_prog_node.increaseEstimatedTotalItems(1);
1443 try comp.link_queue.enqueueZcu(comp, pt.tid, .{ .debug_update_container_type = .{
1444 .ty = ty.toIntern(),
1445 .success = !new_failed,
1446 } });
1447
1448 if (new_failed) return error.AnalysisFail;
1449}
1450
1451/// Ensures that the default field values of the given `struct` type are fully up-to-date,
1452/// performing re-analysis if necessary. Asserts that `ty` is a struct (not a tuple!) type. Unlike
1453/// the other "ensure X up to date" functions, this particular function also asserts that the
1454/// *layout* of `ty` is *already* up-to-date (though it is okay for that resolution to have failed).
1455/// Returns `error.AnalysisFail` if an analysis error is encountered while resolving the default
1456/// field values; the caller is free to ignore this, since the error is already registered.
1457pub fn ensureStructDefaultsUpToDate(
1458 pt: Zcu.PerThread,
1459 ty: Type,
1460 /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`.
1461 reason: ?*const Zcu.DependencyReason,
1462) Zcu.SemaError!void {
1463 const tracy_trace = trace(@src());
1464 defer tracy_trace.end();
1465
1466 const zcu = pt.zcu;
1467 const ip = &zcu.intern_pool;
1468 const comp = zcu.comp;
1469 const gpa = comp.gpa;
1470
1471 assert(ip.indexToKey(ty.toIntern()) == .struct_type);
1472
1473 const anal_unit: AnalUnit = .wrap(.{ .struct_defaults = ty.toIntern() });
1474
1475 log.debug("ensureStructDefaultsUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});
1476
1477 assert(!zcu.analysis_in_progress.contains(anal_unit));
1478
1479 const was_outdated: bool = outdated: {
1480 if (zcu.clearOutdatedState(anal_unit)) break :outdated true;
1481 // The type layout should already be marked as "wanted" by this point, because a struct's
1482 // layout must always be analyzed before its default values are.
1483 assert(!ip.setWantTypeLayout(comp.io, ty.toIntern()));
1484 break :outdated false;
1485 };
1486
1487 if (was_outdated) {
1488 zcu.resetUnit(anal_unit);
1489 // For types, we already know that we have to invalidate all dependees.
1490 // TODO: we actually *could* detect whether everything was the same. should we bother?
1491 try zcu.markDependeeOutdated(.marked_po, .{ .struct_defaults = ty.toIntern() });
1492 } else {
1493 // We can trust the current information about this unit.
1494 if (zcu.failed_analysis.contains(anal_unit)) return error.AnalysisFail;
1495 if (zcu.transitive_failed_analysis.contains(anal_unit)) return error.AnalysisFail;
1496 return;
1497 }
1498
1499 if (zcu.comp.debugIncremental()) {
1500 const info = try zcu.incremental_debug_state.getUnitInfo(gpa, anal_unit);
1501 info.last_update_gen = zcu.generation;
1502 info.deps.clearRetainingCapacity();
1503 }
1504
1505 const unit_tracking = zcu.trackUnitSema(ty.containerTypeName(ip).toSlice(ip), null);
1506 defer unit_tracking.end(zcu);
1507
1508 try zcu.analysis_in_progress.put(gpa, anal_unit, reason);
1509 defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));
1510
1511 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);
1512 defer analysis_arena.deinit();
1513
1514 var comptime_err_ret_trace: std.array_list.Managed(Zcu.LazySrcLoc) = .init(gpa);
1515 defer comptime_err_ret_trace.deinit();
1516
1517 const file = zcu.namespacePtr(ty.getNamespaceIndex(zcu)).fileScope(zcu);
1518
1519 var sema: Sema = .{
1520 .pt = pt,
1521 .gpa = gpa,
1522 .arena = analysis_arena.allocator(),
1523 .code = file.zir.?,
1524 .owner = anal_unit,
1525 .func_index = .none,
1526 .func_is_naked = false,
1527 .fn_ret_ty = .void,
1528 .fn_ret_ty_ies = null,
1529 .comptime_err_ret_trace = &comptime_err_ret_trace,
1530 };
1531 defer sema.deinit();
1532
1533 const new_failed: bool = if (Sema.type_resolution.resolveStructDefaults(&sema, ty)) failed: {
1534 break :failed false;
1535 } else |err| switch (err) {
1536 error.AnalysisFail => failed: {
1537 if (!zcu.failed_analysis.contains(anal_unit)) {
1538 // If this unit caused the error, it would have an entry in `failed_analysis`.
1539 // Since it does not, this must be a transitive failure.
1540 try zcu.transitive_failed_analysis.put(gpa, anal_unit, {});
1541 log.debug("mark transitive analysis failure for {f}", .{zcu.fmtAnalUnit(anal_unit)});
1542 }
1543 break :failed true;
1544 },
1545 error.OutOfMemory,
1546 error.Canceled,
1547 => |e| return e,
1548 error.ComptimeReturn => unreachable,
1549 error.ComptimeBreak => unreachable,
1550 };
1551
1552 sema.flushExports() catch |err| switch (err) {
1553 error.OutOfMemory => |e| return e,
1554 };
1555
1556 // We don't need to `markDependeeOutdated`/`markPoDependeeUpToDate` here, because we already
1557 // marked the struct defaults as outdated at the top of this function.
1558
1559 if (new_failed) return error.AnalysisFail;
1560}
1561
10151562/// Ensures that the resolved value of the given `Nav` is fully up-to-date, performing re-analysis
10161563/// if necessary. Returns `error.AnalysisFail` if an analysis error is encountered; the caller is
10171564/// free to ignore this, since the error is already registered.
1018pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.SemaError!void {
1019 const tracy = trace(@src());
1020 defer tracy.end();
1021
1022 // TODO: document this elsewhere mlugg!
1023 // For my own benefit, here's how a namespace update for a normal (non-file-root) type works:
1024 // `const S = struct { ... };`
1025 // We are adding or removing a declaration within this `struct`.
1026 // * `S` registers a dependency on `.{ .src_hash = (declaration of S) }`
1027 // * Any change to the `struct` body -- including changing a declaration -- invalidates this
1028 // * `S` is re-analyzed, but notes:
1029 // * there is an existing struct instance (at this `TrackedInst` with these captures)
1030 // * the struct's resolution is up-to-date (because nothing about the fields changed)
1031 // * so, it uses the same `struct`
1032 // * but this doesn't stop it from updating the namespace!
1033 // * we basically do `scanDecls`, updating the namespace as needed
1034 // * so everyone lived happily ever after
1565pub fn ensureNavValUpToDate(
1566 pt: Zcu.PerThread,
1567 nav_id: InternPool.Nav.Index,
1568 /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`.
1569 reason: ?*const Zcu.DependencyReason,
1570) Zcu.SemaError!void {
1571 const tracy_trace = trace(@src());
1572 defer tracy_trace.end();
10351573
10361574 const zcu = pt.zcu;
10371575 const gpa = zcu.gpa;
10381576 const ip = &zcu.intern_pool;
10391577
1040 _ = zcu.nav_val_analysis_queued.swapRemove(nav_id);
1041
10421578 const anal_unit: AnalUnit = .wrap(.{ .nav_val = nav_id });
10431579 const nav = ip.getNav(nav_id);
10441580
......@@ -1046,6 +1582,8 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
10461582
10471583 assert(!zcu.analysis_in_progress.contains(anal_unit));
10481584
1585 try zcu.ensureNavValAnalysisQueued(nav_id);
1586
10491587 // Determine whether or not this `Nav`'s value is outdated. This also includes checking if the
10501588 // status is `.unresolved`, which indicates that the value is outdated because it has *never*
10511589 // been analyzed so far.
......@@ -1055,30 +1593,18 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
10551593 // result in over-analysis if analysis occurs in a poor order; we do our best to avoid this by
10561594 // carefully choosing which units to re-analyze. See `Zcu.findOutdatedToAnalyze`.
10571595
1058 const was_outdated = zcu.outdated.swapRemove(anal_unit) or
1059 zcu.potentially_outdated.swapRemove(anal_unit);
1596 const was_outdated = zcu.clearOutdatedState(anal_unit);
10601597
10611598 const prev_failed = zcu.failed_analysis.contains(anal_unit) or
10621599 zcu.transitive_failed_analysis.contains(anal_unit);
10631600
10641601 if (was_outdated) {
1065 dev.check(.incremental);
1066 _ = zcu.outdated_ready.swapRemove(anal_unit);
1067 zcu.deleteUnitExports(anal_unit);
1068 zcu.deleteUnitReferences(anal_unit);
1069 zcu.deleteUnitCompileLogs(anal_unit);
1070 if (zcu.failed_analysis.fetchSwapRemove(anal_unit)) |kv| {
1071 kv.value.destroy(gpa);
1072 }
1073 _ = zcu.transitive_failed_analysis.swapRemove(anal_unit);
1074 ip.removeDependenciesForDepender(gpa, anal_unit);
1602 zcu.resetUnit(anal_unit);
10751603 } else {
10761604 // We can trust the current information about this unit.
10771605 if (prev_failed) return error.AnalysisFail;
1078 switch (nav.status) {
1079 .unresolved, .type_resolved => {},
1080 .fully_resolved => return,
1081 }
1606 assert(nav.status == .fully_resolved);
1607 return;
10821608 }
10831609
10841610 if (zcu.comp.debugIncremental()) {
......@@ -1090,7 +1616,7 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
10901616 const unit_tracking = zcu.trackUnitSema(nav.fqn.toSlice(ip), nav.srcInst(ip));
10911617 defer unit_tracking.end(zcu);
10921618
1093 const invalidate_value: bool, const new_failed: bool = if (pt.analyzeNavVal(nav_id)) |result| res: {
1619 const invalidate_value: bool, const new_failed: bool = if (pt.analyzeNavVal(nav_id, reason)) |result| res: {
10941620 break :res .{
10951621 // If the unit has gone from failed to success, we still need to invalidate the dependencies.
10961622 result.val_changed or prev_failed,
......@@ -1134,39 +1660,14 @@ pub fn ensureNavValUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu
11341660 }
11351661 }
11361662
1137 // If there isn't a type annotation, then we have also just resolved the type. That means the
1138 // the type is up-to-date, so it won't have the chance to mark its own dependency on the value;
1139 // we must do that ourselves.
1140 type_deps_on_val: {
1141 const inst_resolved = nav.analysis.?.zir_index.resolveFull(ip) orelse break :type_deps_on_val;
1142 const file = zcu.fileByIndex(inst_resolved.file);
1143 const zir_decl = file.zir.?.getDeclaration(inst_resolved.inst);
1144 if (zir_decl.type_body != null) break :type_deps_on_val;
1145 // The type does indeed depend on the value. We are responsible for populating all state of
1146 // the `nav_ty`, including exports, references, errors, and dependencies.
1147 const ty_unit: AnalUnit = .wrap(.{ .nav_ty = nav_id });
1148 const ty_was_outdated = zcu.outdated.swapRemove(ty_unit) or
1149 zcu.potentially_outdated.swapRemove(ty_unit);
1150 if (ty_was_outdated) {
1151 _ = zcu.outdated_ready.swapRemove(ty_unit);
1152 zcu.deleteUnitExports(ty_unit);
1153 zcu.deleteUnitReferences(ty_unit);
1154 zcu.deleteUnitCompileLogs(ty_unit);
1155 if (zcu.failed_analysis.fetchSwapRemove(ty_unit)) |kv| {
1156 kv.value.destroy(gpa);
1157 }
1158 _ = zcu.transitive_failed_analysis.swapRemove(ty_unit);
1159 ip.removeDependenciesForDepender(gpa, ty_unit);
1160 }
1161 try pt.addDependency(ty_unit, .{ .nav_val = nav_id });
1162 if (new_failed) try zcu.transitive_failed_analysis.put(gpa, ty_unit, {});
1163 if (ty_was_outdated) try zcu.markDependeeOutdated(.marked_po, .{ .nav_ty = nav_id });
1164 }
1165
11661663 if (new_failed) return error.AnalysisFail;
11671664}
11681665
1169fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileError!struct { val_changed: bool } {
1666fn analyzeNavVal(
1667 pt: Zcu.PerThread,
1668 nav_id: InternPool.Nav.Index,
1669 reason: ?*const Zcu.DependencyReason,
1670) Zcu.CompileError!struct { val_changed: bool } {
11701671 const zcu = pt.zcu;
11711672 const ip = &zcu.intern_pool;
11721673 const comp = zcu.comp;
......@@ -1183,16 +1684,8 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
11831684 const zir = file.zir.?;
11841685 const zir_decl = zir.getDeclaration(inst_resolved.inst);
11851686
1186 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, {});
1187 errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit);
1188
1189 // If there's no type body, we are also resolving the type here.
1190 if (zir_decl.type_body == null) {
1191 try zcu.analysis_in_progress.putNoClobber(gpa, .wrap(.{ .nav_ty = nav_id }), {});
1192 }
1193 errdefer if (zir_decl.type_body == null) {
1194 _ = zcu.analysis_in_progress.swapRemove(.wrap(.{ .nav_ty = nav_id }));
1195 };
1687 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, reason);
1688 defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));
11961689
11971690 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);
11981691 defer analysis_arena.deinit();
......@@ -1225,7 +1718,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
12251718 .parent = null,
12261719 .sema = &sema,
12271720 .namespace = old_nav.analysis.?.namespace,
1228 .instructions = .{},
1721 .instructions = .empty,
12291722 .inlining = null,
12301723 .comptime_reason = undefined, // set below
12311724 .src_base_inst = old_nav.analysis.?.zir_index,
......@@ -1246,9 +1739,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
12461739
12471740 const maybe_ty: ?Type = if (zir_decl.type_body != null) ty: {
12481741 // Since we have a type body, the type is resolved separately!
1249 // Of course, we need to make sure we depend on it properly.
1250 try sema.declareDependency(.{ .nav_ty = nav_id });
1251 try pt.ensureNavTypeUpToDate(nav_id);
1742 try sema.ensureNavResolved(&block, init_src, nav_id, .type);
12521743 break :ty .fromInterned(ip.getNav(nav_id).typeOf(ip));
12531744 } else null;
12541745
......@@ -1271,9 +1762,6 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
12711762
12721763 const nav_ty: Type = maybe_ty orelse final_val.?.typeOf(zcu);
12731764
1274 // First, we must resolve the declaration's type. To do this, we analyze the type body if available,
1275 // or otherwise, we analyze the value body, populating `early_val` in the process.
1276
12771765 const is_const = is_const: switch (zir_decl.kind) {
12781766 .@"comptime" => unreachable, // this is not a Nav
12791767 .unnamed_test, .@"test", .decltest => {
......@@ -1360,7 +1848,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
13601848
13611849 // This resolves the type of the resolved value, not that value itself. If `nav_val` is a struct type,
13621850 // this resolves the type `type` (which needs no resolution), not the struct itself.
1363 try nav_ty.resolveLayout(pt);
1851 try sema.ensureLayoutResolved(nav_ty, block.nodeOffset(.zero), if (zir_decl.kind == .@"var") .variable else .constant);
13641852
13651853 const queue_linker_work, const is_owned_fn = switch (ip.indexToKey(nav_val.toIntern())) {
13661854 .func => |f| .{ true, f.owner_nav == nav_id }, // note that this lets function aliases reach codegen
......@@ -1377,23 +1865,47 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
13771865 if (zir_decl.align_body != null and !target_util.supportsFunctionAlignment(zcu.getTarget())) {
13781866 return sema.fail(&block, align_src, "target does not support function alignment", .{});
13791867 }
1380 } else if (try nav_ty.comptimeOnlySema(pt)) {
1868 } else if (nav_ty.comptimeOnly(zcu)) {
13811869 // alignment, linksection, addrspace annotations are not allowed for comptime-only types.
1382 const reason: []const u8 = switch (ip.indexToKey(nav_val.toIntern())) {
1870 const cannot_align_reason: []const u8 = switch (ip.indexToKey(nav_val.toIntern())) {
13831871 .func => "function alias", // slightly clearer message, since you *can* specify these on function *declarations*
13841872 else => "comptime-only type",
13851873 };
13861874 if (zir_decl.align_body != null) {
1387 return sema.fail(&block, align_src, "cannot specify alignment of {s}", .{reason});
1875 return sema.fail(&block, align_src, "cannot specify alignment of {s}", .{cannot_align_reason});
13881876 }
13891877 if (zir_decl.linksection_body != null) {
1390 return sema.fail(&block, section_src, "cannot specify linksection of {s}", .{reason});
1878 return sema.fail(&block, section_src, "cannot specify linksection of {s}", .{cannot_align_reason});
13911879 }
13921880 if (zir_decl.addrspace_body != null) {
1393 return sema.fail(&block, addrspace_src, "cannot specify addrspace of {s}", .{reason});
1881 return sema.fail(&block, addrspace_src, "cannot specify addrspace of {s}", .{cannot_align_reason});
13941882 }
13951883 }
13961884
1885 // We're about to resolve the value of the Nav. This causes the information about what the value
1886 // was last update to be lost; therefore, if the `nav_ty` is currently out of date, it would
1887 // incorrectly think it was unchanged when eventually analyzed. To avoid this, we need to detect
1888 // that case and invalidate the dependee right now.
1889 if (zcu.clearOutdatedState(.wrap(.{ .nav_ty = nav_id }))) {
1890 assert(zir_decl.type_body == null); // otherwise we already resolved it with `Sema.ensureNavResolved`
1891 zcu.resetUnit(.wrap(.{ .nav_ty = nav_id }));
1892 try pt.addDependency(.wrap(.{ .nav_ty = nav_id }), .{ .nav_val = nav_id }); // inferred type depends on the value (that's us!)
1893 if (comp.debugIncremental()) {
1894 const info = try zcu.incremental_debug_state.getUnitInfo(gpa, .wrap(.{ .nav_ty = nav_id }));
1895 info.last_update_gen = zcu.generation;
1896 info.deps.clearRetainingCapacity();
1897 }
1898 const type_changed: bool = switch (old_nav.status) {
1899 .unresolved => true,
1900 .type_resolved => |old| old.type != nav_ty.toIntern(),
1901 .fully_resolved => |old| ip.typeOf(old.val) != nav_ty.toIntern(),
1902 };
1903 if (type_changed) {
1904 try zcu.markDependeeOutdated(.marked_po, .{ .nav_ty = nav_id });
1905 } else {
1906 try zcu.markPoDependeeUpToDate(.{ .nav_ty = nav_id });
1907 }
1908 }
13971909 ip.resolveNavValue(io, nav_id, .{
13981910 .val = nav_val.toIntern(),
13991911 .is_const = is_const,
......@@ -1402,17 +1914,11 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
14021914 .@"addrspace" = modifiers.@"addrspace",
14031915 });
14041916
1405 // Mark the unit as completed before evaluating the export!
1406 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
1407 if (zir_decl.type_body == null) {
1408 assert(zcu.analysis_in_progress.swapRemove(.wrap(.{ .nav_ty = nav_id })));
1409 }
1410
14111917 if (zir_decl.linkage == .@"export") {
14121918 const export_src = block.src(.{ .token_offset = @enumFromInt(@intFromBool(zir_decl.is_pub)) });
14131919 const name_slice = zir.nullTerminatedString(zir_decl.name);
14141920 const name_ip = try ip.getOrPutString(gpa, io, pt.tid, name_slice, .no_embedded_nulls);
1415 try sema.analyzeExport(&block, export_src, .{ .name = name_ip }, nav_id);
1921 try sema.analyzeExportSelfNav(&block, export_src, name_ip);
14161922 }
14171923
14181924 try sema.flushExports();
......@@ -1420,25 +1926,37 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
14201926 queue_codegen: {
14211927 if (!queue_linker_work) break :queue_codegen;
14221928
1423 if (!try nav_ty.hasRuntimeBitsSema(pt)) {
1424 if (zcu.comp.config.use_llvm) break :queue_codegen;
1929 if (!nav_ty.hasRuntimeBits(zcu)) {
1930 if (comp.config.use_llvm) break :queue_codegen;
14251931 if (file.mod.?.strip) break :queue_codegen;
14261932 }
14271933
1428 // This job depends on any resolve_type_fully jobs queued up before it.
1429 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
1430 try zcu.comp.queueJob(.{ .link_nav = nav_id });
1934 comp.link_prog_node.increaseEstimatedTotalItems(1);
1935 try comp.link_queue.enqueueZcu(comp, pt.tid, .{ .link_nav = nav_id });
14311936 }
14321937
1433 switch (old_nav.status) {
1434 .unresolved, .type_resolved => return .{ .val_changed = true },
1435 .fully_resolved => |old| return .{ .val_changed = old.val != nav_val.toIntern() },
1938 if (comp.config.is_test and zcu.test_functions.contains(nav_id)) {
1939 // We just analyzed a test function's "value" (essentially its signature); now we need to
1940 // implicitly reference the function *body*. `Zcu.resolveReferences` knows about this rule,
1941 // so we don't need to mark an explicit reference, but we do need to make sure that the test
1942 // body will actually get analyzed!
1943 try zcu.ensureFuncBodyAnalysisQueued(nav_val.toIntern());
14361944 }
1945
1946 return switch (old_nav.status) {
1947 .unresolved, .type_resolved => .{ .val_changed = true },
1948 .fully_resolved => |old| .{ .val_changed = old.val != nav_val.toIntern() },
1949 };
14371950}
14381951
1439pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.SemaError!void {
1440 const tracy = trace(@src());
1441 defer tracy.end();
1952pub fn ensureNavTypeUpToDate(
1953 pt: Zcu.PerThread,
1954 nav_id: InternPool.Nav.Index,
1955 /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`.
1956 reason: ?*const Zcu.DependencyReason,
1957) Zcu.SemaError!void {
1958 const tracy_trace = trace(@src());
1959 defer tracy_trace.end();
14421960
14431961 const zcu = pt.zcu;
14441962 const gpa = zcu.gpa;
......@@ -1451,17 +1969,7 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc
14511969
14521970 assert(!zcu.analysis_in_progress.contains(anal_unit));
14531971
1454 const type_resolved_by_value: bool = from_val: {
1455 const analysis = nav.analysis orelse break :from_val false;
1456 const inst_resolved = analysis.zir_index.resolveFull(ip) orelse break :from_val false;
1457 const file = zcu.fileByIndex(inst_resolved.file);
1458 const zir_decl = file.zir.?.getDeclaration(inst_resolved.inst);
1459 break :from_val zir_decl.type_body == null;
1460 };
1461 if (type_resolved_by_value) {
1462 // Logic at the end of `ensureNavValUpToDate` is directly responsible for populating our state.
1463 return pt.ensureNavValUpToDate(nav_id);
1464 }
1972 try zcu.ensureNavValAnalysisQueued(nav_id);
14651973
14661974 // Determine whether or not this `Nav`'s type is outdated. This also includes checking if the
14671975 // status is `.unresolved`, which indicates that the value is outdated because it has *never*
......@@ -1472,30 +1980,18 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc
14721980 // result in over-analysis if analysis occurs in a poor order; we do our best to avoid this by
14731981 // carefully choosing which units to re-analyze. See `Zcu.findOutdatedToAnalyze`.
14741982
1475 const was_outdated = zcu.outdated.swapRemove(anal_unit) or
1476 zcu.potentially_outdated.swapRemove(anal_unit);
1983 const was_outdated = zcu.clearOutdatedState(anal_unit);
14771984
14781985 const prev_failed = zcu.failed_analysis.contains(anal_unit) or
14791986 zcu.transitive_failed_analysis.contains(anal_unit);
14801987
14811988 if (was_outdated) {
1482 dev.check(.incremental);
1483 _ = zcu.outdated_ready.swapRemove(anal_unit);
1484 zcu.deleteUnitExports(anal_unit);
1485 zcu.deleteUnitReferences(anal_unit);
1486 zcu.deleteUnitCompileLogs(anal_unit);
1487 if (zcu.failed_analysis.fetchSwapRemove(anal_unit)) |kv| {
1488 kv.value.destroy(gpa);
1489 }
1490 _ = zcu.transitive_failed_analysis.swapRemove(anal_unit);
1491 ip.removeDependenciesForDepender(gpa, anal_unit);
1989 zcu.resetUnit(anal_unit);
14921990 } else {
14931991 // We can trust the current information about this unit.
14941992 if (prev_failed) return error.AnalysisFail;
1495 switch (nav.status) {
1496 .unresolved => {},
1497 .type_resolved, .fully_resolved => return,
1498 }
1993 assert(nav.status != .unresolved);
1994 return;
14991995 }
15001996
15011997 if (zcu.comp.debugIncremental()) {
......@@ -1507,7 +2003,7 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc
15072003 const unit_tracking = zcu.trackUnitSema(nav.fqn.toSlice(ip), nav.srcInst(ip));
15082004 defer unit_tracking.end(zcu);
15092005
1510 const invalidate_type: bool, const new_failed: bool = if (pt.analyzeNavType(nav_id)) |result| res: {
2006 const invalidate_type: bool, const new_failed: bool = if (pt.analyzeNavType(nav_id, reason)) |result| res: {
15112007 break :res .{
15122008 // If the unit has gone from failed to success, we still need to invalidate the dependencies.
15132009 result.type_changed or prev_failed,
......@@ -1554,7 +2050,11 @@ pub fn ensureNavTypeUpToDate(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zc
15542050 if (new_failed) return error.AnalysisFail;
15552051}
15562052
1557fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileError!struct { type_changed: bool } {
2053fn analyzeNavType(
2054 pt: Zcu.PerThread,
2055 nav_id: InternPool.Nav.Index,
2056 reason: ?*const Zcu.DependencyReason,
2057) Zcu.CompileError!struct { type_changed: bool } {
15582058 const zcu = pt.zcu;
15592059 const comp = zcu.comp;
15602060 const gpa = comp.gpa;
......@@ -1570,11 +2070,10 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
15702070 const file = zcu.fileByIndex(inst_resolved.file);
15712071 const zir = file.zir.?;
15722072
1573 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, {});
2073 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, reason);
15742074 defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));
15752075
15762076 const zir_decl = zir.getDeclaration(inst_resolved.inst);
1577 const type_body = zir_decl.type_body.?;
15782077
15792078 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);
15802079 defer analysis_arena.deinit();
......@@ -1607,7 +2106,7 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
16072106 .parent = null,
16082107 .sema = &sema,
16092108 .namespace = old_nav.analysis.?.namespace,
1610 .instructions = .{},
2109 .instructions = .empty,
16112110 .inlining = null,
16122111 .comptime_reason = undefined, // set below
16132112 .src_base_inst = old_nav.analysis.?.zir_index,
......@@ -1616,6 +2115,34 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
16162115 defer block.instructions.deinit(gpa);
16172116
16182117 const ty_src = block.src(.{ .node_offset_var_decl_ty = .zero });
2118 const init_src = block.src(.{ .node_offset_var_decl_init = .zero });
2119
2120 const type_body = zir_decl.type_body orelse {
2121 // There is no type annotation, so we just need to use the declaration's value.
2122 // If the value had already been re-analyzed, it would have resolved the `nav_ty` unit as
2123 // either outdated or up-to-date. So we know that `old_nav` does contain information from
2124 // the previous update. As such, after this call, we will be able to determine whether the
2125 // type changed.
2126 try sema.ensureNavResolved(&block, init_src, nav_id, .fully);
2127 const new = ip.getNav(nav_id).status.fully_resolved;
2128 const new_is_extern_decl = ip.indexToKey(new.val) == .@"extern";
2129 const changed = switch (old_nav.status) {
2130 .unresolved => true,
2131 .type_resolved => |r| r.type != ip.typeOf(new.val) or
2132 r.alignment != new.alignment or
2133 r.@"linksection" != new.@"linksection" or
2134 r.@"addrspace" != new.@"addrspace" or
2135 r.is_const != new.is_const or
2136 r.is_extern_decl != new_is_extern_decl,
2137 .fully_resolved => |r| ip.typeOf(r.val) != ip.typeOf(new.val) or
2138 r.alignment != new.alignment or
2139 r.@"linksection" != new.@"linksection" or
2140 r.@"addrspace" != new.@"addrspace" or
2141 r.is_const != new.is_const or
2142 (old_nav.getExtern(ip) != null) != new_is_extern_decl,
2143 };
2144 return .{ .type_changed = changed };
2145 };
16192146
16202147 block.comptime_reason = .{ .reason = .{
16212148 .src = ty_src,
......@@ -1628,7 +2155,7 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
16282155 break :ty .fromInterned(type_ref.toInterned().?);
16292156 };
16302157
1631 try resolved_ty.resolveLayout(pt);
2158 try sema.ensureLayoutResolved(resolved_ty, block.nodeOffset(.zero), if (zir_decl.kind == .@"var") .variable else .constant);
16322159
16332160 // In the case where the type is specified, this function is also responsible for resolving
16342161 // the pointer modifiers, i.e. alignment, linksection, addrspace.
......@@ -1678,18 +2205,24 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
16782205 return .{ .type_changed = true };
16792206}
16802207
1681pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaError!void {
2208/// If `func_index` is not a runtime function (e.g. it has a comptime-only parameter type) then it
2209/// is still valid to call this function and use its `func_body` unit in general---analysis of the
2210/// runtime function body will simply fail.
2211pub fn ensureFuncBodyUpToDate(
2212 pt: Zcu.PerThread,
2213 func_index: InternPool.Index,
2214 /// `null` is valid only for the "root" analysis, i.e. called from `Compilation.processOneJob`.
2215 reason: ?*const Zcu.DependencyReason,
2216) Zcu.SemaError!void {
16822217 dev.check(.sema);
16832218
1684 const tracy = trace(@src());
1685 defer tracy.end();
2219 const tracy_trace = trace(@src());
2220 defer tracy_trace.end();
16862221
16872222 const zcu = pt.zcu;
16882223 const gpa = zcu.gpa;
16892224 const ip = &zcu.intern_pool;
16902225
1691 _ = zcu.func_body_analysis_queued.swapRemove(func_index);
1692
16932226 const anal_unit: AnalUnit = .wrap(.{ .func = func_index });
16942227
16952228 log.debug("ensureFuncBodyUpToDate {f}", .{zcu.fmtAnalUnit(anal_unit)});
......@@ -1700,27 +2233,17 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z
17002233
17012234 assert(func.ty == func.uncoerced_ty); // analyze the body of the original function, not a coerced one
17022235
1703 const was_outdated = zcu.outdated.swapRemove(anal_unit) or
1704 zcu.potentially_outdated.swapRemove(anal_unit);
2236 const was_outdated = zcu.clearOutdatedState(anal_unit) or
2237 ip.setWantRuntimeFnAnalysis(zcu.comp.io, func_index);
17052238
17062239 const prev_failed = zcu.failed_analysis.contains(anal_unit) or zcu.transitive_failed_analysis.contains(anal_unit);
17072240
17082241 if (was_outdated) {
1709 dev.check(.incremental);
1710 _ = zcu.outdated_ready.swapRemove(anal_unit);
1711 zcu.deleteUnitExports(anal_unit);
1712 zcu.deleteUnitReferences(anal_unit);
1713 zcu.deleteUnitCompileLogs(anal_unit);
1714 if (zcu.failed_analysis.fetchSwapRemove(anal_unit)) |kv| {
1715 kv.value.destroy(gpa);
1716 }
1717 _ = zcu.transitive_failed_analysis.swapRemove(anal_unit);
2242 zcu.resetUnit(anal_unit);
17182243 } else {
17192244 // We can trust the current information about this function.
1720 if (prev_failed) {
1721 return error.AnalysisFail;
1722 }
1723 if (func.analysisUnordered(ip).is_analyzed) return;
2245 if (prev_failed) return error.AnalysisFail;
2246 return;
17242247 }
17252248
17262249 if (zcu.comp.debugIncremental()) {
......@@ -1736,7 +2259,7 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z
17362259 );
17372260 defer unit_tracking.end(zcu);
17382261
1739 const ies_outdated, const new_failed = if (pt.analyzeFuncBody(func_index)) |result|
2262 const ies_outdated, const new_failed = if (pt.analyzeFuncBody(func_index, reason)) |result|
17402263 .{ prev_failed or result.ies_outdated, false }
17412264 else |err| switch (err) {
17422265 error.AnalysisFail => res: {
......@@ -1765,9 +2288,9 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z
17652288
17662289 if (was_outdated) {
17672290 if (ies_outdated) {
1768 try zcu.markDependeeOutdated(.marked_po, .{ .interned = func_index });
2291 try zcu.markDependeeOutdated(.marked_po, .{ .func_ies = func_index });
17692292 } else {
1770 try zcu.markPoDependeeUpToDate(.{ .interned = func_index });
2293 try zcu.markPoDependeeUpToDate(.{ .func_ies = func_index });
17712294 }
17722295 }
17732296
......@@ -1777,6 +2300,7 @@ pub fn ensureFuncBodyUpToDate(pt: Zcu.PerThread, func_index: InternPool.Index) Z
17772300fn analyzeFuncBody(
17782301 pt: Zcu.PerThread,
17792302 func_index: InternPool.Index,
2303 reason: ?*const Zcu.DependencyReason,
17802304) Zcu.SemaError!struct { ies_outdated: bool } {
17812305 const zcu = pt.zcu;
17822306 const gpa = zcu.gpa;
......@@ -1785,29 +2309,6 @@ fn analyzeFuncBody(
17852309 const func = zcu.funcInfo(func_index);
17862310 const anal_unit = AnalUnit.wrap(.{ .func = func_index });
17872311
1788 // Make sure that this function is still owned by the same `Nav`. Otherwise, analyzing
1789 // it would be a waste of time in the best case, and could cause codegen to give bogus
1790 // results in the worst case.
1791
1792 if (func.generic_owner == .none) {
1793 // Among another things, this ensures that the function's `zir_body_inst` is correct.
1794 try pt.ensureNavValUpToDate(func.owner_nav);
1795 if (ip.getNav(func.owner_nav).status.fully_resolved.val != func_index) {
1796 // This function is no longer referenced! There's no point in re-analyzing it.
1797 // Just mark a transitive failure and move on.
1798 return error.AnalysisFail;
1799 }
1800 } else {
1801 const go_nav = zcu.funcInfo(func.generic_owner).owner_nav;
1802 // Among another things, this ensures that the function's `zir_body_inst` is correct.
1803 try pt.ensureNavValUpToDate(go_nav);
1804 if (ip.getNav(go_nav).status.fully_resolved.val != func.generic_owner) {
1805 // The generic owner is no longer referenced, so this function is also unreferenced.
1806 // There's no point in re-analyzing it. Just mark a transitive failure and move on.
1807 return error.AnalysisFail;
1808 }
1809 }
1810
18112312 // We'll want to remember what the IES used to be before the update for
18122313 // dependency invalidation purposes.
18132314 const old_resolved_ies = if (func.analysisUnordered(ip).inferred_error_set)
......@@ -1817,8 +2318,9 @@ fn analyzeFuncBody(
18172318
18182319 log.debug("analyze and generate fn body {f}", .{zcu.fmtAnalUnit(anal_unit)});
18192320
1820 var air = try pt.analyzeFnBodyInner(func_index);
1821 errdefer air.deinit(gpa);
2321 var air = try pt.analyzeFuncBodyInner(func_index, reason);
2322 var air_owned = true;
2323 defer if (air_owned) air.deinit(gpa);
18222324
18232325 const ies_outdated = !func.analysisUnordered(ip).inferred_error_set or
18242326 func.resolvedErrorSetUnordered(ip) != old_resolved_ies;
......@@ -1828,103 +2330,24 @@ fn analyzeFuncBody(
18282330 const dump_air = build_options.enable_debug_extensions and comp.verbose_air;
18292331 const dump_llvm_ir = build_options.enable_debug_extensions and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null);
18302332
1831 if (comp.bin_file == null and zcu.llvm_object == null and !dump_air and !dump_llvm_ir) {
1832 air.deinit(gpa);
1833 return .{ .ies_outdated = ies_outdated };
1834 }
1835
1836 // This job depends on any resolve_type_fully jobs queued up before it.
1837 zcu.codegen_prog_node.increaseEstimatedTotalItems(1);
1838 comp.link_prog_node.increaseEstimatedTotalItems(1);
1839 try comp.queueJob(.{ .codegen_func = .{
1840 .func = func_index,
1841 .air = air,
1842 } });
1843
1844 return .{ .ies_outdated = ies_outdated };
1845}
1846
1847pub fn semaMod(pt: Zcu.PerThread, mod: *Module) !void {
1848 dev.check(.sema);
1849 const file_index = pt.zcu.module_roots.get(mod).?.unwrap().?;
1850 const root_type = pt.zcu.fileRootType(file_index);
1851 if (root_type == .none) {
1852 return pt.semaFile(file_index);
1853 }
1854}
1855
1856fn createFileRootStruct(
1857 pt: Zcu.PerThread,
1858 file_index: Zcu.File.Index,
1859 namespace_index: Zcu.Namespace.Index,
1860 replace_existing: bool,
1861) Allocator.Error!InternPool.Index {
1862 const zcu = pt.zcu;
1863 const gpa = zcu.gpa;
1864 const io = zcu.comp.io;
1865 const ip = &zcu.intern_pool;
1866 const file = zcu.fileByIndex(file_index);
1867 const extended = file.zir.?.instructions.items(.data)[@intFromEnum(Zir.Inst.Index.main_struct_inst)].extended;
1868 assert(extended.opcode == .struct_decl);
1869 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
1870 assert(!small.has_captures_len);
1871 assert(!small.has_backing_int);
1872 assert(small.layout == .auto);
1873 var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).@"struct".fields.len;
1874 const fields_len = if (small.has_fields_len) blk: {
1875 const fields_len = file.zir.?.extra[extra_index];
1876 extra_index += 1;
1877 break :blk fields_len;
1878 } else 0;
1879 const decls_len = if (small.has_decls_len) blk: {
1880 const decls_len = file.zir.?.extra[extra_index];
1881 extra_index += 1;
1882 break :blk decls_len;
1883 } else 0;
1884 const decls = file.zir.?.bodySlice(extra_index, decls_len);
1885 extra_index += decls_len;
2333 if (comp.bin_file != null or zcu.llvm_object != null or dump_air or dump_llvm_ir) {
2334 zcu.codegen_prog_node.increaseEstimatedTotalItems(1);
2335 comp.link_prog_node.increaseEstimatedTotalItems(1);
18862336
1887 const tracked_inst = try ip.trackZir(gpa, io, pt.tid, .{
1888 .file = file_index,
1889 .inst = .main_struct_inst,
1890 });
1891 const wip_ty = switch (try ip.getStructType(gpa, io, pt.tid, .{
1892 .layout = .auto,
1893 .fields_len = fields_len,
1894 .known_non_opv = small.known_non_opv,
1895 .requires_comptime = if (small.known_comptime_only) .yes else .unknown,
1896 .any_comptime_fields = small.any_comptime_fields,
1897 .any_default_inits = small.any_default_inits,
1898 .inits_resolved = false,
1899 .any_aligned_fields = small.any_aligned_fields,
1900 .key = .{ .declared = .{
1901 .zir_index = tracked_inst,
1902 .captures = &.{},
1903 } },
1904 }, replace_existing)) {
1905 .existing => unreachable, // we wouldn't be analysing the file root if this type existed
1906 .wip => |wip| wip,
1907 };
1908 errdefer wip_ty.cancel(ip, pt.tid);
2337 // Some linkers need to refer to the AIR. In that case, the linker is not running
2338 // concurrently, so we'll just keep ownership of the AIR for ourselves instead of
2339 // letting the codegen job destroy it.
2340 const disown_air = zcu.backendSupportsFeature(.separate_thread);
19092341
1910 wip_ty.setName(ip, try file.internFullyQualifiedName(pt), .none);
1911 ip.namespacePtr(namespace_index).owner_type = wip_ty.index;
2342 // Begin the codegen task. If the codegen/link queue is backed up, this might
2343 // block until the linker is able to process some tasks.
2344 const codegen_task = try zcu.codegen_task_pool.start(zcu, func_index, &air, disown_air);
2345 if (disown_air) air_owned = false;
19122346
1913 if (zcu.comp.config.incremental) {
1914 try pt.addDependency(.wrap(.{ .type = wip_ty.index }), .{ .src_hash = tracked_inst });
2347 try comp.link_queue.enqueueZcu(comp, pt.tid, .{ .link_func = codegen_task });
19152348 }
19162349
1917 try pt.scanNamespace(namespace_index, decls);
1918 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
1919 codegen_type: {
1920 if (file.mod.?.strip) break :codegen_type;
1921 // This job depends on any resolve_type_fully jobs queued up before it.
1922 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
1923 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
1924 }
1925 zcu.setFileRootType(file_index, wip_ty.index);
1926 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
1927 return wip_ty.finish(ip, namespace_index);
2350 return .{ .ies_outdated = ies_outdated };
19282351}
19292352
19302353/// Re-scan the namespace of a file's root struct type on an incremental update.
......@@ -1945,48 +2368,11 @@ fn updateFileNamespace(pt: Zcu.PerThread, file_index: Zcu.File.Index) Allocator.
19452368 });
19462369
19472370 const namespace_index = Type.fromInterned(file_root_type).getNamespaceIndex(zcu);
1948 const decls = decls: {
1949 const extended = file.zir.?.instructions.items(.data)[@intFromEnum(Zir.Inst.Index.main_struct_inst)].extended;
1950 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
1951
1952 var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).@"struct".fields.len;
1953 extra_index += @intFromBool(small.has_fields_len);
1954 const decls_len = if (small.has_decls_len) blk: {
1955 const decls_len = file.zir.?.extra[extra_index];
1956 extra_index += 1;
1957 break :blk decls_len;
1958 } else 0;
1959 break :decls file.zir.?.bodySlice(extra_index, decls_len);
1960 };
2371 const decls = file.zir.?.getStructDecl(.main_struct_inst).decls;
19612372 try pt.scanNamespace(namespace_index, decls);
19622373 zcu.namespacePtr(namespace_index).generation = zcu.generation;
19632374}
19642375
1965fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
1966 const tracy = trace(@src());
1967 defer tracy.end();
1968
1969 const zcu = pt.zcu;
1970 const file = zcu.fileByIndex(file_index);
1971 assert(file.getMode() == .zig);
1972 assert(zcu.fileRootType(file_index) == .none);
1973
1974 assert(file.zir != null);
1975
1976 const new_namespace_index = try pt.createNamespace(.{
1977 .parent = .none,
1978 .owner_type = undefined, // set in `createFileRootStruct`
1979 .file_scope = file_index,
1980 .generation = zcu.generation,
1981 });
1982 const struct_ty = try pt.createFileRootStruct(file_index, new_namespace_index, false);
1983 errdefer zcu.intern_pool.remove(pt.tid, struct_ty);
1984
1985 if (zcu.comp.time_report) |*tr| {
1986 tr.stats.n_imported_files += 1;
1987 }
1988}
1989
19902376/// Called by AstGen worker threads when an import is seen. If `new_file` is returned, the caller is
19912377/// then responsible for queueing a new AstGen job for the new file.
19922378/// Assumes that `comp.mutex` is NOT locked. It will be locked by this function where necessary.
......@@ -2214,7 +2600,7 @@ pub fn populateModuleRootTable(pt: Zcu.PerThread) error{
22142600/// modify `pt.zcu.skip_analysis_this_update`.
22152601///
22162602/// If an error is returned, `pt.zcu.alive_files` might contain undefined values.
2217pub fn computeAliveFiles(pt: Zcu.PerThread) Allocator.Error!bool {
2603fn computeAliveFiles(pt: Zcu.PerThread) Allocator.Error!bool {
22182604 const zcu = pt.zcu;
22192605 const comp = zcu.comp;
22202606 const gpa = zcu.gpa;
......@@ -2655,8 +3041,8 @@ pub fn scanNamespace(
26553041 namespace_index: Zcu.Namespace.Index,
26563042 decls: []const Zir.Inst.Index,
26573043) Allocator.Error!void {
2658 const tracy = trace(@src());
2659 defer tracy.end();
3044 const tracy_trace = trace(@src());
3045 defer tracy_trace.end();
26603046
26613047 const zcu = pt.zcu;
26623048 const ip = &zcu.intern_pool;
......@@ -2752,8 +3138,8 @@ const ScanDeclIter = struct {
27523138 }
27533139
27543140 fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void {
2755 const tracy = trace(@src());
2756 defer tracy.end();
3141 const tracy_trace = trace(@src());
3142 defer tracy_trace.end();
27573143
27583144 const pt = iter.pt;
27593145 const zcu = pt.zcu;
......@@ -2806,89 +3192,76 @@ const ScanDeclIter = struct {
28063192
28073193 const existing_unit = iter.existing_by_inst.get(tracked_inst);
28083194
2809 const unit, const want_analysis = switch (decl.kind) {
2810 .@"comptime" => unit: {
2811 const cu = if (existing_unit) |eu|
2812 eu.unwrap().@"comptime"
2813 else
2814 try ip.createComptimeUnit(gpa, io, pt.tid, tracked_inst, namespace_index);
2815
2816 const unit: AnalUnit = .wrap(.{ .@"comptime" = cu });
2817
3195 const name = maybe_name.unwrap() orelse {
3196 // Only `comptime` declarations are unnamed.
3197 assert(decl.kind == .@"comptime");
3198 if (existing_unit) |unit| {
3199 try namespace.comptime_decls.append(gpa, unit.unwrap().@"comptime");
3200 } else {
3201 const cu = try ip.createComptimeUnit(gpa, io, pt.tid, tracked_inst, namespace_index);
3202 try zcu.queueComptimeUnitAnalysis(cu);
28183203 try namespace.comptime_decls.append(gpa, cu);
3204 }
3205 return;
3206 };
28193207
2820 if (existing_unit == null) {
2821 // For a `comptime` declaration, whether to analyze is based solely on whether the unit
2822 // is outdated. So, add this fresh one to `outdated` and `outdated_ready`.
2823 try zcu.outdated.ensureUnusedCapacity(gpa, 1);
2824 try zcu.outdated_ready.ensureUnusedCapacity(gpa, 1);
2825 zcu.outdated.putAssumeCapacityNoClobber(unit, 0);
2826 zcu.outdated_ready.putAssumeCapacityNoClobber(unit, {});
2827 }
3208 const fqn = try namespace.internFullyQualifiedName(ip, gpa, io, pt.tid, name);
3209
3210 const nav = if (existing_unit) |unit| nav: {
3211 const nav = unit.unwrap().nav_val;
3212 assert(ip.getNav(nav).name == name);
3213 assert(ip.getNav(nav).fqn == fqn);
3214 break :nav nav;
3215 } else nav: {
3216 const nav = try ip.createDeclNav(gpa, io, pt.tid, name, fqn, tracked_inst, namespace_index);
3217 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newNav(zcu, nav);
3218 break :nav nav;
3219 };
28283220
2829 break :unit .{ unit, true };
3221 const want_analysis: bool = switch (decl.kind) {
3222 .@"comptime" => unreachable,
3223 .unnamed_test, .@"test", .decltest => a: {
3224 const is_named = decl.kind != .unnamed_test;
3225 try namespace.test_decls.append(gpa, nav);
3226 // TODO: incremental compilation!
3227 // * remove from `test_functions` if no longer matching filter
3228 // * add to `test_functions` if newly passing filter
3229 // This logic is unaware of incremental: we'll end up with duplicates.
3230 // Perhaps we should add all test indiscriminately and filter at the end of the update.
3231 if (!comp.config.is_test) break :a false;
3232 if (file.mod != zcu.main_mod) break :a false;
3233 if (is_named and comp.test_filters.len > 0) {
3234 const fqn_slice = fqn.toSlice(ip);
3235 for (comp.test_filters) |test_filter| {
3236 if (std.mem.indexOf(u8, fqn_slice, test_filter) != null) break;
3237 } else break :a false;
3238 }
3239 try zcu.test_functions.put(gpa, nav, {});
3240 break :a true;
28303241 },
2831 else => unit: {
2832 const name = maybe_name.unwrap().?;
2833 const fqn = try namespace.internFullyQualifiedName(ip, gpa, io, pt.tid, name);
2834 const nav = if (existing_unit) |eu| eu.unwrap().nav_val else nav: {
2835 const nav = try ip.createDeclNav(gpa, io, pt.tid, name, fqn, tracked_inst, namespace_index);
2836 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newNav(zcu, nav);
2837 break :nav nav;
2838 };
2839
2840 const unit: AnalUnit = .wrap(.{ .nav_val = nav });
2841
2842 assert(ip.getNav(nav).name == name);
2843 assert(ip.getNav(nav).fqn == fqn);
2844
2845 const want_analysis = switch (decl.kind) {
2846 .@"comptime" => unreachable,
2847 .unnamed_test, .@"test", .decltest => a: {
2848 const is_named = decl.kind != .unnamed_test;
2849 try namespace.test_decls.append(gpa, nav);
2850 // TODO: incremental compilation!
2851 // * remove from `test_functions` if no longer matching filter
2852 // * add to `test_functions` if newly passing filter
2853 // This logic is unaware of incremental: we'll end up with duplicates.
2854 // Perhaps we should add all test indiscriminately and filter at the end of the update.
2855 if (!comp.config.is_test) break :a false;
2856 if (file.mod != zcu.main_mod) break :a false;
2857 if (is_named and comp.test_filters.len > 0) {
2858 const fqn_slice = fqn.toSlice(ip);
2859 for (comp.test_filters) |test_filter| {
2860 if (std.mem.indexOf(u8, fqn_slice, test_filter) != null) break;
2861 } else break :a false;
2862 }
2863 try zcu.test_functions.put(gpa, nav, {});
2864 break :a true;
2865 },
2866 .@"const", .@"var" => a: {
2867 if (decl.is_pub) {
2868 try namespace.pub_decls.putContext(gpa, nav, {}, .{ .zcu = zcu });
2869 } else {
2870 try namespace.priv_decls.putContext(gpa, nav, {}, .{ .zcu = zcu });
2871 }
2872 break :a false;
2873 },
2874 };
2875 break :unit .{ unit, want_analysis };
3242 .@"const", .@"var" => a: {
3243 if (decl.is_pub) {
3244 try namespace.pub_decls.putContext(gpa, nav, {}, .{ .zcu = zcu });
3245 } else {
3246 try namespace.priv_decls.putContext(gpa, nav, {}, .{ .zcu = zcu });
3247 }
3248 break :a false;
28763249 },
28773250 };
28783251
2879 if (existing_unit == null and (want_analysis or decl.linkage == .@"export")) {
2880 log.debug(
2881 "scanDecl queue analyze_comptime_unit file='{s}' unit={f}",
2882 .{ namespace.fileScope(zcu).sub_file_path, zcu.fmtAnalUnit(unit) },
2883 );
2884 try comp.queueJob(.{ .analyze_comptime_unit = unit });
3252 if (want_analysis or decl.linkage == .@"export") {
3253 try zcu.ensureNavValAnalysisQueued(nav);
28853254 }
28863255 }
28873256};
28883257
2889fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaError!Air {
2890 const tracy = trace(@src());
2891 defer tracy.end();
3258fn analyzeFuncBodyInner(
3259 pt: Zcu.PerThread,
3260 func_index: InternPool.Index,
3261 reason: ?*const Zcu.DependencyReason,
3262) Zcu.SemaError!Air {
3263 const tracy_trace = trace(@src());
3264 defer tracy_trace.end();
28923265
28933266 const zcu = pt.zcu;
28943267 const comp = zcu.comp;
......@@ -2898,17 +3271,18 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
28983271
28993272 const anal_unit = AnalUnit.wrap(.{ .func = func_index });
29003273 const func = zcu.funcInfo(func_index);
2901 const inst_info = func.zir_body_inst.resolveFull(ip) orelse return error.AnalysisFail;
2902 const file = zcu.fileByIndex(inst_info.file);
2903 const zir = file.zir.?;
29043274
2905 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, {});
2906 errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit);
3275 // This is the `Nav` corresponding to the `declaration` instruction which the function or its generic owner originates from.
3276 const decl_analysis = if (func.generic_owner == .none)
3277 ip.getNav(func.owner_nav).analysis.?
3278 else
3279 ip.getNav(zcu.funcInfo(func.generic_owner).owner_nav).analysis.?;
29073280
2908 func.setAnalyzed(ip, io);
2909 if (func.analysisUnordered(ip).inferred_error_set) {
2910 func.setResolvedErrorSet(ip, io, .none);
2911 }
3281 const file = zcu.fileByIndex(decl_analysis.zir_index.resolveFile(ip));
3282 const zir = file.zir.?;
3283
3284 try zcu.analysis_in_progress.putNoClobber(gpa, anal_unit, reason);
3285 defer assert(zcu.analysis_in_progress.swapRemove(anal_unit));
29123286
29133287 if (zcu.comp.time_report) |*tr| {
29143288 if (func.generic_owner != .none) {
......@@ -2916,16 +3290,8 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
29163290 }
29173291 }
29183292
2919 // This is the `Nau` corresponding to the `declaration` instruction which the function or its generic owner originates from.
2920 const decl_nav = ip.getNav(if (func.generic_owner == .none)
2921 func.owner_nav
2922 else
2923 zcu.funcInfo(func.generic_owner).owner_nav);
2924
29253293 const func_nav = ip.getNav(func.owner_nav);
29263294
2927 zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit);
2928
29293295 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
29303296 defer analysis_arena.deinit();
29313297
......@@ -2957,9 +3323,30 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
29573323
29583324 // Every runtime function has a dependency on the source of the Decl it originates from.
29593325 // It also depends on the value of its owner Decl.
2960 try sema.declareDependency(.{ .src_hash = decl_nav.analysis.?.zir_index });
3326 try sema.declareDependency(.{ .src_hash = decl_analysis.zir_index });
29613327 try sema.declareDependency(.{ .nav_val = func.owner_nav });
29623328
3329 // Make sure that the declaration `Nav` still refers to this function (or its generic owner).
3330 // This will not be the case if the incremental update has changed a function type or turned a
3331 // `fn` decl into some other declaration. In that case, we must not run analysis: this function
3332 // will not be referenced this update, and trying to generate it could be problematic since we
3333 // assume the owner NAV actually, um, owns us.
3334 //
3335 // If we *are* still owned by the right NAV, this analysis updates `zir_body_inst` if necessary.
3336
3337 if (func.generic_owner == .none) {
3338 try pt.ensureNavValUpToDate(func.owner_nav, reason);
3339 if (ip.getNav(func.owner_nav).status.fully_resolved.val != func_index) {
3340 return error.AnalysisFail;
3341 }
3342 } else {
3343 const go_nav = zcu.funcInfo(func.generic_owner).owner_nav;
3344 try pt.ensureNavValUpToDate(go_nav, reason);
3345 if (ip.getNav(go_nav).status.fully_resolved.val != func.generic_owner) {
3346 return error.AnalysisFail;
3347 }
3348 }
3349
29633350 if (func.analysisUnordered(ip).inferred_error_set) {
29643351 const ies = try analysis_arena.allocator().create(Sema.InferredErrorSet);
29653352 ies.* = .{ .func = func_index };
......@@ -2977,11 +3364,11 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
29773364 var inner_block: Sema.Block = .{
29783365 .parent = null,
29793366 .sema = &sema,
2980 .namespace = decl_nav.analysis.?.namespace,
2981 .instructions = .{},
3367 .namespace = decl_analysis.namespace,
3368 .instructions = .empty,
29823369 .inlining = null,
29833370 .comptime_reason = null,
2984 .src_base_inst = decl_nav.analysis.?.zir_index,
3371 .src_base_inst = decl_analysis.zir_index,
29853372 .type_name_ctx = func_nav.fqn,
29863373 };
29873374 defer inner_block.instructions.deinit(gpa);
......@@ -3020,16 +3407,21 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
30203407 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);
30213408 if (gop.found_existing) continue; // provided above by comptime arg
30223409
3023 const param_ty = fn_ty_info.param_types.get(ip)[runtime_param_index];
3410 const param_ty: Type = .fromInterned(fn_ty_info.param_types.get(ip)[runtime_param_index]);
30243411 runtime_param_index += 1;
30253412
3026 const opt_opv = sema.typeHasOnePossibleValue(Type.fromInterned(param_ty)) catch |err| switch (err) {
3027 error.ComptimeReturn => unreachable,
3028 error.ComptimeBreak => unreachable,
3029 else => |e| return e,
3030 };
3031 if (opt_opv) |opv| {
3032 gop.value_ptr.* = Air.internedToRef(opv.toIntern());
3413 if (param_ty.isGenericPoison()) {
3414 // We're guaranteed to get a compile error on the `fnHasRuntimeBits` check after this
3415 // loop (the generic poison means this is a generic function). But `continue` here to
3416 // avoid an illegal call to `onePossibleValue` below.
3417 continue;
3418 }
3419
3420 const param_ty_src = inner_block.src(.{ .func_decl_param_ty = @intCast(zir_param_index) });
3421
3422 try sema.ensureLayoutResolved(param_ty, param_ty_src, .parameter);
3423 if (try param_ty.onePossibleValue(pt)) |opv| {
3424 gop.value_ptr.* = .fromValue(opv);
30333425 continue;
30343426 }
30353427 const arg_index: Air.Inst.Index = @enumFromInt(sema.air_instructions.len);
......@@ -3038,12 +3430,31 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
30383430 sema.air_instructions.appendAssumeCapacity(.{
30393431 .tag = .arg,
30403432 .data = .{ .arg = .{
3041 .ty = Air.internedToRef(param_ty),
3433 .ty = .fromIntern(param_ty.toIntern()),
30423434 .zir_param_index = @intCast(zir_param_index),
30433435 } },
30443436 });
30453437 }
30463438
3439 try sema.ensureLayoutResolved(sema.fn_ret_ty, inner_block.src(.{ .node_offset_fn_type_ret_ty = .zero }), .return_type);
3440
3441 // The function type is now resolved, so we're ready to check whether it even makes sense to ask
3442 // for it to be analyzed at runtime.
3443 if (!fn_ty.fnHasRuntimeBits(zcu)) {
3444 const description: []const u8 = switch (fn_ty_info.cc) {
3445 .@"inline" => "inline",
3446 else => "generic",
3447 };
3448 // This error makes sense because the only reason this analysis would ever be requested is
3449 // for IES resolution.
3450 return sema.fail(
3451 &inner_block,
3452 inner_block.nodeOffset(.zero),
3453 "cannot resolve inferred error set of {s} function type '{f}'",
3454 .{ description, fn_ty.fmt(pt) },
3455 );
3456 }
3457
30473458 const last_arg_index = inner_block.instructions.items.len;
30483459
30493460 // Save the error trace as our first action in the function.
......@@ -3103,21 +3514,6 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
31033514 func.setResolvedErrorSet(ip, io, ies.resolved);
31043515 }
31053516
3106 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
3107
3108 // Finally we must resolve the return type and parameter types so that backends
3109 // have full access to type information.
3110 // Crucially, this happens *after* we set the function state to success above,
3111 // so that dependencies on the function body will now be satisfied rather than
3112 // result in circular dependency errors.
3113 // TODO: this can go away once we fix backends having to resolve `StackTrace`.
3114 // The codegen timing guarantees that the parameter types will be populated.
3115 sema.resolveFnTypes(fn_ty, inner_block.nodeOffset(.zero)) catch |err| switch (err) {
3116 error.ComptimeReturn => unreachable,
3117 error.ComptimeBreak => unreachable,
3118 else => |e| return e,
3119 };
3120
31213517 try sema.flushExports();
31223518
31233519 defer {
......@@ -3244,7 +3640,7 @@ pub fn processExports(pt: Zcu.PerThread) !void {
32443640 break :gop .{ gop.value_ptr, gop.found_existing };
32453641 },
32463642 };
3247 if (!found_existing) value_ptr.* = .{};
3643 if (!found_existing) value_ptr.* = .empty;
32483644 try value_ptr.append(gpa, export_idx);
32493645 }
32503646
......@@ -3273,7 +3669,7 @@ pub fn processExports(pt: Zcu.PerThread) !void {
32733669 break :gop .{ gop.value_ptr, gop.found_existing };
32743670 },
32753671 };
3276 if (!found_existing) value_ptr.* = .{};
3672 if (!found_existing) value_ptr.* = .empty;
32773673 try value_ptr.append(gpa, @enumFromInt(export_idx));
32783674 }
32793675 }
......@@ -3545,36 +3941,45 @@ pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool
35453941
35463942/// Essentially a shortcut for calling `intern_pool.getCoerced`.
35473943/// However, this function also allows coercing `extern`s. The `InternPool` function can't do
3548/// this because it requires potentially pushing to the job queue.
3944/// this because it requires potentially queueing a link task.
35493945pub fn getCoerced(pt: Zcu.PerThread, val: Value, new_ty: Type) Allocator.Error!Value {
35503946 const ip = &pt.zcu.intern_pool;
35513947 const comp = pt.zcu.comp;
35523948 const gpa = comp.gpa;
35533949 const io = comp.io;
35543950 switch (ip.indexToKey(val.toIntern())) {
3555 .@"extern" => |e| {
3556 const coerced = try pt.getExtern(.{
3557 .name = e.name,
3951 .@"extern" => |@"extern"| {
3952 // TODO: it's awkward to make this function cancelable. The problem is really that
3953 // `getCoerced` is a bad API: it should be replaced with smaller, more specialized
3954 // functions, so that this cancel point is only possible in the rare case that you
3955 // may actually need to coerce an extern!
3956 const old_prot = io.swapCancelProtection(.blocked);
3957 defer _ = io.swapCancelProtection(old_prot);
3958 const coerced = pt.getExtern(.{
3959 .name = @"extern".name,
35583960 .ty = new_ty.toIntern(),
3559 .lib_name = e.lib_name,
3560 .is_const = e.is_const,
3561 .is_threadlocal = e.is_threadlocal,
3562 .linkage = e.linkage,
3563 .visibility = e.visibility,
3564 .is_dll_import = e.is_dll_import,
3565 .relocation = e.relocation,
3566 .decoration = e.decoration,
3567 .alignment = e.alignment,
3568 .@"addrspace" = e.@"addrspace",
3569 .zir_index = e.zir_index,
3961 .lib_name = @"extern".lib_name,
3962 .is_const = @"extern".is_const,
3963 .is_threadlocal = @"extern".is_threadlocal,
3964 .linkage = @"extern".linkage,
3965 .visibility = @"extern".visibility,
3966 .is_dll_import = @"extern".is_dll_import,
3967 .relocation = @"extern".relocation,
3968 .decoration = @"extern".decoration,
3969 .alignment = @"extern".alignment,
3970 .@"addrspace" = @"extern".@"addrspace",
3971 .zir_index = @"extern".zir_index,
35703972 .owner_nav = undefined, // ignored by `getExtern`.
3571 .source = e.source,
3572 });
3573 return Value.fromInterned(coerced);
3973 .source = @"extern".source,
3974 }) catch |err| switch (err) {
3975 error.Canceled => unreachable, // blocked above
3976 error.OutOfMemory => |e| return e,
3977 };
3978 return .fromInterned(coerced);
35743979 },
35753980 else => {},
35763981 }
3577 return Value.fromInterned(try ip.getCoerced(gpa, io, pt.tid, val.toIntern(), new_ty.toIntern()));
3982 return .fromInterned(try ip.getCoerced(gpa, io, pt.tid, val.toIntern(), new_ty.toIntern()));
35783983}
35793984
35803985pub fn intType(pt: Zcu.PerThread, signedness: std.builtin.Signedness, bits: u16) Allocator.Error!Type {
......@@ -3605,16 +4010,6 @@ pub fn ptrType(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Allocator.Error!
36054010
36064011 if (info.flags.size == .c) canon_info.flags.is_allowzero = true;
36074012
3608 // Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee
3609 // type, we change it to 0 here. If this causes an assertion trip because the
3610 // pointee type needs to be resolved more, that needs to be done before calling
3611 // this ptr() function.
3612 if (info.flags.alignment != .none and
3613 info.flags.alignment == Type.fromInterned(info.child).abiAlignment(pt.zcu))
3614 {
3615 canon_info.flags.alignment = .none;
3616 }
3617
36184013 switch (info.flags.vector_index) {
36194014 // Canonicalize host_size. If it matches the bit size of the pointee type,
36204015 // we change it to 0 here. If this causes an assertion trip, the pointee type
......@@ -3632,16 +4027,6 @@ pub fn ptrType(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Allocator.Error!
36324027 return Type.fromInterned(try pt.intern(.{ .ptr_type = canon_info }));
36334028}
36344029
3635/// Like `ptrType`, but if `info` specifies an `alignment`, first ensures the pointer
3636/// child type's alignment is resolved so that an invalid alignment is not used.
3637/// In general, prefer this function during semantic analysis.
3638pub fn ptrTypeSema(pt: Zcu.PerThread, info: InternPool.Key.PtrType) Zcu.SemaError!Type {
3639 if (info.flags.alignment != .none) {
3640 _ = try Type.fromInterned(info.child).abiAlignmentSema(pt);
3641 }
3642 return pt.ptrType(info);
3643}
3644
36454030pub fn singleMutPtrType(pt: Zcu.PerThread, child_type: Type) Allocator.Error!Type {
36464031 return pt.ptrType(.{ .child = child_type.toIntern() });
36474032}
......@@ -3741,29 +4126,54 @@ pub fn enumValueFieldIndex(pt: Zcu.PerThread, ty: Type, field_index: u32) Alloca
37414126 const ip = &pt.zcu.intern_pool;
37424127 const enum_type = ip.loadEnumType(ty.toIntern());
37434128
3744 if (enum_type.values.len == 0) {
4129 assert(field_index < enum_type.field_names.len);
4130
4131 if (enum_type.field_values.len == 0) {
37454132 // Auto-numbered fields.
37464133 return Value.fromInterned(try pt.intern(.{ .enum_tag = .{
37474134 .ty = ty.toIntern(),
37484135 .int = try pt.intern(.{ .int = .{
3749 .ty = enum_type.tag_ty,
4136 .ty = enum_type.int_tag_type,
37504137 .storage = .{ .u64 = field_index },
37514138 } }),
37524139 } }));
37534140 }
37544141
3755 return Value.fromInterned(try pt.intern(.{ .enum_tag = .{
4142 return .fromInterned(try pt.intern(.{ .enum_tag = .{
37564143 .ty = ty.toIntern(),
3757 .int = enum_type.values.get(ip)[field_index],
4144 .int = enum_type.field_values.get(ip)[field_index],
37584145 } }));
37594146}
37604147
37614148pub fn undefValue(pt: Zcu.PerThread, ty: Type) Allocator.Error!Value {
3762 return Value.fromInterned(try pt.intern(.{ .undef = ty.toIntern() }));
4149 if (std.debug.runtime_safety) {
4150 // TODO: values of type `struct { comptime x: u8 = undefined }` are currently represented as
4151 // undef. This is wrong: they should really be represented as empty aggregates instead,
4152 // because `comptime` fields shouldn't factor into that decision! This is implemented
4153 // through logic in `aggregateValue` and requires this weird workaround in what ought to be
4154 // a straightforward assertion:
4155 //assert(ty.classify(pt.zcu) != .one_possible_value);
4156 if (ty.classify(pt.zcu) == .one_possible_value) {
4157 const ip = &pt.zcu.intern_pool;
4158 switch (ip.indexToKey(ty.toIntern())) {
4159 else => unreachable, // assertion failure
4160 .struct_type => {
4161 const comptime_bits = ip.loadStructType(ty.toIntern()).field_is_comptime_bits.getAll(ip);
4162 for (comptime_bits) |bag| {
4163 if (@popCount(bag) > 0) break;
4164 } else unreachable; // assertion failure
4165 },
4166 .tuple_type => |tuple| for (tuple.values.get(ip)) |val| {
4167 if (val != .none) break;
4168 } else unreachable, // assertion failure
4169 }
4170 }
4171 }
4172 return .fromInterned(try pt.intern(.{ .undef = ty.toIntern() }));
37634173}
37644174
37654175pub fn undefRef(pt: Zcu.PerThread, ty: Type) Allocator.Error!Air.Inst.Ref {
3766 return Air.internedToRef((try pt.undefValue(ty)).toIntern());
4176 return .fromValue(try pt.undefValue(ty));
37674177}
37684178
37694179pub fn intValue(pt: Zcu.PerThread, ty: Type, x: anytype) Allocator.Error!Value {
......@@ -3839,7 +4249,7 @@ pub fn aggregateValue(pt: Zcu.PerThread, ty: Type, elems: []const InternPool.Ind
38394249 for (elems) |elem| {
38404250 if (!Value.fromInterned(elem).isUndef(pt.zcu)) break;
38414251 } else if (elems.len > 0) {
3842 return pt.undefValue(ty); // all-undef
4252 return pt.undefValue(ty);
38434253 }
38444254 return .fromInterned(try pt.intern(.{ .aggregate = .{
38454255 .ty = ty.toIntern(),
......@@ -3877,6 +4287,15 @@ pub fn floatValue(pt: Zcu.PerThread, ty: Type, x: anytype) Allocator.Error!Value
38774287 } }));
38784288}
38794289
4290/// Create a value whose type is a `packed struct` or `packed union`, from the backing integer value.
4291pub fn bitpackValue(pt: Zcu.PerThread, ty: Type, backing_int_val: Value) Allocator.Error!Value {
4292 assert(backing_int_val.typeOf(pt.zcu).toIntern() == ty.bitpackBackingInt(pt.zcu).toIntern());
4293 return .fromInterned(try pt.intern(.{ .bitpack = .{
4294 .ty = ty.toIntern(),
4295 .backing_int_val = backing_int_val.toIntern(),
4296 } }));
4297}
4298
38804299pub fn nullValue(pt: Zcu.PerThread, opt_ty: Type) Allocator.Error!Value {
38814300 assert(pt.zcu.intern_pool.isOptionalType(opt_ty.toIntern()));
38824301 return Value.fromInterned(try pt.intern(.{ .opt = .{
......@@ -3916,7 +4335,7 @@ pub fn intFittingRange(pt: Zcu.PerThread, min: Value, max: Value) !Type {
39164335 assert(Value.order(min, max, zcu).compare(.lte));
39174336 }
39184337
3919 const sign = min.orderAgainstZero(zcu) == .lt;
4338 const sign = min.compareHetero(.lt, .zero_comptime_int, zcu);
39204339
39214340 const min_val_bits = pt.intBitsForValue(min, sign);
39224341 const max_val_bits = pt.intBitsForValue(max, sign);
......@@ -3955,12 +4374,6 @@ pub fn intBitsForValue(pt: Zcu.PerThread, val: Value, sign: bool) u16 {
39554374
39564375 return @as(u16, @intCast(big.bitCountTwosComp()));
39574376 },
3958 .lazy_align => |lazy_ty| {
3959 return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiAlignment(pt.zcu).toByteUnits() orelse 0) + @intFromBool(sign);
3960 },
3961 .lazy_size => |lazy_ty| {
3962 return Type.smallestUnsignedBits(Type.fromInterned(lazy_ty).abiSize(pt.zcu)) + @intFromBool(sign);
3963 },
39644377 }
39654378}
39664379
......@@ -3975,10 +4388,7 @@ pub fn navPtrType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Allocator.Err
39754388 return pt.ptrType(.{
39764389 .child = ty,
39774390 .flags = .{
3978 .alignment = if (alignment == Type.fromInterned(ty).abiAlignment(zcu))
3979 .none
3980 else
3981 alignment,
4391 .alignment = alignment,
39824392 .address_space = @"addrspace",
39834393 .is_const = is_const,
39844394 },
......@@ -3988,392 +4398,19 @@ pub fn navPtrType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Allocator.Err
39884398/// Intern an `.@"extern"`, creating a corresponding owner `Nav` if necessary.
39894399/// If necessary, the new `Nav` is queued for codegen.
39904400/// `key.owner_nav` is ignored and may be `undefined`.
3991pub fn getExtern(pt: Zcu.PerThread, key: InternPool.Key.Extern) Allocator.Error!InternPool.Index {
4401pub fn getExtern(pt: Zcu.PerThread, key: InternPool.Key.Extern) (Io.Cancelable || Allocator.Error)!InternPool.Index {
39924402 const zcu = pt.zcu;
39934403 const comp = zcu.comp;
4404 Type.fromInterned(key.ty).assertHasLayout(zcu);
39944405 const result = try zcu.intern_pool.getExtern(comp.gpa, comp.io, pt.tid, key);
39954406 if (result.new_nav.unwrap()) |nav| {
3996 // This job depends on any resolve_type_fully jobs queued up before it.
3997 comp.link_prog_node.increaseEstimatedTotalItems(1);
3998 try comp.queueJob(.{ .link_nav = nav });
39994407 if (comp.debugIncremental()) try zcu.incremental_debug_state.newNav(zcu, nav);
4408 comp.link_prog_node.increaseEstimatedTotalItems(1);
4409 try comp.link_queue.enqueueZcu(comp, pt.tid, .{ .link_nav = nav });
40004410 }
40014411 return result.index;
40024412}
40034413
4004// TODO: this shouldn't need a `PerThread`! Fix the signature of `Type.abiAlignment`.
4005pub fn navAlignment(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) InternPool.Alignment {
4006 const zcu = pt.zcu;
4007 const ty: Type, const alignment = switch (zcu.intern_pool.getNav(nav_index).status) {
4008 .unresolved => unreachable,
4009 .type_resolved => |r| .{ .fromInterned(r.type), r.alignment },
4010 .fully_resolved => |r| .{ Value.fromInterned(r.val).typeOf(zcu), r.alignment },
4011 };
4012 if (alignment != .none) return alignment;
4013 return ty.abiAlignment(zcu);
4014}
4015
4016/// `ty` is a container type requiring resolution (struct, union, or enum).
4017/// If `ty` is outdated, it is recreated at a new `InternPool.Index`, which is returned.
4018/// If the type cannot be recreated because it has been lost, `error.AnalysisFail` is returned.
4019/// If `ty` is not outdated, that same `InternPool.Index` is returned.
4020/// If `ty` has already been replaced by this function, the new index will not be returned again.
4021/// Also, if `ty` is an enum, this function will resolve the new type if needed, and the call site
4022/// is responsible for checking `[transitive_]failed_analysis` to detect resolution failures.
4023pub fn ensureTypeUpToDate(pt: Zcu.PerThread, ty: InternPool.Index) Zcu.SemaError!InternPool.Index {
4024 const zcu = pt.zcu;
4025 const gpa = zcu.gpa;
4026 const ip = &zcu.intern_pool;
4027
4028 const anal_unit: AnalUnit = .wrap(.{ .type = ty });
4029 const outdated = zcu.outdated.swapRemove(anal_unit) or
4030 zcu.potentially_outdated.swapRemove(anal_unit);
4031
4032 if (outdated) {
4033 _ = zcu.outdated_ready.swapRemove(anal_unit);
4034 try zcu.markDependeeOutdated(.marked_po, .{ .interned = ty });
4035 }
4036
4037 const ty_key = switch (ip.indexToKey(ty)) {
4038 .struct_type, .union_type, .enum_type => |key| key,
4039 else => unreachable,
4040 };
4041 const declared_ty_key = switch (ty_key) {
4042 .reified => unreachable, // never outdated
4043 .generated_tag => unreachable, // never outdated
4044 .declared => |d| d,
4045 };
4046
4047 if (declared_ty_key.zir_index.resolve(ip) == null) {
4048 // The instruction has been lost -- this type is dead.
4049 return error.AnalysisFail;
4050 }
4051
4052 if (!outdated) return ty;
4053
4054 // We will recreate the type at a new `InternPool.Index`.
4055
4056 // Delete old state which is no longer in use. Technically, this is not necessary: these exports,
4057 // references, etc, will be ignored because the type itself is unreferenced. However, it allows
4058 // reusing the memory which is currently being used to track this state.
4059 zcu.deleteUnitExports(anal_unit);
4060 zcu.deleteUnitReferences(anal_unit);
4061 zcu.deleteUnitCompileLogs(anal_unit);
4062 if (zcu.failed_analysis.fetchSwapRemove(anal_unit)) |kv| {
4063 kv.value.destroy(gpa);
4064 }
4065 _ = zcu.transitive_failed_analysis.swapRemove(anal_unit);
4066 zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit);
4067
4068 if (zcu.comp.debugIncremental()) {
4069 const info = try zcu.incremental_debug_state.getUnitInfo(gpa, anal_unit);
4070 info.last_update_gen = zcu.generation;
4071 info.deps.clearRetainingCapacity();
4072 }
4073
4074 switch (ip.indexToKey(ty)) {
4075 .struct_type => return pt.recreateStructType(ty, declared_ty_key),
4076 .union_type => return pt.recreateUnionType(ty, declared_ty_key),
4077 .enum_type => return pt.recreateEnumType(ty, declared_ty_key),
4078 else => unreachable,
4079 }
4080}
4081
4082fn recreateStructType(
4083 pt: Zcu.PerThread,
4084 old_ty: InternPool.Index,
4085 key: InternPool.Key.NamespaceType.Declared,
4086) Allocator.Error!InternPool.Index {
4087 const zcu = pt.zcu;
4088 const comp = zcu.comp;
4089 const gpa = comp.gpa;
4090 const io = comp.io;
4091 const ip = &zcu.intern_pool;
4092
4093 const inst_info = key.zir_index.resolveFull(ip).?;
4094 const file = zcu.fileByIndex(inst_info.file);
4095 const zir = file.zir.?;
4096
4097 assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended);
4098 const extended = zir.instructions.items(.data)[@intFromEnum(inst_info.inst)].extended;
4099 assert(extended.opcode == .struct_decl);
4100 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
4101 const extra = zir.extraData(Zir.Inst.StructDecl, extended.operand);
4102 var extra_index = extra.end;
4103
4104 const captures_len = if (small.has_captures_len) blk: {
4105 const captures_len = zir.extra[extra_index];
4106 extra_index += 1;
4107 break :blk captures_len;
4108 } else 0;
4109 const fields_len = if (small.has_fields_len) blk: {
4110 const fields_len = zir.extra[extra_index];
4111 extra_index += 1;
4112 break :blk fields_len;
4113 } else 0;
4114
4115 assert(captures_len == key.captures.owned.len); // synchronises with logic in `Zcu.mapOldZirToNew`
4116
4117 const struct_obj = ip.loadStructType(old_ty);
4118
4119 const wip_ty = switch (try ip.getStructType(gpa, io, pt.tid, .{
4120 .layout = small.layout,
4121 .fields_len = fields_len,
4122 .known_non_opv = small.known_non_opv,
4123 .requires_comptime = if (small.known_comptime_only) .yes else .unknown,
4124 .any_comptime_fields = small.any_comptime_fields,
4125 .any_default_inits = small.any_default_inits,
4126 .inits_resolved = false,
4127 .any_aligned_fields = small.any_aligned_fields,
4128 .key = .{ .declared_owned_captures = .{
4129 .zir_index = key.zir_index,
4130 .captures = key.captures.owned,
4131 } },
4132 }, true)) {
4133 .wip => |wip| wip,
4134 .existing => unreachable, // we passed `replace_existing`
4135 };
4136 errdefer wip_ty.cancel(ip, pt.tid);
4137
4138 wip_ty.setName(ip, struct_obj.name, struct_obj.name_nav);
4139 try pt.addDependency(.wrap(.{ .type = wip_ty.index }), .{ .src_hash = key.zir_index });
4140 zcu.namespacePtr(struct_obj.namespace).owner_type = wip_ty.index;
4141 // No need to re-scan the namespace -- `zirStructDecl` will ultimately do that if the type is still alive.
4142 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
4143
4144 codegen_type: {
4145 if (file.mod.?.strip) break :codegen_type;
4146 // This job depends on any resolve_type_fully jobs queued up before it.
4147 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
4148 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
4149 }
4150
4151 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
4152 const new_ty = wip_ty.finish(ip, struct_obj.namespace);
4153 if (inst_info.inst == .main_struct_inst) {
4154 // This is the root type of a file! Update the reference.
4155 zcu.setFileRootType(inst_info.file, new_ty);
4156 }
4157 return new_ty;
4158}
4159
4160fn recreateUnionType(
4161 pt: Zcu.PerThread,
4162 old_ty: InternPool.Index,
4163 key: InternPool.Key.NamespaceType.Declared,
4164) Allocator.Error!InternPool.Index {
4165 const zcu = pt.zcu;
4166 const comp = zcu.comp;
4167 const gpa = comp.gpa;
4168 const io = comp.io;
4169 const ip = &zcu.intern_pool;
4170
4171 const inst_info = key.zir_index.resolveFull(ip).?;
4172 const file = zcu.fileByIndex(inst_info.file);
4173 const zir = file.zir.?;
4174
4175 assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended);
4176 const extended = zir.instructions.items(.data)[@intFromEnum(inst_info.inst)].extended;
4177 assert(extended.opcode == .union_decl);
4178 const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small);
4179 const extra = zir.extraData(Zir.Inst.UnionDecl, extended.operand);
4180 var extra_index = extra.end;
4181
4182 extra_index += @intFromBool(small.has_tag_type);
4183 const captures_len = if (small.has_captures_len) blk: {
4184 const captures_len = zir.extra[extra_index];
4185 extra_index += 1;
4186 break :blk captures_len;
4187 } else 0;
4188 extra_index += @intFromBool(small.has_body_len);
4189 const fields_len = if (small.has_fields_len) blk: {
4190 const fields_len = zir.extra[extra_index];
4191 extra_index += 1;
4192 break :blk fields_len;
4193 } else 0;
4194
4195 assert(captures_len == key.captures.owned.len); // synchronises with logic in `Zcu.mapOldZirToNew`
4196
4197 const union_obj = ip.loadUnionType(old_ty);
4198
4199 const namespace_index = union_obj.namespace;
4200
4201 const wip_ty = switch (try ip.getUnionType(gpa, io, pt.tid, .{
4202 .flags = .{
4203 .layout = small.layout,
4204 .status = .none,
4205 .runtime_tag = if (small.has_tag_type or small.auto_enum_tag)
4206 .tagged
4207 else if (small.layout != .auto)
4208 .none
4209 else switch (true) { // TODO
4210 true => .safety,
4211 false => .none,
4212 },
4213 .any_aligned_fields = small.any_aligned_fields,
4214 .requires_comptime = .unknown,
4215 .assumed_runtime_bits = false,
4216 .assumed_pointer_aligned = false,
4217 .alignment = .none,
4218 },
4219 .fields_len = fields_len,
4220 .enum_tag_ty = .none, // set later
4221 .field_types = &.{}, // set later
4222 .field_aligns = &.{}, // set later
4223 .key = .{ .declared_owned_captures = .{
4224 .zir_index = key.zir_index,
4225 .captures = key.captures.owned,
4226 } },
4227 }, true)) {
4228 .wip => |wip| wip,
4229 .existing => unreachable, // we passed `replace_existing`
4230 };
4231 errdefer wip_ty.cancel(ip, pt.tid);
4232
4233 wip_ty.setName(ip, union_obj.name, union_obj.name_nav);
4234 try pt.addDependency(.wrap(.{ .type = wip_ty.index }), .{ .src_hash = key.zir_index });
4235 zcu.namespacePtr(namespace_index).owner_type = wip_ty.index;
4236 // No need to re-scan the namespace -- `zirUnionDecl` will ultimately do that if the type is still alive.
4237 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
4238
4239 codegen_type: {
4240 if (file.mod.?.strip) break :codegen_type;
4241 // This job depends on any resolve_type_fully jobs queued up before it.
4242 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
4243 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
4244 }
4245
4246 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
4247 return wip_ty.finish(ip, namespace_index);
4248}
4249
4250/// This *does* call `Sema.resolveDeclaredEnum`, but errors from it are not propagated.
4251/// Call sites are resposible for checking `[transitive_]failed_analysis` after `ensureTypeUpToDate`
4252/// returns in order to detect resolution failures.
4253fn recreateEnumType(
4254 pt: Zcu.PerThread,
4255 old_ty: InternPool.Index,
4256 key: InternPool.Key.NamespaceType.Declared,
4257) (Allocator.Error || Io.Cancelable)!InternPool.Index {
4258 const zcu = pt.zcu;
4259 const comp = zcu.comp;
4260 const gpa = comp.gpa;
4261 const io = comp.io;
4262 const ip = &zcu.intern_pool;
4263
4264 const inst_info = key.zir_index.resolveFull(ip).?;
4265 const file = zcu.fileByIndex(inst_info.file);
4266 const zir = file.zir.?;
4267
4268 assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended);
4269 const extended = zir.instructions.items(.data)[@intFromEnum(inst_info.inst)].extended;
4270 assert(extended.opcode == .enum_decl);
4271 const small: Zir.Inst.EnumDecl.Small = @bitCast(extended.small);
4272 const extra = zir.extraData(Zir.Inst.EnumDecl, extended.operand);
4273 var extra_index = extra.end;
4274
4275 const tag_type_ref = if (small.has_tag_type) blk: {
4276 const tag_type_ref: Zir.Inst.Ref = @enumFromInt(zir.extra[extra_index]);
4277 extra_index += 1;
4278 break :blk tag_type_ref;
4279 } else .none;
4280
4281 const captures_len = if (small.has_captures_len) blk: {
4282 const captures_len = zir.extra[extra_index];
4283 extra_index += 1;
4284 break :blk captures_len;
4285 } else 0;
4286
4287 const body_len = if (small.has_body_len) blk: {
4288 const body_len = zir.extra[extra_index];
4289 extra_index += 1;
4290 break :blk body_len;
4291 } else 0;
4292
4293 const fields_len = if (small.has_fields_len) blk: {
4294 const fields_len = zir.extra[extra_index];
4295 extra_index += 1;
4296 break :blk fields_len;
4297 } else 0;
4298
4299 const decls_len = if (small.has_decls_len) blk: {
4300 const decls_len = zir.extra[extra_index];
4301 extra_index += 1;
4302 break :blk decls_len;
4303 } else 0;
4304
4305 assert(captures_len == key.captures.owned.len); // synchronises with logic in `Zcu.mapOldZirToNew`
4306
4307 extra_index += captures_len * 2;
4308 extra_index += decls_len;
4309
4310 const body = zir.bodySlice(extra_index, body_len);
4311 extra_index += body.len;
4312
4313 const bit_bags_count = std.math.divCeil(usize, fields_len, 32) catch unreachable;
4314 const body_end = extra_index;
4315 extra_index += bit_bags_count;
4316
4317 const any_values = for (zir.extra[body_end..][0..bit_bags_count]) |bag| {
4318 if (bag != 0) break true;
4319 } else false;
4320
4321 const enum_obj = ip.loadEnumType(old_ty);
4322
4323 const namespace_index = enum_obj.namespace;
4324
4325 const wip_ty = switch (try ip.getEnumType(gpa, io, pt.tid, .{
4326 .has_values = any_values,
4327 .tag_mode = if (small.nonexhaustive)
4328 .nonexhaustive
4329 else if (tag_type_ref == .none)
4330 .auto
4331 else
4332 .explicit,
4333 .fields_len = fields_len,
4334 .key = .{ .declared_owned_captures = .{
4335 .zir_index = key.zir_index,
4336 .captures = key.captures.owned,
4337 } },
4338 }, true)) {
4339 .wip => |wip| wip,
4340 .existing => unreachable, // we passed `replace_existing`
4341 };
4342 var done = true;
4343 errdefer if (!done) wip_ty.cancel(ip, pt.tid);
4344
4345 wip_ty.setName(ip, enum_obj.name, enum_obj.name_nav);
4346
4347 zcu.namespacePtr(namespace_index).owner_type = wip_ty.index;
4348 // No need to re-scan the namespace -- `zirEnumDecl` will ultimately do that if the type is still alive.
4349
4350 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
4351 wip_ty.prepare(ip, namespace_index);
4352 done = true;
4353
4354 Sema.resolveDeclaredEnum(
4355 pt,
4356 wip_ty,
4357 inst_info.inst,
4358 key.zir_index,
4359 namespace_index,
4360 enum_obj.name,
4361 small,
4362 body,
4363 tag_type_ref,
4364 any_values,
4365 fields_len,
4366 zir,
4367 body_end,
4368 ) catch |err| switch (err) {
4369 error.OutOfMemory => |e| return e,
4370 error.Canceled => |e| return e,
4371 error.AnalysisFail => {}, // call sites are responsible for checking `[transitive_]failed_analysis` to detect this
4372 };
4373
4374 return wip_ty.index;
4375}
4376
43774414/// Given a namespace, re-scan its declarations from the type definition if they have not
43784415/// yet been re-scanned on this update.
43794416/// If the type declaration instruction has been lost, returns `error.AnalysisFail`.
......@@ -4396,7 +4433,7 @@ pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace
43964433 };
43974434
43984435 const key = switch (full_key) {
4399 .reified, .generated_tag => {
4436 .reified, .generated_union_tag => {
44004437 // Namespace always empty, so up-to-date.
44014438 namespace.generation = zcu.generation;
44024439 return;
......@@ -4408,123 +4445,37 @@ pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace
44084445
44094446 const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
44104447 const file = zcu.fileByIndex(inst_info.file);
4411 const zir = file.zir.?;
4412
4413 assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended);
4414 const extended = zir.instructions.items(.data)[@intFromEnum(inst_info.inst)].extended;
4448 const zir = &file.zir.?;
44154449
44164450 const decls = switch (container) {
4417 .@"struct" => decls: {
4418 assert(extended.opcode == .struct_decl);
4419 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
4420 const extra = zir.extraData(Zir.Inst.StructDecl, extended.operand);
4421 var extra_index = extra.end;
4422 const captures_len = if (small.has_captures_len) blk: {
4423 const captures_len = zir.extra[extra_index];
4424 extra_index += 1;
4425 break :blk captures_len;
4426 } else 0;
4427 extra_index += @intFromBool(small.has_fields_len);
4428 const decls_len = if (small.has_decls_len) blk: {
4429 const decls_len = zir.extra[extra_index];
4430 extra_index += 1;
4431 break :blk decls_len;
4432 } else 0;
4433 extra_index += captures_len * 2;
4434 if (small.has_backing_int) {
4435 const backing_int_body_len = zir.extra[extra_index];
4436 extra_index += 1; // backing_int_body_len
4437 if (backing_int_body_len == 0) {
4438 extra_index += 1; // backing_int_ref
4439 } else {
4440 extra_index += backing_int_body_len; // backing_int_body_inst
4441 }
4442 }
4443 break :decls zir.bodySlice(extra_index, decls_len);
4444 },
4445 .@"union" => decls: {
4446 assert(extended.opcode == .union_decl);
4447 const small: Zir.Inst.UnionDecl.Small = @bitCast(extended.small);
4448 const extra = zir.extraData(Zir.Inst.UnionDecl, extended.operand);
4449 var extra_index = extra.end;
4450 extra_index += @intFromBool(small.has_tag_type);
4451 const captures_len = if (small.has_captures_len) blk: {
4452 const captures_len = zir.extra[extra_index];
4453 extra_index += 1;
4454 break :blk captures_len;
4455 } else 0;
4456 extra_index += @intFromBool(small.has_body_len);
4457 extra_index += @intFromBool(small.has_fields_len);
4458 const decls_len = if (small.has_decls_len) blk: {
4459 const decls_len = zir.extra[extra_index];
4460 extra_index += 1;
4461 break :blk decls_len;
4462 } else 0;
4463 extra_index += captures_len * 2;
4464 break :decls zir.bodySlice(extra_index, decls_len);
4465 },
4466 .@"enum" => decls: {
4467 assert(extended.opcode == .enum_decl);
4468 const small: Zir.Inst.EnumDecl.Small = @bitCast(extended.small);
4469 const extra = zir.extraData(Zir.Inst.EnumDecl, extended.operand);
4470 var extra_index = extra.end;
4471 extra_index += @intFromBool(small.has_tag_type);
4472 const captures_len = if (small.has_captures_len) blk: {
4473 const captures_len = zir.extra[extra_index];
4474 extra_index += 1;
4475 break :blk captures_len;
4476 } else 0;
4477 extra_index += @intFromBool(small.has_body_len);
4478 extra_index += @intFromBool(small.has_fields_len);
4479 const decls_len = if (small.has_decls_len) blk: {
4480 const decls_len = zir.extra[extra_index];
4481 extra_index += 1;
4482 break :blk decls_len;
4483 } else 0;
4484 extra_index += captures_len * 2;
4485 break :decls zir.bodySlice(extra_index, decls_len);
4486 },
4487 .@"opaque" => decls: {
4488 assert(extended.opcode == .opaque_decl);
4489 const small: Zir.Inst.OpaqueDecl.Small = @bitCast(extended.small);
4490 const extra = zir.extraData(Zir.Inst.OpaqueDecl, extended.operand);
4491 var extra_index = extra.end;
4492 const captures_len = if (small.has_captures_len) blk: {
4493 const captures_len = zir.extra[extra_index];
4494 extra_index += 1;
4495 break :blk captures_len;
4496 } else 0;
4497 const decls_len = if (small.has_decls_len) blk: {
4498 const decls_len = zir.extra[extra_index];
4499 extra_index += 1;
4500 break :blk decls_len;
4501 } else 0;
4502 extra_index += captures_len * 2;
4503 break :decls zir.bodySlice(extra_index, decls_len);
4504 },
4451 .@"struct" => zir.getStructDecl(inst_info.inst).decls,
4452 .@"union" => zir.getUnionDecl(inst_info.inst).decls,
4453 .@"enum" => zir.getEnumDecl(inst_info.inst).decls,
4454 .@"opaque" => zir.getOpaqueDecl(inst_info.inst).decls,
45054455 };
45064456
45074457 try pt.scanNamespace(namespace_index, decls);
45084458 namespace.generation = zcu.generation;
45094459}
45104460
4511pub fn refValue(pt: Zcu.PerThread, val: InternPool.Index) Zcu.SemaError!InternPool.Index {
4512 const ptr_ty = (try pt.ptrTypeSema(.{
4513 .child = pt.zcu.intern_pool.typeOf(val),
4461pub fn uavValue(pt: Zcu.PerThread, val: Value) Zcu.SemaError!Value {
4462 const zcu = pt.zcu;
4463 const ptr_ty = try pt.ptrType(.{
4464 .child = val.typeOf(zcu).toIntern(),
45144465 .flags = .{
45154466 .alignment = .none,
45164467 .is_const = true,
45174468 .address_space = .generic,
45184469 },
4519 })).toIntern();
4520 return pt.intern(.{ .ptr = .{
4521 .ty = ptr_ty,
4470 });
4471 return .fromInterned(try pt.intern(.{ .ptr = .{
4472 .ty = ptr_ty.toIntern(),
45224473 .base_addr = .{ .uav = .{
4523 .val = val,
4524 .orig_ty = ptr_ty,
4474 .val = val.toIntern(),
4475 .orig_ty = ptr_ty.toIntern(),
45254476 } },
45264477 .byte_offset = 0,
4527 } });
4478 } }));
45284479}
45294480
45304481pub fn addDependency(pt: Zcu.PerThread, unit: AnalUnit, dependee: InternPool.Dependee) Allocator.Error!void {
src/codegen.zig+56-98
......@@ -343,11 +343,9 @@ pub fn generateSymbol(
343343
344344 .undef => unreachable, // handled above
345345 .simple_value => |simple_value| switch (simple_value) {
346 .undefined => unreachable, // non-runtime value
347346 .void => unreachable, // non-runtime value
348347 .null => unreachable, // non-runtime value
349348 .@"unreachable" => unreachable, // non-runtime value
350 .empty_tuple => return,
351349 .false, .true => try w.writeByte(switch (simple_value) {
352350 .false => 0,
353351 .true => 1,
......@@ -358,7 +356,6 @@ pub fn generateSymbol(
358356 .@"extern",
359357 .func,
360358 .enum_literal,
361 .empty_enum_value,
362359 => unreachable, // non-runtime values
363360 .int => {
364361 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
......@@ -377,7 +374,7 @@ pub fn generateSymbol(
377374 .payload => 0,
378375 };
379376
380 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
377 if (!payload_ty.hasRuntimeBits(zcu)) {
381378 try w.writeInt(u16, err_val, endian);
382379 return;
383380 }
......@@ -571,46 +568,11 @@ pub fn generateSymbol(
571568 .struct_type => {
572569 const struct_type = ip.loadStructType(ty.toIntern());
573570 switch (struct_type.layout) {
574 .@"packed" => {
575 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
576 const start = w.end;
577 const buffer = try w.writableSlice(abi_size);
578 @memset(buffer, 0);
579 var bits: u16 = 0;
580
581 for (struct_type.field_types.get(ip), 0..) |field_ty, index| {
582 const field_val = switch (aggregate.storage) {
583 .bytes => |bytes| try pt.intern(.{ .int = .{
584 .ty = field_ty,
585 .storage = .{ .u64 = bytes.at(index, ip) },
586 } }),
587 .elems => |elems| elems[index],
588 .repeated_elem => |elem| elem,
589 };
590
591 // pointer may point to a decl which must be marked used
592 // but can also result in a relocation. Therefore we handle those separately.
593 if (Type.fromInterned(field_ty).zigTypeTag(zcu) == .pointer) {
594 const field_offset = std.math.divExact(u16, bits, 8) catch |err| switch (err) {
595 error.DivisionByZero => unreachable,
596 error.UnexpectedRemainder => return error.RelocationNotByteAligned,
597 };
598 w.end = start + field_offset;
599 defer {
600 assert(w.end == start + field_offset + @divExact(target.ptrBitWidth(), 8));
601 w.end = start + abi_size;
602 }
603 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), w, reloc_parent);
604 } else {
605 Value.fromInterned(field_val).writeToPackedMemory(.fromInterned(field_ty), pt, buffer, bits) catch unreachable;
606 }
607 bits += @intCast(Type.fromInterned(field_ty).bitSize(zcu));
608 }
609 },
571 .@"packed" => unreachable,
610572 .auto, .@"extern" => {
611573 const struct_begin = w.end;
612574 const field_types = struct_type.field_types.get(ip);
613 const offsets = struct_type.offsets.get(ip);
575 const offsets = struct_type.field_offsets.get(ip);
614576
615577 var it = struct_type.iterateRuntimeOrder(ip);
616578 while (it.next()) |field_index| {
......@@ -635,13 +597,11 @@ pub fn generateSymbol(
635597 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), w, reloc_parent);
636598 }
637599
638 const size = struct_type.sizeUnordered(ip);
639 const alignment = struct_type.flagsUnordered(ip).alignment.toByteUnits().?;
600 assert(struct_type.alignment.check(struct_type.size));
640601
641 const padding = math.cast(
642 usize,
643 std.mem.alignForward(u64, size, @max(alignment, 1)) - (w.end - struct_begin),
644 ) orelse return error.Overflow;
602 const padding = math.cast(usize, struct_type.size - (w.end - struct_begin)) orelse {
603 return error.Overflow;
604 };
645605 if (padding > 0) try w.splatByteAll(0, padding);
646606 },
647607 }
......@@ -686,6 +646,7 @@ pub fn generateSymbol(
686646 }
687647 }
688648 },
649 .bitpack => |bitpack| try generateSymbol(bin_file, pt, src_loc, .fromInterned(bitpack.backing_int_val), w, reloc_parent),
689650 .memoized_call => unreachable,
690651 }
691652}
......@@ -739,7 +700,14 @@ fn lowerPtr(
739700 };
740701 return lowerPtr(bin_file, pt, src_loc, field.base, w, reloc_parent, offset + field_off);
741702 },
742 .arr_elem, .comptime_field, .comptime_alloc => unreachable,
703 .arr_elem => |arr_elem| {
704 const base_ptr_ty = Value.fromInterned(arr_elem.base).typeOf(zcu);
705 assert(base_ptr_ty.ptrSize(zcu) == .many);
706 const elem_size = base_ptr_ty.childType(zcu).abiSize(zcu);
707 return lowerPtr(bin_file, pt, src_loc, arr_elem.base, w, reloc_parent, offset + elem_size * arr_elem.index);
708 },
709 .comptime_alloc => unreachable,
710 .comptime_field => unreachable,
743711 };
744712}
745713
......@@ -820,9 +788,8 @@ fn lowerNavRef(
820788 const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);
821789 const is_obj = lf.comp.config.output_mode == .Obj;
822790 const nav_ty = Type.fromInterned(ip.getNav(nav_index).typeOf(ip));
823 const is_fn_body = nav_ty.zigTypeTag(zcu) == .@"fn";
824791
825 if (!is_fn_body and !nav_ty.hasRuntimeBits(zcu)) {
792 if (!nav_ty.isRuntimeFnOrHasRuntimeBits(zcu) and ip.getNav(nav_index).getExtern(ip) == null) {
826793 try w.splatByteAll(0xaa, ptr_width_bytes);
827794 return;
828795 }
......@@ -834,7 +801,7 @@ fn lowerNavRef(
834801 dev.check(link.File.Tag.wasm.devFeature());
835802 const wasm = lf.cast(.wasm).?;
836803 assert(reloc_parent == .none);
837 if (is_fn_body) {
804 if (nav_ty.zigTypeTag(zcu) == .@"fn") {
838805 const gop = try wasm.zcu_indirect_function_set.getOrPut(gpa, nav_index);
839806 if (!gop.found_existing) gop.value_ptr.* = {};
840807 if (is_obj) {
......@@ -1060,51 +1027,41 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo
10601027
10611028 switch (ty.zigTypeTag(zcu)) {
10621029 .void => return .none,
1030 .bool => return .{ .immediate = @intFromBool(val.toBool()) },
10631031 .pointer => switch (ty.ptrSize(zcu)) {
10641032 .slice => {},
1065 else => switch (val.toIntern()) {
1066 .null_value => {
1067 return .{ .immediate = 0 };
1068 },
1069 else => switch (ip.indexToKey(val.toIntern())) {
1070 .int => {
1071 return .{ .immediate = val.toUnsignedInt(zcu) };
1033 .one, .many, .c => {
1034 const ptr = ip.indexToKey(val.toIntern()).ptr;
1035 if (ptr.base_addr == .int) return .{ .immediate = ptr.byte_offset };
1036 if (ptr.byte_offset == 0) switch (ptr.base_addr) {
1037 .int => unreachable, // handled above
1038
1039 .nav => |nav_index| {
1040 const nav = ip.getNav(nav_index);
1041 const nav_ty: Type = .fromInterned(nav.typeOf(ip));
1042 if (nav_ty.isRuntimeFnOrHasRuntimeBits(zcu) or nav.getExtern(ip) != null) {
1043 return .{ .lea_nav = nav_index };
1044 } else {
1045 // Create the 0xaa bit pattern...
1046 const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3);
1047 // ...but align the pointer
1048 const alignment = zcu.navAlignment(nav_index);
1049 return .{ .immediate = alignment.forward(undef_ptr_bits) };
1050 }
10721051 },
1073 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
1074 .nav => |nav| {
1075 if (!ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {
1076 const imm: u64 = switch (@divExact(target.ptrBitWidth(), 8)) {
1077 1 => 0xaa,
1078 2 => 0xaaaa,
1079 4 => 0xaaaaaaaa,
1080 8 => 0xaaaaaaaaaaaaaaaa,
1081 else => unreachable,
1082 };
1083 return .{ .immediate = imm };
1084 }
10851052
1086 if (ty.castPtrToFn(zcu)) |fn_ty| {
1087 if (zcu.typeToFunc(fn_ty).?.is_generic) {
1088 return .{ .immediate = fn_ty.abiAlignment(zcu).toByteUnits().? };
1089 }
1090 } else if (ty.zigTypeTag(zcu) == .pointer) {
1091 const elem_ty = ty.elemType2(zcu);
1092 if (!elem_ty.hasRuntimeBits(zcu)) {
1093 return .{ .immediate = elem_ty.abiAlignment(zcu).toByteUnits().? };
1094 }
1095 }
1096
1097 return .{ .lea_nav = nav };
1098 },
1099 .uav => |uav| if (Value.fromInterned(uav.val).typeOf(zcu).hasRuntimeBits(zcu))
1100 return .{ .lea_uav = uav }
1101 else
1102 return .{ .immediate = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu)
1103 .forward(@intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() | 1)) / 3)) },
1104 else => {},
1053 .uav => |uav| if (Value.fromInterned(uav.val).typeOf(zcu).isRuntimeFnOrHasRuntimeBits(zcu)) {
1054 return .{ .lea_uav = uav };
1055 } else {
1056 // Create the 0xaa bit pattern...
1057 const undef_ptr_bits: u64 = @intCast((@as(u66, 1) << @intCast(target.ptrBitWidth() + 1)) / 3);
1058 // ...but align the pointer
1059 const alignment = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu);
1060 return .{ .immediate = alignment.forward(undef_ptr_bits) };
11051061 },
1062
11061063 else => {},
1107 },
1064 };
11081065 },
11091066 },
11101067 .int => {
......@@ -1117,9 +1074,6 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo
11171074 return .{ .immediate = unsigned };
11181075 }
11191076 },
1120 .bool => {
1121 return .{ .immediate = @intFromBool(val.toBool()) };
1122 },
11231077 .optional => {
11241078 if (ty.isPtrLikeOptional(zcu)) {
11251079 return lowerValue(
......@@ -1139,6 +1093,10 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo
11391093 target,
11401094 );
11411095 },
1096 .@"struct", .@"union" => if (ty.containerLayout(zcu) == .@"packed") {
1097 const bitpack = ip.indexToKey(val.toIntern()).bitpack;
1098 return lowerValue(pt, .fromInterned(bitpack.backing_int_val), target);
1099 },
11421100 .error_set => {
11431101 const err_name = ip.indexToKey(val.toIntern()).err.name;
11441102 const error_index = ip.getErrorValueIfExists(err_name).?;
......@@ -1147,7 +1105,7 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo
11471105 .error_union => {
11481106 const err_type = ty.errorUnionSet(zcu);
11491107 const payload_type = ty.errorUnionPayload(zcu);
1150 if (!payload_type.hasRuntimeBitsIgnoreComptime(zcu)) {
1108 if (!payload_type.hasRuntimeBits(zcu)) {
11511109 // We use the error type directly as the type.
11521110 const err_int_ty = try pt.errorIntType();
11531111 switch (ip.indexToKey(val.toIntern()).error_union.val) {
......@@ -1187,10 +1145,10 @@ pub fn lowerValue(pt: Zcu.PerThread, val: Value, target: *const std.Target) Allo
11871145}
11881146
11891147pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {
1190 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0;
1148 if (!payload_ty.hasRuntimeBits(zcu)) return 0;
11911149 const payload_align = payload_ty.abiAlignment(zcu);
11921150 const error_align = Type.anyerror.abiAlignment(zcu);
1193 if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
1151 if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBits(zcu)) {
11941152 return 0;
11951153 } else {
11961154 return payload_align.forward(Type.anyerror.abiSize(zcu));
......@@ -1198,10 +1156,10 @@ pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {
11981156}
11991157
12001158pub fn errUnionErrorOffset(payload_ty: Type, zcu: *Zcu) u64 {
1201 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0;
1159 if (!payload_ty.hasRuntimeBits(zcu)) return 0;
12021160 const payload_align = payload_ty.abiAlignment(zcu);
12031161 const error_align = Type.anyerror.abiAlignment(zcu);
1204 if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
1162 if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBits(zcu)) {
12051163 return error_align.forward(payload_ty.abiSize(zcu));
12061164 } else {
12071165 return 0;
src/codegen/aarch64/Select.zig+63-88
......@@ -2464,7 +2464,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
24642464
24652465 const ty_pl = air.data(air.inst_index).ty_pl;
24662466 const bin_op = isel.air.extraData(Air.Bin, ty_pl.payload).data;
2467 const elem_size = ty_pl.ty.toType().elemType2(zcu).abiSize(zcu);
2467 const elem_size = ty_pl.ty.toType().childType(zcu).abiSize(zcu);
24682468
24692469 const base_vi = try isel.use(bin_op.lhs);
24702470 var base_part_it = base_vi.field(ty_pl.ty.toType(), 0, 8);
......@@ -2791,17 +2791,17 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
27912791 } else return isel.fail("invalid constraint: '{s}'", .{constraint});
27922792 }
27932793
2794 const clobbers = ip.indexToKey(unwrapped_asm.clobbers).aggregate;
2795 const clobbers_ty: ZigType = .fromInterned(clobbers.ty);
2794 const clobbers_val: Constant = .fromInterned(unwrapped_asm.clobbers);
2795 const clobbers_ty = clobbers_val.typeOf(zcu);
2796 var clobbers_bigint_buf: Constant.BigIntSpace = undefined;
2797 const clobbers_bigint = clobbers_val.toBigInt(&clobbers_bigint_buf, zcu);
27962798 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
2797 switch (switch (clobbers.storage) {
2798 .bytes => unreachable,
2799 .elems => |elems| elems[field_index],
2800 .repeated_elem => |repeated_elem| repeated_elem,
2801 }) {
2802 else => unreachable,
2803 .bool_false => continue,
2804 .bool_true => {},
2799 assert(clobbers_ty.fieldType(field_index, zcu).toIntern() == .bool_type);
2800 const limb_bits = @bitSizeOf(std.math.big.Limb);
2801 if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
2802 switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
2803 0 => continue, // field is false
2804 1 => {}, // field is true
28052805 }
28062806 const clobber_name = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;
28072807 if (std.mem.eql(u8, clobber_name, "memory")) continue;
......@@ -2816,14 +2816,11 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
28162816 }
28172817 }
28182818 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
2819 switch (switch (clobbers.storage) {
2820 .bytes => unreachable,
2821 .elems => |elems| elems[field_index],
2822 .repeated_elem => |repeated_elem| repeated_elem,
2823 }) {
2824 else => unreachable,
2825 .bool_false => continue,
2826 .bool_true => {},
2819 const limb_bits = @bitSizeOf(std.math.big.Limb);
2820 if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
2821 switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
2822 0 => continue, // field is false
2823 1 => {}, // field is true
28272824 }
28282825 const clobber_name = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;
28292826 if (std.mem.eql(u8, clobber_name, "memory")) continue;
......@@ -2872,14 +2869,11 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
28722869 }
28732870
28742871 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
2875 switch (switch (clobbers.storage) {
2876 .bytes => unreachable,
2877 .elems => |elems| elems[field_index],
2878 .repeated_elem => |repeated_elem| repeated_elem,
2879 }) {
2880 else => unreachable,
2881 .bool_false => continue,
2882 .bool_true => {},
2872 const limb_bits = @bitSizeOf(std.math.big.Limb);
2873 if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
2874 switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
2875 0 => continue, // field is false
2876 1 => {}, // field is true
28832877 }
28842878 const clobber_name = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;
28852879 if (std.mem.eql(u8, clobber_name, "memory")) continue;
......@@ -3289,8 +3283,8 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
32893283 } else if (dst_ty.isSliceAtRuntime(zcu) and src_ty.isSliceAtRuntime(zcu)) {
32903284 try dst_vi.value.move(isel, ty_op.operand);
32913285 } else if (dst_tag == .error_union and src_tag == .error_union) {
3292 assert(dst_ty.errorUnionSet(zcu).hasRuntimeBitsIgnoreComptime(zcu) ==
3293 src_ty.errorUnionSet(zcu).hasRuntimeBitsIgnoreComptime(zcu));
3286 assert(dst_ty.errorUnionSet(zcu).hasRuntimeBits(zcu) ==
3287 src_ty.errorUnionSet(zcu).hasRuntimeBits(zcu));
32943288 if (dst_ty.errorUnionPayload(zcu).toIntern() == src_ty.errorUnionPayload(zcu).toIntern()) {
32953289 try dst_vi.value.move(isel, ty_op.operand);
32963290 } else return isel.fail("bad {t} {f} {f}", .{ air_tag, isel.fmtType(dst_ty), isel.fmtType(src_ty) });
......@@ -4568,7 +4562,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
45684562 }
45694563 if (case.ranges.len == 0 and case.items.len == 1 and Constant.fromInterned(
45704564 case.items[0].toInterned().?,
4571 ).orderAgainstZero(zcu).compare(.eq)) {
4565 ).compareHetero(.eq, .zero_comptime_int, zcu)) {
45724566 try isel.emit(.cbnz(
45734567 cond_reg,
45744568 @intCast((isel.instructions.items.len + 1 - next_label) << 2),
......@@ -6145,7 +6139,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
61456139 } else {
61466140 const elem_ptr_ra = try isel.allocIntReg();
61476141 defer isel.freeReg(elem_ptr_ra);
6148 if (!try elem_vi.value.load(isel, slice_ty.elemType2(zcu), elem_ptr_ra, .{
6142 if (!try elem_vi.value.load(isel, slice_ty.childType(zcu), elem_ptr_ra, .{
61496143 .@"volatile" = ptr_info.flags.is_volatile,
61506144 })) break :unused;
61516145 const slice_vi = try isel.use(bin_op.lhs);
......@@ -6253,7 +6247,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
62536247 } else {
62546248 const elem_ptr_ra = try isel.allocIntReg();
62556249 defer isel.freeReg(elem_ptr_ra);
6256 if (!try elem_vi.value.load(isel, ptr_ty.elemType2(zcu), elem_ptr_ra, .{
6250 if (!try elem_vi.value.load(isel, ptr_ty.childType(zcu), elem_ptr_ra, .{
62576251 .@"volatile" = ptr_info.flags.is_volatile,
62586252 })) break :unused;
62596253 const base_vi = try isel.use(bin_op.lhs);
......@@ -6594,7 +6588,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
65946588 if (try isel.hasRepeatedByteRepr(.fromInterned(fill_val))) |fill_byte|
65956589 break :fill_byte .{ .constant = fill_byte };
65966590 }
6597 switch (dst_ty.elemType2(zcu).abiSize(zcu)) {
6591 switch (dst_ty.indexableElem(zcu).abiSize(zcu)) {
65986592 0 => unreachable,
65996593 1 => break :fill_byte .{ .value = bin_op.rhs },
66006594 2, 4, 8 => |size| {
......@@ -6899,11 +6893,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
68996893 var field_it = loaded_struct.iterateRuntimeOrder(ip);
69006894 while (field_it.next()) |field_index| {
69016895 const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
6902 field_offset = field_ty.structFieldAlignment(
6903 loaded_struct.fieldAlign(ip, field_index),
6904 loaded_struct.layout,
6905 zcu,
6906 ).forward(field_offset);
6896 field_offset = loaded_struct.field_offsets.get(ip)[field_index];
69076897 const field_size = field_ty.abiSize(zcu);
69086898 if (field_size == 0) continue;
69096899 var agg_part_it = agg_vi.value.field(agg_ty, field_offset, field_size);
......@@ -6911,7 +6901,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
69116901 try agg_part_vi.?.move(isel, elems[field_index]);
69126902 field_offset += field_size;
69136903 }
6914 assert(loaded_struct.flagsUnordered(ip).alignment.forward(field_offset) == agg_vi.value.size(isel));
6904 assert(loaded_struct.alignment.forward(field_offset) == agg_vi.value.size(isel));
69156905 },
69166906 .tuple_type => |tuple_type| {
69176907 const elems: []const Air.Inst.Ref =
......@@ -6953,23 +6943,23 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
69536943 const union_layout = ZigType.getUnionLayout(loaded_union, zcu);
69546944
69556945 if (union_layout.tag_size > 0) unused_tag: {
6956 const loaded_tag = loaded_union.loadTagType(ip);
6946 const loaded_tag = ip.loadEnumType(loaded_union.enum_tag_type);
69576947 var tag_it = union_vi.value.field(union_ty, union_layout.tagOffset(), union_layout.tag_size);
69586948 const tag_vi = try tag_it.only(isel);
69596949 const tag_ra = try tag_vi.?.defReg(isel) orelse break :unused_tag;
69606950 switch (union_layout.tag_size) {
69616951 0 => unreachable,
6962 1...4 => try isel.movImmediate(tag_ra.w(), @as(u32, switch (loaded_tag.values.len) {
6952 1...4 => try isel.movImmediate(tag_ra.w(), @as(u32, switch (loaded_tag.field_values.len) {
69636953 0 => extra.field_index,
6964 else => switch (ip.indexToKey(loaded_tag.values.get(ip)[extra.field_index]).int.storage) {
6954 else => switch (ip.indexToKey(loaded_tag.field_values.get(ip)[extra.field_index]).int.storage) {
69656955 .u64 => |imm| @intCast(imm),
69666956 .i64 => |imm| @bitCast(@as(i32, @intCast(imm))),
69676957 else => unreachable,
69686958 },
69696959 })),
6970 5...8 => try isel.movImmediate(tag_ra.x(), switch (loaded_tag.values.len) {
6960 5...8 => try isel.movImmediate(tag_ra.x(), switch (loaded_tag.field_values.len) {
69716961 0 => extra.field_index,
6972 else => switch (ip.indexToKey(loaded_tag.values.get(ip)[extra.field_index]).int.storage) {
6962 else => switch (ip.indexToKey(loaded_tag.field_values.get(ip)[extra.field_index]).int.storage) {
69736963 .u64 => |imm| imm,
69746964 .i64 => |imm| @bitCast(imm),
69756965 else => unreachable,
......@@ -7217,7 +7207,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
72177207 const ptr_ra = try ptr_vi.value.defReg(isel) orelse break :unused;
72187208
72197209 const ty_nav = air.data(air.inst_index).ty_nav;
7220 if (ZigType.fromInterned(ip.getNav(ty_nav.nav).typeOf(ip)).isFnOrHasRuntimeBits(zcu)) switch (true) {
7210 if (ZigType.fromInterned(ip.getNav(ty_nav.nav).typeOf(ip)).isRuntimeFnOrHasRuntimeBits(zcu)) switch (true) {
72217211 false => {
72227212 try isel.nav_relocs.append(gpa, .{
72237213 .nav = ty_nav.nav,
......@@ -7240,7 +7230,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
72407230 });
72417231 try isel.emit(.adrp(ptr_ra.x(), 0));
72427232 },
7243 } else try isel.movImmediate(ptr_ra.x(), isel.pt.navAlignment(ty_nav.nav).forward(0xaaaaaaaaaaaaaaaa));
7233 } else try isel.movImmediate(ptr_ra.x(), zcu.navAlignment(ty_nav.nav).forward(0xaaaaaaaaaaaaaaaa));
72447234 }
72457235 if (air.next()) |next_air_tag| continue :air_tag next_air_tag;
72467236 },
......@@ -10397,7 +10387,7 @@ pub const Value = struct {
1039710387 switch (loaded_struct.layout) {
1039810388 .auto, .@"extern" => {},
1039910389 .@"packed" => continue :type_key .{
10400 .int_type = ip.indexToKey(loaded_struct.backingIntTypeUnordered(ip)).int_type,
10390 .int_type = ip.indexToKey(loaded_struct.packed_backing_int_type).int_type,
1040110391 },
1040210392 }
1040310393 const min_part_log2_stride: u5 = if (size > 16) 4 else if (size > 8) 3 else 0;
......@@ -10412,7 +10402,7 @@ pub const Value = struct {
1041210402 var field_it = loaded_struct.iterateRuntimeOrder(ip);
1041310403 while (field_it.next()) |field_index| {
1041410404 const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
10415 const field_begin = switch (loaded_struct.fieldAlign(ip, field_index)) {
10405 const field_begin = switch (loaded_struct.field_aligns.getOrNone(ip, field_index)) {
1041610406 .none => field_ty.abiAlignment(zcu),
1041710407 else => |field_align| field_align,
1041810408 }.forward(field_end);
......@@ -10510,7 +10500,7 @@ pub const Value = struct {
1051010500 },
1051110501 .union_type => {
1051210502 const loaded_union = ip.loadUnionType(ty.toIntern());
10513 switch (loaded_union.flagsUnordered(ip).layout) {
10503 switch (loaded_union.layout) {
1051410504 .auto, .@"extern" => {},
1051510505 .@"packed" => continue :type_key .{ .int_type = .{
1051610506 .signedness = .unsigned,
......@@ -10545,12 +10535,13 @@ pub const Value = struct {
1054510535 const field_signedness = field_signedness: switch (field) {
1054610536 .tag => {
1054710537 if (offset >= field_begin and offset + size <= field_begin + field_size) {
10548 ty = .fromInterned(loaded_union.enum_tag_ty);
10538 ty = .fromInterned(loaded_union.enum_tag_type);
1054910539 ty_size = field_size;
1055010540 offset -= field_begin;
10551 continue :type_key ip.indexToKey(loaded_union.enum_tag_ty);
10541 continue :type_key ip.indexToKey(loaded_union.enum_tag_type);
1055210542 }
10553 break :field_signedness ip.indexToKey(loaded_union.loadTagType(ip).tag_ty).int_type.signedness;
10543 const loaded_enum = ip.loadEnumType(loaded_union.enum_tag_type);
10544 break :field_signedness ip.indexToKey(loaded_enum.int_tag_type).int_type.signedness;
1055410545 },
1055510546 .payload => null,
1055610547 };
......@@ -10580,7 +10571,7 @@ pub const Value = struct {
1058010571 }
1058110572 },
1058210573 .opaque_type, .func_type => continue :type_key .{ .simple_type = .anyopaque },
10583 .enum_type => continue :type_key ip.indexToKey(ip.loadEnumType(ty.toIntern()).tag_ty),
10574 .enum_type => continue :type_key ip.indexToKey(ip.loadEnumType(ty.toIntern()).int_tag_type),
1058410575 .error_set_type,
1058510576 .inferred_error_set_type,
1058610577 => continue :type_key .{ .simple_type = .anyerror },
......@@ -10594,7 +10585,6 @@ pub const Value = struct {
1059410585 .error_union,
1059510586 .enum_literal,
1059610587 .enum_tag,
10597 .empty_enum_value,
1059810588 .float,
1059910589 .ptr,
1060010590 .slice,
......@@ -10717,7 +10707,6 @@ pub const Value = struct {
1071710707 .inferred_error_set_type,
1071810708
1071910709 .enum_literal,
10720 .empty_enum_value,
1072110710 .memoized_call,
1072210711 => unreachable, // not a runtime value
1072310712 .undef => break :free try isel.emit(if (mat.ra.isVector()) .movi(switch (size) {
......@@ -10738,7 +10727,7 @@ pub const Value = struct {
1073810727 } }),
1073910728 }),
1074010729 .simple_value => |simple_value| switch (simple_value) {
10741 .undefined, .void, .null, .empty_tuple, .@"unreachable" => unreachable,
10730 .void, .null, .@"unreachable" => unreachable,
1074210731 .true => continue :constant_key .{ .int = .{
1074310732 .ty = .bool_type,
1074410733 .storage = .{ .u64 = 1 },
......@@ -10748,7 +10737,7 @@ pub const Value = struct {
1074810737 .storage = .{ .u64 = 0 },
1074910738 } },
1075010739 },
10751 .int => |int| break :free storage: switch (int.storage) {
10740 .int => |int| break :free switch (int.storage) {
1075210741 .u64 => |imm| try isel.movImmediate(switch (size) {
1075310742 else => unreachable,
1075410743 1...4 => mat.ra.w(),
......@@ -10780,12 +10769,6 @@ pub const Value = struct {
1078010769 }
1078110770 try isel.movImmediate(mat.ra.x(), imm);
1078210771 },
10783 .lazy_align => |ty| continue :storage .{
10784 .u64 = ZigType.fromInterned(ty).abiAlignment(zcu).toByteUnits().?,
10785 },
10786 .lazy_size => |ty| continue :storage .{
10787 .u64 = ZigType.fromInterned(ty).abiSize(zcu),
10788 },
1078910772 },
1079010773 .err => |err| continue :constant_key .{ .int = .{
1079110774 .ty = err.ty,
......@@ -10931,7 +10914,7 @@ pub const Value = struct {
1093110914 .ptr => |ptr| {
1093210915 assert(offset == 0 and size == 8);
1093310916 break :free switch (ptr.base_addr) {
10934 .nav => |nav| if (ZigType.fromInterned(ip.getNav(nav).typeOf(ip)).isFnOrHasRuntimeBits(zcu)) switch (true) {
10917 .nav => |nav| if (ZigType.fromInterned(ip.getNav(nav).typeOf(ip)).isRuntimeFnOrHasRuntimeBits(zcu)) switch (true) {
1093510918 false => {
1093610919 try isel.nav_relocs.append(zcu.gpa, .{
1093710920 .nav = nav,
......@@ -10965,9 +10948,9 @@ pub const Value = struct {
1096510948 },
1096610949 } else continue :constant_key .{ .int = .{
1096710950 .ty = .usize_type,
10968 .storage = .{ .u64 = isel.pt.navAlignment(nav).forward(0xaaaaaaaaaaaaaaaa) },
10951 .storage = .{ .u64 = zcu.navAlignment(nav).forward(0xaaaaaaaaaaaaaaaa) },
1096910952 } },
10970 .uav => |uav| if (ZigType.fromInterned(ip.typeOf(uav.val)).isFnOrHasRuntimeBits(zcu)) switch (true) {
10953 .uav => |uav| if (ZigType.fromInterned(ip.typeOf(uav.val)).isRuntimeFnOrHasRuntimeBits(zcu)) switch (true) {
1097110954 false => {
1097210955 try isel.uav_relocs.append(zcu.gpa, .{
1097310956 .uav = uav,
......@@ -11092,13 +11075,9 @@ pub const Value = struct {
1109211075 var field_offset: u64 = 0;
1109311076 var field_it = loaded_struct.iterateRuntimeOrder(ip);
1109411077 while (field_it.next()) |field_index| {
11095 if (loaded_struct.fieldIsComptime(ip, field_index)) continue;
11078 if (loaded_struct.field_is_comptime_bits.get(ip, field_index)) continue;
1109611079 const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
11097 field_offset = field_ty.structFieldAlignment(
11098 loaded_struct.fieldAlign(ip, field_index),
11099 loaded_struct.layout,
11100 zcu,
11101 ).forward(field_offset);
11080 field_offset = loaded_struct.field_offsets.get(ip)[field_index];
1110211081 const field_size = field_ty.abiSize(zcu);
1110311082 if (offset >= field_offset and offset + size <= field_offset + field_size) {
1110411083 offset -= field_offset;
......@@ -11140,7 +11119,7 @@ pub const Value = struct {
1114011119 .un => |un| {
1114111120 const loaded_union = ip.loadUnionType(un.ty);
1114211121 const union_layout = ZigType.getUnionLayout(loaded_union, zcu);
11143 if (loaded_union.hasTag(ip)) {
11122 if (loaded_union.has_runtime_tag) {
1114411123 const tag_offset = union_layout.tagOffset();
1114511124 if (offset >= tag_offset and offset + size <= tag_offset + union_layout.tag_size) {
1114611125 offset -= tag_offset;
......@@ -11414,7 +11393,6 @@ fn writeKeyToMemory(isel: *Select, constant_key: InternPool.Key, buffer: []u8) e
1141411393 .inferred_error_set_type,
1141511394
1141611395 .enum_literal,
11417 .empty_enum_value,
1141811396 .memoized_call,
1141911397 => unreachable, // not a runtime value
1142011398 .err => |err| {
......@@ -11486,13 +11464,9 @@ fn writeKeyToMemory(isel: *Select, constant_key: InternPool.Key, buffer: []u8) e
1148611464 var field_offset: u64 = 0;
1148711465 var field_it = loaded_struct.iterateRuntimeOrder(ip);
1148811466 while (field_it.next()) |field_index| {
11489 if (loaded_struct.fieldIsComptime(ip, field_index)) continue;
11467 if (loaded_struct.field_is_comptime_bits.get(ip, field_index)) continue;
1149011468 const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
11491 field_offset = field_ty.structFieldAlignment(
11492 loaded_struct.fieldAlign(ip, field_index),
11493 loaded_struct.layout,
11494 zcu,
11495 ).forward(field_offset);
11469 field_offset = loaded_struct.field_offsets.get(ip)[field_index];
1149611470 const field_size = field_ty.abiSize(zcu);
1149711471 if (!try isel.writeToMemory(.fromInterned(switch (aggregate.storage) {
1149811472 .bytes => unreachable,
......@@ -12091,7 +12065,7 @@ pub const CallAbiIterator = struct {
1209112065 const zcu = isel.pt.zcu;
1209212066 const ip = &zcu.intern_pool;
1209312067
12094 if (ty.isNoReturn(zcu) or !ty.hasRuntimeBitsIgnoreComptime(zcu)) return null;
12068 if (!ty.hasRuntimeBits(zcu)) return null;
1209512069 try isel.values.ensureUnusedCapacity(zcu.gpa, Value.max_parts);
1209612070 const wip_vi = isel.initValue(ty);
1209712071 type_key: switch (ip.indexToKey(ty.toIntern())) {
......@@ -12195,7 +12169,7 @@ pub const CallAbiIterator = struct {
1219512169 switch (loaded_struct.layout) {
1219612170 .auto, .@"extern" => {},
1219712171 .@"packed" => continue :type_key .{
12198 .int_type = ip.indexToKey(loaded_struct.backingIntTypeUnordered(ip)).int_type,
12172 .int_type = ip.indexToKey(loaded_struct.packed_backing_int_type).int_type,
1219912173 },
1220012174 }
1220112175 const size = wip_vi.size(isel);
......@@ -12219,7 +12193,7 @@ pub const CallAbiIterator = struct {
1221912193 const field_end = next_field_end;
1222012194 const next_field_begin = if (field_it.next()) |field_index| next_field_begin: {
1222112195 const field_ty: ZigType = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
12222 const next_field_begin = switch (loaded_struct.fieldAlign(ip, field_index)) {
12196 const next_field_begin = switch (loaded_struct.field_aligns.getOrNone(ip, field_index)) {
1222312197 .none => field_ty.abiAlignment(zcu),
1222412198 else => |field_align| field_align,
1222512199 }.forward(field_end);
......@@ -12285,7 +12259,7 @@ pub const CallAbiIterator = struct {
1228512259 },
1228612260 .union_type => {
1228712261 const loaded_union = ip.loadUnionType(ty.toIntern());
12288 switch (loaded_union.flagsUnordered(ip).layout) {
12262 switch (loaded_union.layout) {
1228912263 .auto, .@"extern" => {},
1229012264 .@"packed" => continue :type_key .{ .int_type = .{
1229112265 .signedness = .unsigned,
......@@ -12318,7 +12292,9 @@ pub const CallAbiIterator = struct {
1231812292 }
1231912293 },
1232012294 .opaque_type, .func_type => continue :type_key .{ .simple_type = .anyopaque },
12321 .enum_type => continue :type_key ip.indexToKey(ip.loadEnumType(ty.toIntern()).tag_ty),
12295 .enum_type => continue :type_key .{
12296 .int_type = ip.indexToKey(ip.loadEnumType(ty.toIntern()).int_tag_type).int_type,
12297 },
1232212298 .error_set_type,
1232312299 .inferred_error_set_type,
1232412300 => continue :type_key .{ .simple_type = .anyerror },
......@@ -12332,7 +12308,6 @@ pub const CallAbiIterator = struct {
1233212308 .error_union,
1233312309 .enum_literal,
1233412310 .enum_tag,
12335 .empty_enum_value,
1233612311 .float,
1233712312 .ptr,
1233812313 .slice,
......@@ -12424,8 +12399,8 @@ pub const CallAbiIterator = struct {
1242412399 const ip = &zcu.intern_pool;
1242512400 var common_fdt: ?FundamentalDataType = null;
1242612401 for (0.., loaded_struct.field_types.get(ip)) |field_index, field_ty| {
12427 if (loaded_struct.fieldIsComptime(ip, field_index)) continue;
12428 if (loaded_struct.fieldAlign(ip, field_index) != .none) return null;
12402 if (loaded_struct.field_is_comptime_bits.get(ip, field_index)) continue;
12403 if (loaded_struct.field_aligns.getOrNone(ip, field_index) != .none) return null;
1242912404 if (!ZigType.fromInterned(field_ty).hasRuntimeBits(zcu)) continue;
1243012405 const fdt = homogeneousAggregateBaseType(zcu, field_ty);
1243112406 if (common_fdt == null) common_fdt = fdt else if (fdt != common_fdt) return null;
src/codegen/aarch64/abi.zig+1-1
......@@ -13,7 +13,7 @@ pub const Class = union(enum) {
1313
1414/// For `float_array` the second element will be the amount of floats.
1515pub fn classifyType(ty: Type, zcu: *Zcu) Class {
16 assert(ty.hasRuntimeBitsIgnoreComptime(zcu));
16 assert(ty.hasRuntimeBits(zcu));
1717
1818 var maybe_float_bits: ?u16 = null;
1919 switch (ty.zigTypeTag(zcu)) {
src/codegen/arm/abi.zig+13-11
......@@ -23,7 +23,7 @@ pub const Class = union(enum) {
2323pub const Context = enum { ret, arg };
2424
2525pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
26 assert(ty.hasRuntimeBitsIgnoreComptime(zcu));
26 assert(ty.hasRuntimeBits(zcu));
2727
2828 var maybe_float_bits: ?u16 = null;
2929 const max_byval_size = 512;
......@@ -39,22 +39,22 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
3939 const float_count = countFloats(ty, zcu, &maybe_float_bits);
4040 if (float_count <= byval_float_count) return .byval;
4141
42 if (ty.abiAlignment(zcu).compare(.gt, .@"32")) {
43 return Class.arrSize(bit_size, 64);
44 }
45
4246 const fields = ty.structFieldCount(zcu);
4347 var i: u32 = 0;
4448 while (i < fields) : (i += 1) {
4549 const field_ty = ty.fieldType(i, zcu);
46 const field_alignment = ty.fieldAlignment(i, zcu);
47 const field_size = field_ty.bitSize(zcu);
48 if (field_size > 32 or field_alignment.compare(.gt, .@"32")) {
49 return Class.arrSize(bit_size, 64);
50 }
50 if (field_ty.bitSize(zcu) > 32) return Class.arrSize(bit_size, 64);
5151 }
5252 return Class.arrSize(bit_size, 32);
5353 },
5454 .@"union" => {
5555 const bit_size = ty.bitSize(zcu);
5656 const union_obj = zcu.typeToUnion(ty).?;
57 if (union_obj.flagsUnordered(ip).layout == .@"packed") {
57 if (union_obj.layout == .@"packed") {
5858 if (bit_size > 64) return .memory;
5959 return .byval;
6060 }
......@@ -62,10 +62,12 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
6262 const float_count = countFloats(ty, zcu, &maybe_float_bits);
6363 if (float_count <= byval_float_count) return .byval;
6464
65 for (union_obj.field_types.get(ip), 0..) |field_ty, field_index| {
66 if (Type.fromInterned(field_ty).bitSize(zcu) > 32 or
67 ty.fieldAlignment(field_index, zcu).compare(.gt, .@"32"))
68 {
65 if (union_obj.alignment.compareStrict(.gt, .@"32")) {
66 return Class.arrSize(bit_size, 64);
67 }
68
69 for (union_obj.field_types.get(ip)) |field_ty| {
70 if (Type.fromInterned(field_ty).bitSize(zcu) > 32) {
6971 return Class.arrSize(bit_size, 64);
7072 }
7173 }
src/codegen/c.zig+2390-3190
......@@ -50,32 +50,39 @@ pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features {
5050/// * The types used, so declarations can be emitted in `flush`
5151/// * The lazy functions used, so definitions can be emitted in `flush`
5252pub const Mir = struct {
53 // These remaining fields are essentially just an owned version of `link.C.AvBlock`.
54 fwd_decl: []u8,
55 code_header: []u8,
56 code: []u8,
5357 /// This map contains all the UAVs we saw generating this function.
5458 /// `link.C` will merge them into its `uavs`/`aligned_uavs` fields.
5559 /// Key is the value of the UAV; value is the UAV's alignment, or
5660 /// `.none` for natural alignment. The specified alignment is never
5761 /// less than the natural alignment.
58 uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
59 // These remaining fields are essentially just an owned version of `link.C.AvBlock`.
60 code_header: []u8,
61 code: []u8,
62 fwd_decl: []u8,
63 ctype_pool: CType.Pool,
64 lazy_fns: LazyFnMap,
62 need_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
63 ctype_deps: CType.Dependencies,
64 /// Key is an enum type for which we need a generated `@tagName` function.
65 need_tag_name_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
66 /// Key is a function Nav for which we need a generated `zig_never_tail` wrapper.
67 need_never_tail_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void),
68 /// Key is a function Nav for which we need a generated `zig_never_inline` wrapper.
69 need_never_inline_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void),
6570
6671 pub fn deinit(mir: *Mir, gpa: Allocator) void {
67 mir.uavs.deinit(gpa);
72 gpa.free(mir.fwd_decl);
6873 gpa.free(mir.code_header);
6974 gpa.free(mir.code);
70 gpa.free(mir.fwd_decl);
71 mir.ctype_pool.deinit(gpa);
72 mir.lazy_fns.deinit(gpa);
75 mir.need_uavs.deinit(gpa);
76 mir.ctype_deps.deinit(gpa);
77 mir.need_tag_name_funcs.deinit(gpa);
78 mir.need_never_tail_funcs.deinit(gpa);
79 mir.need_never_inline_funcs.deinit(gpa);
7380 }
7481};
7582
76pub const Error = Writer.Error || std.mem.Allocator.Error || error{AnalysisFail};
83pub const Error = Writer.Error || Allocator.Error || error{AnalysisFail};
7784
78pub const CType = @import("c/Type.zig");
85pub const CType = @import("c/type.zig").CType;
7986
8087pub const CValue = union(enum) {
8188 none: void,
......@@ -87,8 +94,6 @@ pub const CValue = union(enum) {
8794 constant: Value,
8895 /// Index into the parameters
8996 arg: usize,
90 /// The array field of a parameter
91 arg_array: usize,
9297 /// Index into a tuple's fields
9398 field: usize,
9499 /// By-value
......@@ -100,8 +105,6 @@ pub const CValue = union(enum) {
100105 identifier: []const u8,
101106 /// Rendered as "payload." followed by as identifier (using fmtIdent)
102107 payload_identifier: []const u8,
103 /// Rendered with fmtCTypePoolString
104 ctype_pool_string: CType.Pool.String,
105108
106109 fn eql(lhs: CValue, rhs: CValue) bool {
107110 return switch (lhs) {
......@@ -122,10 +125,6 @@ pub const CValue = union(enum) {
122125 .arg => |rhs_arg_index| lhs_arg_index == rhs_arg_index,
123126 else => false,
124127 },
125 .arg_array => |lhs_arg_index| switch (rhs) {
126 .arg_array => |rhs_arg_index| lhs_arg_index == rhs_arg_index,
127 else => false,
128 },
129128 .field => |lhs_field_index| switch (rhs) {
130129 .field => |rhs_field_index| lhs_field_index == rhs_field_index,
131130 else => false,
......@@ -150,10 +149,6 @@ pub const CValue = union(enum) {
150149 .payload_identifier => |rhs_id| std.mem.eql(u8, lhs_id, rhs_id),
151150 else => false,
152151 },
153 .ctype_pool_string => |lhs_str| switch (rhs) {
154 .ctype_pool_string => |rhs_str| lhs_str.index == rhs_str.index,
155 else => false,
156 },
157152 };
158153 }
159154};
......@@ -163,53 +158,24 @@ const BlockData = struct {
163158 result: CValue,
164159};
165160
166pub const CValueMap = std.AutoHashMap(Air.Inst.Ref, CValue);
167
168pub const LazyFnKey = union(enum) {
169 tag_name: InternPool.Index,
170 never_tail: InternPool.Nav.Index,
171 never_inline: InternPool.Nav.Index,
172};
173pub const LazyFnValue = struct {
174 fn_name: CType.Pool.String,
175};
176pub const LazyFnMap = std.AutoArrayHashMapUnmanaged(LazyFnKey, LazyFnValue);
177
178const Local = struct {
179 ctype: CType,
180 flags: packed struct(u32) {
181 alignas: CType.AlignAs,
182 _: u20 = undefined,
183 },
184
185 fn getType(local: Local) LocalType {
186 return .{ .ctype = local.ctype, .alignas = local.flags.alignas };
187 }
161const LocalType = struct {
162 type: Type,
163 alignment: Alignment,
188164};
189165
190166const LocalIndex = u16;
191const LocalType = struct { ctype: CType, alignas: CType.AlignAs };
192167const LocalsList = std.AutoArrayHashMapUnmanaged(LocalIndex, void);
193168const LocalsMap = std.AutoArrayHashMapUnmanaged(LocalType, LocalsList);
194169
195170const ValueRenderLocation = enum {
196 FunctionArgument,
197 Initializer,
198 StaticInitializer,
199 Other,
171 initializer,
172 static_initializer,
173 other,
200174
201175 fn isInitializer(loc: ValueRenderLocation) bool {
202176 return switch (loc) {
203 .Initializer, .StaticInitializer => true,
204 else => false,
205 };
206 }
207
208 fn toCTypeKind(loc: ValueRenderLocation) CType.Kind {
209 return switch (loc) {
210 .FunctionArgument => .parameter,
211 .Initializer, .Other => .complete,
212 .StaticInitializer => .global,
177 .initializer, .static_initializer => true,
178 .other => false,
213179 };
214180 }
215181};
......@@ -334,16 +300,31 @@ const reserved_idents = std.StaticStringMap(void).initComptime(.{
334300});
335301
336302fn isReservedIdent(ident: []const u8) bool {
337 if (ident.len >= 2 and ident[0] == '_') { // C language
303 // C language
304 if (ident.len >= 2 and ident[0] == '_') {
338305 switch (ident[1]) {
339306 'A'...'Z', '_' => return true,
340 else => return false,
307 else => {},
341308 }
342 } else if (mem.startsWith(u8, ident, "DUMMYSTRUCTNAME") or
309 }
310
311 // windows.h
312 if (mem.startsWith(u8, ident, "DUMMYSTRUCTNAME") or
343313 mem.startsWith(u8, ident, "DUMMYUNIONNAME"))
344 { // windows.h
314 {
315 return true;
316 }
317
318 // CType
319 if (mem.startsWith(u8, ident, "enum__") or
320 mem.startsWith(u8, ident, "bitpack__") or
321 mem.startsWith(u8, ident, "aligned__") or
322 mem.startsWith(u8, ident, "fn__"))
323 {
345324 return true;
346 } else return reserved_idents.has(ident);
325 }
326
327 return reserved_idents.has(ident);
347328}
348329
349330fn formatIdentSolo(ident: []const u8, w: *Writer) Writer.Error!void {
......@@ -361,7 +342,7 @@ fn formatIdentOptions(ident: []const u8, w: *Writer, solo: bool) Writer.Error!vo
361342 for (ident, 0..) |c, i| {
362343 switch (c) {
363344 'a'...'z', 'A'...'Z', '_' => try w.writeByte(c),
364 '.' => try w.writeByte('_'),
345 '.', ' ' => try w.writeByte('_'),
365346 '0'...'9' => if (i == 0) {
366347 try w.print("_{x:2}", .{c});
367348 } else {
......@@ -380,29 +361,6 @@ pub fn fmtIdentUnsolo(ident: []const u8) std.fmt.Alt([]const u8, formatIdentUnso
380361 return .{ .data = ident };
381362}
382363
383const CTypePoolStringFormatData = struct {
384 ctype_pool_string: CType.Pool.String,
385 ctype_pool: *const CType.Pool,
386 solo: bool,
387};
388fn formatCTypePoolString(data: CTypePoolStringFormatData, w: *Writer) Writer.Error!void {
389 if (data.ctype_pool_string.toSlice(data.ctype_pool)) |slice|
390 try formatIdentOptions(slice, w, data.solo)
391 else
392 try w.print("{f}", .{data.ctype_pool_string.fmt(data.ctype_pool)});
393}
394pub fn fmtCTypePoolString(
395 ctype_pool_string: CType.Pool.String,
396 ctype_pool: *const CType.Pool,
397 solo: bool,
398) std.fmt.Alt(CTypePoolStringFormatData, formatCTypePoolString) {
399 return .{ .data = .{
400 .ctype_pool_string = ctype_pool_string,
401 .ctype_pool = ctype_pool,
402 .solo = solo,
403 } };
404}
405
406364// Returns true if `formatIdent` would make any edits to ident.
407365// This must be kept in sync with `formatIdent`.
408366pub fn isMangledIdent(ident: []const u8, solo: bool) bool {
......@@ -417,21 +375,26 @@ pub fn isMangledIdent(ident: []const u8, solo: bool) bool {
417375 return false;
418376}
419377
420/// This data is available when outputting .c code for a `InternPool.Index`
421/// that corresponds to `func`.
422/// It is not available when generating .h file.
378/// This data is available when rendering C source code for an interned function.
423379pub const Function = struct {
424380 air: Air,
425381 liveness: Air.Liveness,
426 value_map: CValueMap,
382 value_map: std.AutoHashMap(Air.Inst.Ref, CValue),
427383 blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, BlockData) = .empty,
428384 next_arg_index: u32 = 0,
429385 next_block_index: u32 = 0,
430 object: Object,
431 lazy_fns: LazyFnMap,
386 dg: DeclGen,
387 code: Writer.Allocating,
388 indent_counter: usize,
389 /// Key is an enum type for which we need a generated `@tagName` function.
390 need_tag_name_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
391 /// Key is a function Nav for which we need a generated `zig_never_tail` wrapper.
392 need_never_tail_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void),
393 /// Key is a function Nav for which we need a generated `zig_never_inline` wrapper.
394 need_never_inline_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void),
432395 func_index: InternPool.Index,
433396 /// All the locals, to be emitted at the top of the function.
434 locals: std.ArrayList(Local) = .empty,
397 locals: std.ArrayList(LocalType) = .empty,
435398 /// Which locals are available for reuse, based on Type.
436399 free_locals_map: LocalsMap = .{},
437400 /// Locals which will not be freed by Liveness. This is used after a
......@@ -445,37 +408,41 @@ pub const Function = struct {
445408 /// for the switch cond. Dispatches should set this local to the new cond.
446409 loop_switch_conds: std.AutoHashMapUnmanaged(Air.Inst.Index, LocalIndex) = .empty,
447410
411 const indent_width = 1;
412 const indent_char = ' ';
413
414 fn newline(f: *Function) !void {
415 const w = &f.code.writer;
416 try w.writeByte('\n');
417 try w.splatByteAll(indent_char, f.indent_counter);
418 }
419 fn indent(f: *Function) void {
420 f.indent_counter += indent_width;
421 }
422 fn outdent(f: *Function) !void {
423 f.indent_counter -= indent_width;
424 const written = f.code.written();
425 switch (written[written.len - 1]) {
426 indent_char => f.code.shrinkRetainingCapacity(written.len - indent_width),
427 '\n' => try f.code.writer.splatByteAll(indent_char, f.indent_counter),
428 else => {
429 std.debug.print("\"{f}\"\n", .{std.zig.fmtString(written[written.len -| 100..])});
430 unreachable;
431 },
432 }
433 }
434
448435 fn resolveInst(f: *Function, ref: Air.Inst.Ref) !CValue {
449436 const gop = try f.value_map.getOrPut(ref);
450 if (gop.found_existing) return gop.value_ptr.*;
451
452 const pt = f.object.dg.pt;
453 const zcu = pt.zcu;
454 const val = (try f.air.value(ref, pt)).?;
455 const ty = f.typeOf(ref);
456
457 const result: CValue = if (lowersToArray(ty, zcu)) result: {
458 const ch = &f.object.code_header.writer;
459 const decl_c_value = try f.allocLocalValue(.{
460 .ctype = try f.ctypeFromType(ty, .complete),
461 .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(zcu)),
462 });
463 const gpa = f.object.dg.gpa;
464 try f.allocs.put(gpa, decl_c_value.new_local, false);
465 try ch.writeAll("static ");
466 try f.object.dg.renderTypeAndName(ch, ty, decl_c_value, Const, .none, .complete);
467 try ch.writeAll(" = ");
468 try f.object.dg.renderValue(ch, val, .StaticInitializer);
469 try ch.writeAll(";\n ");
470 break :result .{ .local = decl_c_value.new_local };
471 } else .{ .constant = val };
472
473 gop.value_ptr.* = result;
474 return result;
437 if (!gop.found_existing) {
438 const val = try f.air.value(ref, f.dg.pt);
439 gop.value_ptr.* = .{ .constant = val.? };
440 }
441 return gop.value_ptr.*;
475442 }
476443
477444 fn wantSafety(f: *Function) bool {
478 return switch (f.object.dg.pt.zcu.optimizeMode()) {
445 return switch (f.dg.pt.zcu.optimizeMode()) {
479446 .Debug, .ReleaseSafe => true,
480447 .ReleaseFast, .ReleaseSmall => false,
481448 };
......@@ -485,18 +452,16 @@ pub const Function = struct {
485452 /// those which go into `allocs`. This function does not add the resulting local into `allocs`;
486453 /// that responsibility lies with the caller.
487454 fn allocLocalValue(f: *Function, local_type: LocalType) !CValue {
488 try f.locals.ensureUnusedCapacity(f.object.dg.gpa, 1);
489 defer f.locals.appendAssumeCapacity(.{
490 .ctype = local_type.ctype,
491 .flags = .{ .alignas = local_type.alignas },
492 });
493 return .{ .new_local = @intCast(f.locals.items.len) };
455 try f.locals.ensureUnusedCapacity(f.dg.gpa, 1);
456 const index = f.locals.items.len;
457 f.locals.appendAssumeCapacity(local_type);
458 return .{ .new_local = @intCast(index) };
494459 }
495460
496461 fn allocLocal(f: *Function, inst: ?Air.Inst.Index, ty: Type) !CValue {
497462 return f.allocAlignedLocal(inst, .{
498 .ctype = try f.ctypeFromType(ty, .complete),
499 .alignas = CType.AlignAs.fromAbiAlignment(ty.abiAlignment(f.object.dg.pt.zcu)),
463 .type = ty,
464 .alignment = .none,
500465 });
501466 }
502467
......@@ -524,11 +489,10 @@ pub const Function = struct {
524489 .none => unreachable,
525490 .new_local, .local => |i| try w.print("t{d}", .{i}),
526491 .local_ref => |i| try w.print("&t{d}", .{i}),
527 .constant => |val| try f.object.dg.renderValue(w, val, location),
492 .constant => |val| try f.dg.renderValue(w, val, location),
528493 .arg => |i| try w.print("a{d}", .{i}),
529 .arg_array => |i| try f.writeCValueMember(w, .{ .arg = i }, .{ .identifier = "array" }),
530 .undef => |ty| try f.object.dg.renderUndefValue(w, ty, location),
531 else => try f.object.dg.writeCValue(w, c_value),
494 .undef => |ty| try f.dg.renderUndefValue(w, ty, location),
495 else => try f.dg.writeCValue(w, c_value),
532496 }
533497 }
534498
......@@ -537,17 +501,12 @@ pub const Function = struct {
537501 .none => unreachable,
538502 .new_local, .local, .constant => {
539503 try w.writeAll("(*");
540 try f.writeCValue(w, c_value, .Other);
504 try f.writeCValue(w, c_value, .other);
541505 try w.writeByte(')');
542506 },
543507 .local_ref => |i| try w.print("t{d}", .{i}),
544508 .arg => |i| try w.print("(*a{d})", .{i}),
545 .arg_array => |i| {
546 try w.writeAll("(*");
547 try f.writeCValueMember(w, .{ .arg = i }, .{ .identifier = "array" });
548 try w.writeByte(')');
549 },
550 else => try f.object.dg.writeCValueDeref(w, c_value),
509 else => try f.dg.writeCValueDeref(w, c_value),
551510 }
552511 }
553512
......@@ -558,119 +517,77 @@ pub const Function = struct {
558517 member: CValue,
559518 ) Error!void {
560519 switch (c_value) {
561 .new_local, .local, .local_ref, .constant, .arg, .arg_array => {
562 try f.writeCValue(w, c_value, .Other);
520 .new_local, .local, .local_ref, .constant, .arg => {
521 try f.writeCValue(w, c_value, .other);
563522 try w.writeByte('.');
564 try f.writeCValue(w, member, .Other);
523 try f.writeCValue(w, member, .other);
565524 },
566 else => return f.object.dg.writeCValueMember(w, c_value, member),
525 else => return f.dg.writeCValueMember(w, c_value, member),
567526 }
568527 }
569528
570529 fn writeCValueDerefMember(f: *Function, w: *Writer, c_value: CValue, member: CValue) !void {
571530 switch (c_value) {
572 .new_local, .local, .arg, .arg_array => {
573 try f.writeCValue(w, c_value, .Other);
531 .new_local, .local, .arg => {
532 try f.writeCValue(w, c_value, .other);
574533 try w.writeAll("->");
575534 },
576535 .constant => {
577536 try w.writeByte('(');
578 try f.writeCValue(w, c_value, .Other);
537 try f.writeCValue(w, c_value, .other);
579538 try w.writeAll(")->");
580539 },
581540 .local_ref => {
582541 try f.writeCValueDeref(w, c_value);
583542 try w.writeByte('.');
584543 },
585 else => return f.object.dg.writeCValueDerefMember(w, c_value, member),
544 else => return f.dg.writeCValueDerefMember(w, c_value, member),
586545 }
587 try f.writeCValue(w, member, .Other);
546 try f.writeCValue(w, member, .other);
588547 }
589548
590549 fn fail(f: *Function, comptime format: []const u8, args: anytype) Error {
591 return f.object.dg.fail(format, args);
592 }
593
594 fn ctypeFromType(f: *Function, ty: Type, kind: CType.Kind) !CType {
595 return f.object.dg.ctypeFromType(ty, kind);
596 }
597
598 fn byteSize(f: *Function, ctype: CType) u64 {
599 return f.object.dg.byteSize(ctype);
600 }
601
602 fn renderType(f: *Function, w: *Writer, ctype: Type) !void {
603 return f.object.dg.renderType(w, ctype);
550 return f.dg.fail(format, args);
604551 }
605552
606 fn renderCType(f: *Function, w: *Writer, ctype: CType) !void {
607 return f.object.dg.renderCType(w, ctype);
553 fn renderType(f: *Function, w: *Writer, ty: Type) !void {
554 return f.dg.renderType(w, ty);
608555 }
609556
610557 fn renderIntCast(f: *Function, w: *Writer, dest_ty: Type, src: CValue, v: Vectorize, src_ty: Type, location: ValueRenderLocation) !void {
611 return f.object.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);
558 return f.dg.renderIntCast(w, dest_ty, .{ .c_value = .{ .f = f, .value = src, .v = v } }, src_ty, location);
612559 }
613560
614561 fn fmtIntLiteralDec(f: *Function, val: Value) !std.fmt.Alt(FormatIntLiteralContext, formatIntLiteral) {
615 return f.object.dg.fmtIntLiteralDec(val, .Other);
562 return f.dg.fmtIntLiteralDec(val, .other);
616563 }
617564
618565 fn fmtIntLiteralHex(f: *Function, val: Value) !std.fmt.Alt(FormatIntLiteralContext, formatIntLiteral) {
619 return f.object.dg.fmtIntLiteralHex(val, .Other);
620 }
621
622 fn getLazyFnName(f: *Function, key: LazyFnKey) ![]const u8 {
623 const gpa = f.object.dg.gpa;
624 const pt = f.object.dg.pt;
625 const zcu = pt.zcu;
626 const ip = &zcu.intern_pool;
627 const ctype_pool = &f.object.dg.ctype_pool;
628
629 const gop = try f.lazy_fns.getOrPut(gpa, key);
630 if (!gop.found_existing) {
631 errdefer _ = f.lazy_fns.pop();
632
633 gop.value_ptr.* = .{
634 .fn_name = switch (key) {
635 .tag_name,
636 => |enum_ty| try ctype_pool.fmt(gpa, "zig_{s}_{f}__{d}", .{
637 @tagName(key),
638 fmtIdentUnsolo(ip.loadEnumType(enum_ty).name.toSlice(ip)),
639 @intFromEnum(enum_ty),
640 }),
641 .never_tail,
642 .never_inline,
643 => |owner_nav| try ctype_pool.fmt(gpa, "zig_{s}_{f}__{d}", .{
644 @tagName(key),
645 fmtIdentUnsolo(ip.getNav(owner_nav).name.toSlice(ip)),
646 @intFromEnum(owner_nav),
647 }),
648 },
649 };
650 }
651 return gop.value_ptr.fn_name.toSlice(ctype_pool).?;
566 return f.dg.fmtIntLiteralHex(val, .other);
652567 }
653568
654569 pub fn deinit(f: *Function) void {
655 const gpa = f.object.dg.gpa;
570 const gpa = f.dg.gpa;
656571 f.allocs.deinit(gpa);
657572 f.locals.deinit(gpa);
658573 deinitFreeLocalsMap(gpa, &f.free_locals_map);
659574 f.blocks.deinit(gpa);
660575 f.value_map.deinit();
661 f.lazy_fns.deinit(gpa);
576 f.need_tag_name_funcs.deinit(gpa);
577 f.need_never_tail_funcs.deinit(gpa);
578 f.need_never_inline_funcs.deinit(gpa);
662579 f.loop_switch_conds.deinit(gpa);
663580 }
664581
665582 fn typeOf(f: *Function, inst: Air.Inst.Ref) Type {
666 return f.air.typeOf(inst, &f.object.dg.pt.zcu.intern_pool);
583 return f.air.typeOf(inst, &f.dg.pt.zcu.intern_pool);
667584 }
668585
669586 fn typeOfIndex(f: *Function, inst: Air.Inst.Index) Type {
670 return f.air.typeOfIndex(inst, &f.object.dg.pt.zcu.intern_pool);
587 return f.air.typeOfIndex(inst, &f.dg.pt.zcu.intern_pool);
671588 }
672589
673 fn copyCValue(f: *Function, ctype: CType, dst: CValue, src: CValue) !void {
590 fn copyCValue(f: *Function, dst: CValue, src: CValue) !void {
674591 switch (dst) {
675592 .new_local, .local => |dst_local_index| switch (src) {
676593 .new_local, .local => |src_local_index| if (dst_local_index == src_local_index) return,
......@@ -678,12 +595,12 @@ pub const Function = struct {
678595 },
679596 else => {},
680597 }
681 const w = &f.object.code.writer;
682 const a = try Assignment.start(f, w, ctype);
683 try f.writeCValue(w, dst, .Other);
684 try a.assign(f, w);
685 try f.writeCValue(w, src, .Other);
686 try a.end(f, w);
598 const w = &f.code.writer;
599 try f.writeCValue(w, dst, .other);
600 try w.writeAll(" = ");
601 try f.writeCValue(w, src, .other);
602 try w.writeByte(';');
603 try f.newline();
687604 }
688605
689606 fn moveCValue(f: *Function, inst: Air.Inst.Index, ty: Type, src: CValue) !CValue {
......@@ -694,7 +611,7 @@ pub const Function = struct {
694611 else => {
695612 try freeCValue(f, inst, src);
696613 const dst = try f.allocLocal(inst, ty);
697 try f.copyCValue(try f.ctypeFromType(ty, .complete), dst, src);
614 try f.copyCValue(dst, src);
698615 return dst;
699616 },
700617 }
......@@ -708,51 +625,17 @@ pub const Function = struct {
708625 }
709626};
710627
711/// This data is available when outputting .c code for a `Zcu`.
712/// It is not available when generating .h file.
713pub const Object = struct {
714 dg: DeclGen,
715 code_header: Writer.Allocating,
716 code: Writer.Allocating,
717 indent_counter: usize,
718
719 const indent_width = 1;
720 const indent_char = ' ';
721
722 fn newline(o: *Object) !void {
723 const w = &o.code.writer;
724 try w.writeByte('\n');
725 try w.splatByteAll(indent_char, o.indent_counter);
726 }
727 fn indent(o: *Object) void {
728 o.indent_counter += indent_width;
729 }
730 fn outdent(o: *Object) !void {
731 o.indent_counter -= indent_width;
732 const written = o.code.written();
733 switch (written[written.len - 1]) {
734 indent_char => o.code.shrinkRetainingCapacity(written.len - indent_width),
735 '\n' => try o.code.writer.splatByteAll(indent_char, o.indent_counter),
736 else => {
737 std.debug.print("\"{f}\"\n", .{std.zig.fmtString(written[written.len -| 100..])});
738 unreachable;
739 },
740 }
741 }
742};
743
744/// This data is available both when outputting .c code and when outputting an .h file.
628/// This data is available when rendering *any* C source code (function or otherwise).
745629pub const DeclGen = struct {
746630 gpa: Allocator,
631 arena: Allocator,
747632 pt: Zcu.PerThread,
748633 mod: *Module,
749 pass: Pass,
634 owner_nav: InternPool.Nav.Index.Optional,
750635 is_naked_fn: bool,
751636 expected_block: ?u32,
752 fwd_decl: Writer.Allocating,
753637 error_msg: ?*Zcu.ErrorMsg,
754 ctype_pool: CType.Pool,
755 scratch: std.ArrayList(u32),
638 ctype_deps: CType.Dependencies,
756639 /// This map contains all the UAVs we saw generating this function.
757640 /// `link.C` will merge them into its `uavs`/`aligned_uavs` fields.
758641 /// Key is the value of the UAV; value is the UAV's alignment, or
......@@ -760,16 +643,10 @@ pub const DeclGen = struct {
760643 /// less than the natural alignment.
761644 uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
762645
763 pub const Pass = union(enum) {
764 nav: InternPool.Nav.Index,
765 uav: InternPool.Index,
766 flush,
767 };
768
769646 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) Error {
770647 @branchHint(.cold);
771648 const zcu = dg.pt.zcu;
772 const src_loc = zcu.navSrcLoc(dg.pass.nav);
649 const src_loc = zcu.navSrcLoc(dg.owner_nav.unwrap().?);
773650 dg.error_msg = try Zcu.ErrorMsg.create(dg.gpa, src_loc, format, args);
774651 return error.AnalysisFail;
775652 }
......@@ -783,14 +660,13 @@ pub const DeclGen = struct {
783660 const pt = dg.pt;
784661 const zcu = pt.zcu;
785662 const ip = &zcu.intern_pool;
786 const ctype_pool = &dg.ctype_pool;
787663 const uav_val = Value.fromInterned(uav.val);
788664 const uav_ty = uav_val.typeOf(zcu);
789665
790666 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
791667 const ptr_ty: Type = .fromInterned(uav.orig_ty);
792 if (ptr_ty.isPtrAtRuntime(zcu) and !uav_ty.isFnOrHasRuntimeBits(zcu)) {
793 return dg.writeCValue(w, .{ .undef = ptr_ty });
668 if (ptr_ty.isPtrAtRuntime(zcu) and !uav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) {
669 return dg.renderUndefValue(w, ptr_ty, location);
794670 }
795671
796672 // Chase function values in order to be able to reference the original function.
......@@ -805,14 +681,12 @@ pub const DeclGen = struct {
805681 // them). The analysis until now should ensure that the C function
806682 // pointers are compatible. If they are not, then there is a bug
807683 // somewhere and we should let the C compiler tell us about it.
808 const ptr_ctype = try dg.ctypeFromType(ptr_ty, .complete);
809 const elem_ctype = ptr_ctype.info(ctype_pool).pointer.elem_ctype;
810 const uav_ctype = try dg.ctypeFromType(uav_ty, .complete);
811 const need_cast = !elem_ctype.eql(uav_ctype) and
812 (elem_ctype.info(ctype_pool) != .function or uav_ctype.info(ctype_pool) != .function);
684 const elem_ty = ptr_ty.childType(zcu);
685 const need_cast = elem_ty.toIntern() != uav_ty.toIntern() and
686 elem_ty.zigTypeTag(zcu) != .@"fn" or uav_ty.zigTypeTag(zcu) != .@"fn";
813687 if (need_cast) {
814688 try w.writeAll("((");
815 try dg.renderCType(w, ptr_ctype);
689 try dg.renderType(w, ptr_ty);
816690 try w.writeByte(')');
817691 }
818692 try w.writeByte('&');
......@@ -842,11 +716,9 @@ pub const DeclGen = struct {
842716 nav_index: InternPool.Nav.Index,
843717 location: ValueRenderLocation,
844718 ) Error!void {
845 _ = location;
846719 const pt = dg.pt;
847720 const zcu = pt.zcu;
848721 const ip = &zcu.intern_pool;
849 const ctype_pool = &dg.ctype_pool;
850722
851723 // Chase function values in order to be able to reference the original function.
852724 const owner_nav = switch (ip.getNav(nav_index).status) {
......@@ -862,26 +734,24 @@ pub const DeclGen = struct {
862734 // Render an undefined pointer if we have a pointer to a zero-bit or comptime type.
863735 const nav_ty: Type = .fromInterned(ip.getNav(owner_nav).typeOf(ip));
864736 const ptr_ty = try pt.navPtrType(owner_nav);
865 if (!nav_ty.isFnOrHasRuntimeBits(zcu)) {
866 return dg.writeCValue(w, .{ .undef = ptr_ty });
737 if (!nav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) {
738 return dg.renderUndefValue(w, ptr_ty, location);
867739 }
868740
869741 // We shouldn't cast C function pointers as this is UB (when you call
870742 // them). The analysis until now should ensure that the C function
871743 // pointers are compatible. If they are not, then there is a bug
872744 // somewhere and we should let the C compiler tell us about it.
873 const ctype = try dg.ctypeFromType(ptr_ty, .complete);
874 const elem_ctype = ctype.info(ctype_pool).pointer.elem_ctype;
875 const nav_ctype = try dg.ctypeFromType(nav_ty, .complete);
876 const need_cast = !elem_ctype.eql(nav_ctype) and
877 (elem_ctype.info(ctype_pool) != .function or nav_ctype.info(ctype_pool) != .function);
745 const elem_ty = ptr_ty.childType(zcu);
746 const need_cast = elem_ty.toIntern() != nav_ty.toIntern() and
747 elem_ty.zigTypeTag(zcu) != .@"fn" or nav_ty.zigTypeTag(zcu) != .@"fn";
878748 if (need_cast) {
879749 try w.writeAll("((");
880 try dg.renderCType(w, ctype);
750 try dg.renderType(w, ptr_ty);
881751 try w.writeByte(')');
882752 }
883753 try w.writeByte('&');
884 try dg.renderNavName(w, owner_nav);
754 try renderNavName(w, owner_nav, ip);
885755 if (need_cast) try w.writeByte(')');
886756 }
887757
......@@ -896,11 +766,10 @@ pub const DeclGen = struct {
896766 switch (derivation) {
897767 .comptime_alloc_ptr, .comptime_field_ptr => unreachable,
898768 .int => |int| {
899 const ptr_ctype = try dg.ctypeFromType(int.ptr_ty, .complete);
900769 const addr_val = try pt.intValue(.usize, int.addr);
901770 try w.writeByte('(');
902 try dg.renderCType(w, ptr_ctype);
903 try w.print("){f}", .{try dg.fmtIntLiteralHex(addr_val, .Other)});
771 try dg.renderType(w, int.ptr_ty);
772 try w.print("){f}", .{try dg.fmtIntLiteralHex(addr_val, .other)});
904773 },
905774
906775 .nav_ptr => |nav| try dg.renderNav(w, nav, location),
......@@ -915,14 +784,10 @@ pub const DeclGen = struct {
915784 .field_ptr => |field| {
916785 const parent_ptr_ty = try field.parent.ptrType(pt);
917786
918 // Ensure complete type definition is available before accessing fields.
919 _ = try dg.ctypeFromType(parent_ptr_ty.childType(zcu), .complete);
920
921787 switch (fieldLocation(parent_ptr_ty, field.result_ptr_ty, field.field_idx, zcu)) {
922788 .begin => {
923 const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete);
924789 try w.writeByte('(');
925 try dg.renderCType(w, ptr_ctype);
790 try dg.renderType(w, field.result_ptr_ty);
926791 try w.writeByte(')');
927792 try dg.renderPointer(w, field.parent.*, location);
928793 },
......@@ -933,51 +798,40 @@ pub const DeclGen = struct {
933798 try dg.writeCValue(w, name);
934799 },
935800 .byte_offset => |byte_offset| {
936 const ptr_ctype = try dg.ctypeFromType(field.result_ptr_ty, .complete);
937801 try w.writeByte('(');
938 try dg.renderCType(w, ptr_ctype);
802 try dg.renderType(w, field.result_ptr_ty);
939803 try w.writeByte(')');
940804 const offset_val = try pt.intValue(.usize, byte_offset);
941805 try w.writeAll("((char *)");
942806 try dg.renderPointer(w, field.parent.*, location);
943 try w.print(" + {f})", .{try dg.fmtIntLiteralDec(offset_val, .Other)});
807 try w.print(" + {f})", .{try dg.fmtIntLiteralDec(offset_val, .other)});
944808 },
945809 }
946810 },
947811
948812 .elem_ptr => |elem| if (!(try elem.parent.ptrType(pt)).childType(zcu).hasRuntimeBits(zcu)) {
949813 // Element type is zero-bit, so lowers to `void`. The index is irrelevant; just cast the pointer.
950 const ptr_ctype = try dg.ctypeFromType(elem.result_ptr_ty, .complete);
951814 try w.writeByte('(');
952 try dg.renderCType(w, ptr_ctype);
815 try dg.renderType(w, elem.result_ptr_ty);
953816 try w.writeByte(')');
954817 try dg.renderPointer(w, elem.parent.*, location);
955818 } else {
956819 const index_val = try pt.intValue(.usize, elem.elem_idx);
957 // We want to do pointer arithmetic on a pointer to the element type.
958 // We might have a pointer-to-array. In this case, we must cast first.
959 const result_ctype = try dg.ctypeFromType(elem.result_ptr_ty, .complete);
960 const parent_ctype = try dg.ctypeFromType(try elem.parent.ptrType(pt), .complete);
961 if (result_ctype.eql(parent_ctype)) {
962 // The pointer already has an appropriate type - just do the arithmetic.
820 try w.writeByte('(');
821 // We want to do pointer arithmetic on a pointer to the element type, but the parent
822 // might be a pointer-to-array, in which case we must cast it.
823 if (elem.result_ptr_ty.toIntern() != (try elem.parent.ptrType(pt)).toIntern()) {
963824 try w.writeByte('(');
964 try dg.renderPointer(w, elem.parent.*, location);
965 try w.print(" + {f})", .{try dg.fmtIntLiteralDec(index_val, .Other)});
966 } else {
967 // We probably have an array pointer `T (*)[n]`. Cast to an element pointer,
968 // and *then* apply the index.
969 try w.writeAll("((");
970 try dg.renderCType(w, result_ctype);
825 try dg.renderType(w, elem.result_ptr_ty);
971826 try w.writeByte(')');
972 try dg.renderPointer(w, elem.parent.*, location);
973 try w.print(" + {f})", .{try dg.fmtIntLiteralDec(index_val, .Other)});
974827 }
828 try dg.renderPointer(w, elem.parent.*, location);
829 try w.print(" + {f})", .{try dg.fmtIntLiteralDec(index_val, .other)});
975830 },
976831
977832 .offset_and_cast => |oac| {
978 const ptr_ctype = try dg.ctypeFromType(oac.new_ptr_ty, .complete);
979833 try w.writeByte('(');
980 try dg.renderCType(w, ptr_ctype);
834 try dg.renderType(w, oac.new_ptr_ty);
981835 try w.writeByte(')');
982836 if (oac.byte_offset == 0) {
983837 try dg.renderPointer(w, oac.parent.*, location);
......@@ -985,14 +839,40 @@ pub const DeclGen = struct {
985839 const offset_val = try pt.intValue(.usize, oac.byte_offset);
986840 try w.writeAll("((char *)");
987841 try dg.renderPointer(w, oac.parent.*, location);
988 try w.print(" + {f})", .{try dg.fmtIntLiteralDec(offset_val, .Other)});
842 try w.print(" + {f})", .{try dg.fmtIntLiteralDec(offset_val, .other)});
989843 }
990844 },
991845 }
992846 }
993847
994 fn renderErrorName(dg: *DeclGen, w: *Writer, err_name: InternPool.NullTerminatedString) !void {
995 try w.print("zig_error_{f}", .{fmtIdentUnsolo(err_name.toSlice(&dg.pt.zcu.intern_pool))});
848 fn renderValueAsLvalue(
849 dg: *DeclGen,
850 w: *Writer,
851 val: Value,
852 ) Error!void {
853 const zcu = dg.pt.zcu;
854
855 // If the type of `val` lowers to a C struct or union type, then `renderValue` will render
856 // it as a compound literal, and compound literals are already lvalues.
857 const ty = val.typeOf(zcu);
858 const is_aggregate: bool = switch (ty.zigTypeTag(zcu)) {
859 .@"struct", .@"union" => switch (ty.containerLayout(zcu)) {
860 .auto, .@"extern" => true,
861 .@"packed" => false,
862 },
863 .array,
864 .vector,
865 .error_union,
866 .optional,
867 => true,
868 else => false,
869 };
870 if (is_aggregate) return renderValue(dg, w, val, .other);
871
872 // Otherwise, use a UAV.
873 const gop = try dg.uavs.getOrPut(dg.gpa, val.toIntern());
874 if (!gop.found_existing) gop.value_ptr.* = .none;
875 try renderUavName(w, val);
996876 }
997877
998878 fn renderValue(
......@@ -1005,16 +885,13 @@ pub const DeclGen = struct {
1005885 const zcu = pt.zcu;
1006886 const ip = &zcu.intern_pool;
1007887 const target = &dg.mod.resolved_target.result;
1008 const ctype_pool = &dg.ctype_pool;
1009888
1010889 const initializer_type: ValueRenderLocation = switch (location) {
1011 .StaticInitializer => .StaticInitializer,
1012 else => .Initializer,
890 .static_initializer => .static_initializer,
891 else => .initializer,
1013892 };
1014893
1015894 const ty = val.typeOf(zcu);
1016 if (val.isUndef(zcu)) return dg.renderUndefValue(w, ty, location);
1017 const ctype = try dg.ctypeFromType(ty, location.toCTypeKind());
1018895 switch (ip.indexToKey(val.toIntern())) {
1019896 // types, not values
1020897 .int_type,
......@@ -1037,13 +914,11 @@ pub const DeclGen = struct {
1037914 .memoized_call,
1038915 => unreachable,
1039916
1040 .undef => unreachable, // handled above
917 .undef => try dg.renderUndefValue(w, ty, location),
1041918 .simple_value => |simple_value| switch (simple_value) {
1042919 // non-runtime values
1043 .undefined => unreachable,
1044920 .void => unreachable,
1045921 .null => unreachable,
1046 .empty_tuple => unreachable,
1047922 .@"unreachable" => unreachable,
1048923
1049924 .false => try w.writeAll("false"),
......@@ -1053,59 +928,30 @@ pub const DeclGen = struct {
1053928 .@"extern",
1054929 .func,
1055930 .enum_literal,
1056 .empty_enum_value,
1057931 => unreachable, // non-runtime values
1058 .int => |int| switch (int.storage) {
1059 .u64, .i64, .big_int => try w.print("{f}", .{try dg.fmtIntLiteralDec(val, location)}),
1060 .lazy_align, .lazy_size => {
1061 try w.writeAll("((");
1062 try dg.renderCType(w, ctype);
1063 try w.print("){f})", .{try dg.fmtIntLiteralHex(
1064 try pt.intValue(.usize, val.toUnsignedInt(zcu)),
1065 .Other,
1066 )});
1067 },
1068 },
1069 .err => |err| try dg.renderErrorName(w, err.name),
1070 .error_union => |error_union| switch (ctype.info(ctype_pool)) {
1071 .basic => switch (error_union.val) {
1072 .err_name => |err_name| try dg.renderErrorName(w, err_name),
932 .int => try w.print("{f}", .{try dg.fmtIntLiteralDec(val, location)}),
933 .err => |err| try renderErrorName(w, err.name.toSlice(ip)),
934 .error_union => |error_union| {
935 if (!location.isInitializer()) {
936 try w.writeByte('(');
937 try dg.renderType(w, ty);
938 try w.writeByte(')');
939 }
940 try w.writeAll("{ .error = ");
941 switch (error_union.val) {
942 .err_name => |err_name| try renderErrorName(w, err_name.toSlice(ip)),
1073943 .payload => try w.writeByte('0'),
1074 },
1075 .pointer, .aligned, .array, .vector, .fwd_decl, .function => unreachable,
1076 .aggregate => |aggregate| {
1077 if (!location.isInitializer()) {
1078 try w.writeByte('(');
1079 try dg.renderCType(w, ctype);
1080 try w.writeByte(')');
1081 }
1082 try w.writeByte('{');
1083 for (0..aggregate.fields.len) |field_index| {
1084 if (field_index > 0) try w.writeByte(',');
1085 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
1086 .@"error" => switch (error_union.val) {
1087 .err_name => |err_name| try dg.renderErrorName(w, err_name),
1088 .payload => try w.writeByte('0'),
1089 },
1090 .payload => switch (error_union.val) {
1091 .err_name => try dg.renderUndefValue(
1092 w,
1093 ty.errorUnionPayload(zcu),
1094 initializer_type,
1095 ),
1096 .payload => |payload| try dg.renderValue(
1097 w,
1098 Value.fromInterned(payload),
1099 initializer_type,
1100 ),
1101 },
1102 else => unreachable,
1103 }
944 }
945 if (ty.errorUnionPayload(zcu).hasRuntimeBits(zcu)) {
946 try w.writeAll(", .payload = ");
947 switch (error_union.val) {
948 .err_name => try dg.renderUndefValue(w, ty.errorUnionPayload(zcu), initializer_type),
949 .payload => |payload| try dg.renderValue(w, .fromInterned(payload), initializer_type),
1104950 }
1105 try w.writeByte('}');
1106 },
951 }
952 try w.writeAll(" }");
1107953 },
1108 .enum_tag => |enum_tag| try dg.renderValue(w, Value.fromInterned(enum_tag.int), location),
954 .enum_tag => |enum_tag| try dg.renderValue(w, .fromInterned(enum_tag.int), location),
1109955 .float => {
1110956 const bits = ty.floatBits(target);
1111957 const f128_val = val.toFloat(f128, zcu);
......@@ -1156,7 +1002,7 @@ pub const DeclGen = struct {
11561002 else
11571003 unreachable;
11581004
1159 if (location == .StaticInitializer) {
1005 if (location == .static_initializer) {
11601006 if (!std.math.isNan(f128_val) and std.math.isSignalNan(f128_val))
11611007 return dg.fail("TODO: C backend: implement nans rendering in static initializers", .{});
11621008
......@@ -1167,9 +1013,11 @@ pub const DeclGen = struct {
11671013 // return dg.fail("Only quiet nans are supported in global variable initializers", .{});
11681014 }
11691015
1170 try w.writeAll("zig_");
1171 try w.writeAll(if (location == .StaticInitializer) "init" else "make");
1172 try w.writeAll("_special_");
1016 if (location == .static_initializer) {
1017 try w.writeAll("zig_init_special_");
1018 } else {
1019 try w.writeAll("zig_make_special_");
1020 }
11731021 try dg.renderTypeForBuiltinFnName(w, ty);
11741022 try w.writeByte('(');
11751023 if (std.math.signbit(f128_val)) try w.writeByte('-');
......@@ -1196,105 +1044,85 @@ pub const DeclGen = struct {
11961044 if (!empty) try w.writeByte(')');
11971045 },
11981046 .slice => |slice| {
1199 const aggregate = ctype.info(ctype_pool).aggregate;
12001047 if (!location.isInitializer()) {
12011048 try w.writeByte('(');
1202 try dg.renderCType(w, ctype);
1049 try dg.renderType(w, ty);
12031050 try w.writeByte(')');
12041051 }
12051052 try w.writeByte('{');
1206 for (0..aggregate.fields.len) |field_index| {
1207 if (field_index > 0) try w.writeByte(',');
1208 try dg.renderValue(w, Value.fromInterned(
1209 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
1210 .ptr => slice.ptr,
1211 .len => slice.len,
1212 else => unreachable,
1213 },
1214 ), initializer_type);
1215 }
1053 try dg.renderValue(w, .fromInterned(slice.ptr), initializer_type);
1054 try w.writeByte(',');
1055 try dg.renderValue(w, .fromInterned(slice.len), initializer_type);
12161056 try w.writeByte('}');
12171057 },
12181058 .ptr => {
1219 var arena = std.heap.ArenaAllocator.init(zcu.gpa);
1220 defer arena.deinit();
1221 const derivation = try val.pointerDerivation(arena.allocator(), pt);
1059 const derivation = try val.pointerDerivation(dg.arena, pt, null);
1060 try w.writeByte('(');
12221061 try dg.renderPointer(w, derivation, location);
1062 try w.writeByte(')');
12231063 },
1224 .opt => |opt| switch (ctype.info(ctype_pool)) {
1225 .basic => if (ctype.isBool()) try w.writeAll(switch (opt.val) {
1226 .none => "true",
1227 else => "false",
1228 }) else switch (opt.val) {
1064 .opt => |opt| switch (CType.classifyOptional(ty, zcu)) {
1065 .npv_payload => unreachable, // opv optional
1066 .opv_payload => {
1067 if (!location.isInitializer()) {
1068 try w.writeByte('(');
1069 try dg.renderType(w, ty);
1070 try w.writeByte(')');
1071 }
1072 try w.writeAll(switch (opt.val) {
1073 .none => "{.is_null = true}",
1074 else => "{.is_null = false}",
1075 });
1076 },
1077 .error_set => switch (opt.val) {
12291078 .none => try w.writeByte('0'),
1230 else => |payload| switch (ip.indexToKey(payload)) {
1231 .undef => |err_ty| try dg.renderUndefValue(
1232 w,
1233 .fromInterned(err_ty),
1234 location,
1235 ),
1236 .err => |err| try dg.renderErrorName(w, err.name),
1237 else => unreachable,
1238 },
1079 else => |payload_val| try dg.renderValue(w, .fromInterned(payload_val), location),
12391080 },
1240 .pointer => switch (opt.val) {
1081 .ptr_like => switch (opt.val) {
12411082 .none => try w.writeAll("NULL"),
1242 else => |payload| try dg.renderValue(w, Value.fromInterned(payload), location),
1083 else => |payload_val| try dg.renderValue(w, .fromInterned(payload_val), location),
12431084 },
1244 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
1245 .aggregate => |aggregate| {
1246 switch (opt.val) {
1247 .none => {},
1248 else => |payload| switch (aggregate.fields.at(0, ctype_pool).name.index) {
1249 .is_null, .payload => {},
1250 .ptr, .len => return dg.renderValue(
1251 w,
1252 Value.fromInterned(payload),
1253 location,
1254 ),
1255 else => unreachable,
1256 },
1257 }
1085 .slice_like => switch (opt.val) {
1086 .none => {
1087 if (!location.isInitializer()) {
1088 try w.writeByte('(');
1089 try dg.renderType(w, ty);
1090 try w.writeByte(')');
1091 }
1092 try w.writeAll("{NULL,");
1093 try dg.renderUndefValue(w, .usize, initializer_type);
1094 try w.writeByte('}');
1095 },
1096 else => |payload_val| try dg.renderValue(w, .fromInterned(payload_val), location),
1097 },
1098 .@"struct" => {
12581099 if (!location.isInitializer()) {
12591100 try w.writeByte('(');
1260 try dg.renderCType(w, ctype);
1101 try dg.renderType(w, ty);
12611102 try w.writeByte(')');
12621103 }
1263 try w.writeByte('{');
1264 for (0..aggregate.fields.len) |field_index| {
1265 if (field_index > 0) try w.writeByte(',');
1266 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
1267 .is_null => try w.writeAll(switch (opt.val) {
1268 .none => "true",
1269 else => "false",
1270 }),
1271 .payload => switch (opt.val) {
1272 .none => try dg.renderUndefValue(
1273 w,
1274 ty.optionalChild(zcu),
1275 initializer_type,
1276 ),
1277 else => |payload| try dg.renderValue(
1278 w,
1279 Value.fromInterned(payload),
1280 initializer_type,
1281 ),
1282 },
1283 .ptr => try w.writeAll("NULL"),
1284 .len => try dg.renderUndefValue(w, .usize, initializer_type),
1285 else => unreachable,
1286 }
1104 switch (opt.val) {
1105 .none => {
1106 try w.writeAll("{ .is_null = true, .payload = ");
1107 try dg.renderUndefValue(w, ty.optionalChild(zcu), initializer_type);
1108 try w.writeAll(" }");
1109 },
1110 else => |payload_val| {
1111 try w.writeAll("{ .is_null = false, .payload = ");
1112 try dg.renderValue(w, .fromInterned(payload_val), initializer_type);
1113 try w.writeAll(" }");
1114 },
12871115 }
1288 try w.writeByte('}');
12891116 },
12901117 },
12911118 .aggregate => switch (ip.indexToKey(ty.toIntern())) {
12921119 .array_type, .vector_type => {
1293 if (location == .FunctionArgument) {
1120 if (!location.isInitializer()) {
12941121 try w.writeByte('(');
1295 try dg.renderCType(w, ctype);
1122 try dg.renderType(w, ty);
12961123 try w.writeByte(')');
12971124 }
1125 try w.writeByte('{');
12981126 const ai = ty.arrayInfo(zcu);
12991127 if (ai.elem_type.eql(.u8, zcu)) {
13001128 var literal: StringLiteral = .init(w, @intCast(ty.arrayLenIncludingSentinel(zcu)));
......@@ -1327,11 +1155,12 @@ pub const DeclGen = struct {
13271155 }
13281156 try w.writeByte('}');
13291157 }
1158 try w.writeByte('}');
13301159 },
13311160 .tuple_type => |tuple| {
13321161 if (!location.isInitializer()) {
13331162 try w.writeByte('(');
1334 try dg.renderCType(w, ctype);
1163 try dg.renderType(w, ty);
13351164 try w.writeByte(')');
13361165 }
13371166
......@@ -1341,7 +1170,7 @@ pub const DeclGen = struct {
13411170 const comptime_val = tuple.values.get(ip)[field_index];
13421171 if (comptime_val != .none) continue;
13431172 const field_ty: Type = .fromInterned(tuple.types.get(ip)[field_index]);
1344 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
1173 if (!field_ty.hasRuntimeBits(zcu)) continue;
13451174
13461175 if (!empty) try w.writeByte(',');
13471176
......@@ -1363,139 +1192,95 @@ pub const DeclGen = struct {
13631192 },
13641193 .struct_type => {
13651194 const loaded_struct = ip.loadStructType(ty.toIntern());
1366 switch (loaded_struct.layout) {
1367 .auto, .@"extern" => {
1368 if (!location.isInitializer()) {
1369 try w.writeByte('(');
1370 try dg.renderCType(w, ctype);
1371 try w.writeByte(')');
1372 }
1195 assert(loaded_struct.layout != .@"packed");
13731196
1374 try w.writeByte('{');
1375 var field_it = loaded_struct.iterateRuntimeOrder(ip);
1376 var need_comma = false;
1377 while (field_it.next()) |field_index| {
1378 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
1379 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
1197 if (!location.isInitializer()) {
1198 try w.writeByte('(');
1199 try dg.renderType(w, ty);
1200 try w.writeByte(')');
1201 }
13801202
1381 if (need_comma) try w.writeByte(',');
1382 need_comma = true;
1383 const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
1384 .bytes => |bytes| try pt.intern(.{ .int = .{
1385 .ty = field_ty.toIntern(),
1386 .storage = .{ .u64 = bytes.at(field_index, ip) },
1387 } }),
1388 .elems => |elems| elems[field_index],
1389 .repeated_elem => |elem| elem,
1390 };
1391 try dg.renderValue(w, Value.fromInterned(field_val), initializer_type);
1392 }
1393 try w.writeByte('}');
1394 },
1395 .@"packed" => {
1396 // https://github.com/ziglang/zig/issues/24657 will eliminate most of the
1397 // following logic, leaving only the recursive `renderValue` call. Once
1398 // that proposal is implemented, a `packed struct` will literally be
1399 // represented in the InternPool by its comptime-known backing integer.
1400 var arena: std.heap.ArenaAllocator = .init(zcu.gpa);
1401 defer arena.deinit();
1402 const backing_ty: Type = .fromInterned(loaded_struct.backingIntTypeUnordered(ip));
1403 const buf = try arena.allocator().alloc(u8, @intCast(ty.abiSize(zcu)));
1404 val.writeToMemory(pt, buf) catch |err| switch (err) {
1405 error.IllDefinedMemoryLayout => unreachable,
1406 error.OutOfMemory => |e| return e,
1407 error.ReinterpretDeclRef, error.Unimplemented => return dg.fail("TODO: C backend: lower packed struct value", .{}),
1408 };
1409 const backing_val: Value = try .readUintFromMemory(backing_ty, pt, buf, arena.allocator());
1410 return dg.renderValue(w, backing_val, location);
1411 },
1203 try w.writeByte('{');
1204 var field_it = loaded_struct.iterateRuntimeOrder(ip);
1205 var need_comma = false;
1206 while (field_it.next()) |field_index| {
1207 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
1208 if (!field_ty.hasRuntimeBits(zcu)) continue;
1209
1210 if (need_comma) try w.writeByte(',');
1211 need_comma = true;
1212 const field_val = switch (ip.indexToKey(val.toIntern()).aggregate.storage) {
1213 .bytes => |bytes| try pt.intern(.{ .int = .{
1214 .ty = field_ty.toIntern(),
1215 .storage = .{ .u64 = bytes.at(field_index, ip) },
1216 } }),
1217 .elems => |elems| elems[field_index],
1218 .repeated_elem => |elem| elem,
1219 };
1220 try dg.renderValue(w, Value.fromInterned(field_val), initializer_type);
14121221 }
1222 try w.writeByte('}');
14131223 },
14141224 else => unreachable,
14151225 },
1226 .bitpack => |bitpack| return dg.renderValue(w, .fromInterned(bitpack.backing_int_val), location),
14161227 .un => |un| {
14171228 const loaded_union = ip.loadUnionType(ty.toIntern());
1418 if (loaded_union.flagsUnordered(ip).layout == .@"packed") {
1419 // https://github.com/ziglang/zig/issues/24657 will eliminate most of the
1420 // following logic, leaving only the recursive `renderValue` call. Once
1421 // that proposal is implemented, a `packed union` will literally be
1422 // represented in the InternPool by its comptime-known backing integer.
1423 var arena: std.heap.ArenaAllocator = .init(zcu.gpa);
1424 defer arena.deinit();
1425 const backing_ty = try ty.unionBackingType(pt);
1426 const buf = try arena.allocator().alloc(u8, @intCast(ty.abiSize(zcu)));
1427 val.writeToMemory(pt, buf) catch |err| switch (err) {
1428 error.IllDefinedMemoryLayout => unreachable,
1429 error.OutOfMemory => |e| return e,
1430 error.ReinterpretDeclRef, error.Unimplemented => return dg.fail("TODO: C backend: lower packed union value", .{}),
1431 };
1432 const backing_val: Value = try .readUintFromMemory(backing_ty, pt, buf, arena.allocator());
1433 return dg.renderValue(w, backing_val, location);
1434 }
14351229 if (un.tag == .none) {
1436 const backing_ty = try ty.unionBackingType(pt);
1437 assert(loaded_union.flagsUnordered(ip).layout == .@"extern");
1438 if (location == .StaticInitializer) {
1230 assert(loaded_union.layout == .@"extern");
1231 if (location == .static_initializer) {
14391232 return dg.fail("TODO: C backend: implement extern union backing type rendering in static initializers", .{});
14401233 }
14411234
14421235 const ptr_ty = try pt.singleConstPtrType(ty);
1443 try w.writeAll("*((");
1236 try w.writeAll("*(");
14441237 try dg.renderType(w, ptr_ty);
1445 try w.writeAll(")(");
1446 try dg.renderType(w, backing_ty);
1447 try w.writeAll("){");
1448 try dg.renderValue(w, Value.fromInterned(un.val), location);
1449 try w.writeAll("})");
1238 try w.writeAll(")&");
1239 // We need an lvalue for '&'.
1240 try dg.renderValueAsLvalue(w, .fromInterned(un.val));
14501241 } else {
14511242 if (!location.isInitializer()) {
14521243 try w.writeByte('(');
1453 try dg.renderCType(w, ctype);
1244 try dg.renderType(w, ty);
14541245 try w.writeByte(')');
14551246 }
1247 if (ty.unionHasAllZeroBitFieldTypes(zcu)) {
1248 assert(loaded_union.has_runtime_tag); // otherwise it does not have runtime bits
1249 try w.writeAll("{ .tag = ");
1250 try dg.renderValue(w, .fromInterned(un.tag), initializer_type);
1251 try w.writeAll(" }");
1252 return;
1253 }
14561254
1457 const field_index = zcu.unionTagFieldIndex(loaded_union, Value.fromInterned(un.tag)).?;
1458 const field_ty: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
1459 const field_name = loaded_union.loadTagType(ip).names.get(ip)[field_index];
1460
1461 const has_tag = loaded_union.hasTag(ip);
1462 if (has_tag) try w.writeByte('{');
1463 const aggregate = ctype.info(ctype_pool).aggregate;
1464 for (0..if (has_tag) aggregate.fields.len else 1) |outer_field_index| {
1465 if (outer_field_index > 0) try w.writeByte(',');
1466 switch (if (has_tag)
1467 aggregate.fields.at(outer_field_index, ctype_pool).name.index
1468 else
1469 .payload) {
1470 .tag => try dg.renderValue(
1471 w,
1472 Value.fromInterned(un.tag),
1473 initializer_type,
1474 ),
1475 .payload => {
1476 try w.writeByte('{');
1477 if (field_ty.hasRuntimeBits(zcu)) {
1478 try w.print(" .{f} = ", .{fmtIdentSolo(field_name.toSlice(ip))});
1479 try dg.renderValue(
1480 w,
1481 Value.fromInterned(un.val),
1482 initializer_type,
1483 );
1484 try w.writeByte(' ');
1485 } else for (0..loaded_union.field_types.len) |inner_field_index| {
1486 const inner_field_ty: Type = .fromInterned(
1487 loaded_union.field_types.get(ip)[inner_field_index],
1488 );
1489 if (!inner_field_ty.hasRuntimeBits(zcu)) continue;
1490 try dg.renderUndefValue(w, inner_field_ty, initializer_type);
1491 break;
1492 }
1493 try w.writeByte('}');
1494 },
1495 else => unreachable,
1496 }
1255 if (loaded_union.layout == .auto) try w.writeByte('{');
1256
1257 if (loaded_union.has_runtime_tag) {
1258 try w.writeAll(" .tag = ");
1259 try dg.renderValue(w, .fromInterned(un.tag), initializer_type);
1260 try w.writeAll(", .payload = ");
1261 }
1262
1263 const enum_tag_ty: Type = .fromInterned(loaded_union.enum_tag_type);
1264 const active_field_index = enum_tag_ty.enumTagFieldIndex(.fromInterned(un.tag), zcu).?;
1265 const active_field_ty: Type = .fromInterned(loaded_union.field_types.get(ip)[active_field_index]);
1266 if (active_field_ty.hasRuntimeBits(zcu)) {
1267 const active_field_name = enum_tag_ty.enumFieldName(active_field_index, zcu);
1268 try w.print("{{ .{f} = ", .{fmtIdentSolo(active_field_name.toSlice(ip))});
1269 try dg.renderValue(w, .fromInterned(un.val), initializer_type);
1270 try w.writeAll(" }");
1271 } else {
1272 const first_field_ty: Type = for (loaded_union.field_types.get(ip)) |field_ty_ip| {
1273 const field_ty: Type = .fromInterned(field_ty_ip);
1274 if (!field_ty.hasRuntimeBits(pt.zcu)) continue;
1275 break field_ty;
1276 } else unreachable;
1277 try w.writeByte('{');
1278 try dg.renderUndefValue(w, first_field_ty, initializer_type);
1279 try w.writeByte('}');
14971280 }
1498 if (has_tag) try w.writeByte('}');
1281
1282 if (loaded_union.has_runtime_tag) try w.writeByte(' ');
1283 if (loaded_union.layout == .auto) try w.writeByte('}');
14991284 }
15001285 },
15011286 }
......@@ -1511,11 +1296,10 @@ pub const DeclGen = struct {
15111296 const zcu = pt.zcu;
15121297 const ip = &zcu.intern_pool;
15131298 const target = &dg.mod.resolved_target.result;
1514 const ctype_pool = &dg.ctype_pool;
15151299
15161300 const initializer_type: ValueRenderLocation = switch (location) {
1517 .StaticInitializer => .StaticInitializer,
1518 else => .Initializer,
1301 .static_initializer => .static_initializer,
1302 else => .initializer,
15191303 };
15201304
15211305 const safety_on = switch (zcu.optimizeMode()) {
......@@ -1523,7 +1307,6 @@ pub const DeclGen = struct {
15231307 .ReleaseFast, .ReleaseSmall => false,
15241308 };
15251309
1526 const ctype = try dg.ctypeFromType(ty, location.toCTypeKind());
15271310 switch (ty.toIntern()) {
15281311 .c_longdouble_type,
15291312 .f16_type,
......@@ -1548,76 +1331,109 @@ pub const DeclGen = struct {
15481331 else => unreachable,
15491332 }
15501333 try w.writeAll(", ");
1551 try dg.renderUndefValue(w, repr_ty, .FunctionArgument);
1334 try dg.renderUndefValue(w, repr_ty, .other);
15521335 return w.writeByte(')');
15531336 },
15541337 .bool_type => try w.writeAll(if (safety_on) "0xaa" else "false"),
15551338 else => switch (ip.indexToKey(ty.toIntern())) {
1556 .simple_type,
1339 .simple_type, // anyerror, c_char (etc), usize, isize
15571340 .int_type,
15581341 .enum_type,
15591342 .error_set_type,
15601343 .inferred_error_set_type,
1561 => return w.print("{f}", .{
1562 try dg.fmtIntLiteralHex(try pt.undefValue(ty), location),
1563 }),
1344 => switch (CType.classifyInt(ty, zcu)) {
1345 .void => unreachable, // opv
1346 .small => |s| {
1347 const int = ty.intInfo(zcu);
1348 var buf: [std.math.big.int.calcTwosCompLimbCount(128)]std.math.big.Limb = undefined;
1349 var bigint: std.math.big.int.Mutable = .init(&buf, undefPattern(u128));
1350 bigint.truncate(bigint.toConst(), int.signedness, int.bits);
1351 const fmt_undef: FormatInt128 = .{
1352 .target = zcu.getTarget(),
1353 .int_cty = s,
1354 .val = bigint.toConst(),
1355 .is_global = location == .static_initializer,
1356 .base = 16,
1357 .case = .lower,
1358 };
1359 try w.print("{f}", .{fmt_undef});
1360 },
1361 .big => |big| {
1362 var buf: [std.math.big.int.calcTwosCompLimbCount(128)]std.math.big.Limb = undefined;
1363 var limb_bigint: std.math.big.int.Mutable = .init(&buf, undefPattern(u128));
1364 limb_bigint.truncate(limb_bigint.toConst(), .unsigned, big.limb_size.bits());
1365 const fmt_undef_limb: FormatInt128 = .{
1366 .target = zcu.getTarget(),
1367 .int_cty = big.limb_size.unsigned(),
1368 .val = limb_bigint.toConst(),
1369 .is_global = location == .static_initializer,
1370 .base = 16,
1371 .case = .lower,
1372 };
1373
1374 if (!location.isInitializer()) {
1375 try w.writeByte('(');
1376 try dg.renderType(w, ty);
1377 try w.writeByte(')');
1378 }
1379 try w.writeAll("{{");
1380 try w.print("{f}", .{fmt_undef_limb});
1381 for (1..big.limbs_len) |_| {
1382 try w.print(",{f}", .{fmt_undef_limb});
1383 }
1384 try w.writeAll("}}");
1385 },
1386 },
15641387 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
15651388 .one, .many, .c => {
15661389 try w.writeAll("((");
1567 try dg.renderCType(w, ctype);
1568 return w.print("){f})", .{
1569 try dg.fmtIntLiteralHex(.undef_usize, .Other),
1570 });
1390 try dg.renderType(w, ty);
1391 try w.writeByte(')');
1392 try dg.renderUndefValue(w, .usize, location);
1393 try w.writeByte(')');
15711394 },
15721395 .slice => {
15731396 if (!location.isInitializer()) {
15741397 try w.writeByte('(');
1575 try dg.renderCType(w, ctype);
1398 try dg.renderType(w, ty);
15761399 try w.writeByte(')');
15771400 }
15781401
1579 try w.writeAll("{(");
1580 const ptr_ty = ty.slicePtrFieldType(zcu);
1581 try dg.renderType(w, ptr_ty);
1582 return w.print("){f}, {0f}}}", .{
1583 try dg.fmtIntLiteralHex(.undef_usize, .Other),
1584 });
1402 try w.writeByte('{');
1403 try dg.renderUndefValue(w, ty.slicePtrFieldType(zcu), initializer_type);
1404 try w.writeByte(',');
1405 try dg.renderUndefValue(w, .usize, initializer_type);
1406 try w.writeByte('}');
15851407 },
15861408 },
1587 .opt_type => |child_type| switch (ctype.info(ctype_pool)) {
1588 .basic, .pointer => try dg.renderUndefValue(
1589 w,
1590 .fromInterned(if (ctype.isBool()) .bool_type else child_type),
1591 location,
1592 ),
1593 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
1594 .aggregate => |aggregate| {
1595 switch (aggregate.fields.at(0, ctype_pool).name.index) {
1596 .is_null, .payload => {},
1597 .ptr, .len => return dg.renderUndefValue(
1598 w,
1599 .fromInterned(child_type),
1600 location,
1601 ),
1602 else => unreachable,
1603 }
1409 .opt_type => |child_type| switch (CType.classifyOptional(ty, zcu)) {
1410 .npv_payload => unreachable, // opv optional
1411
1412 .error_set,
1413 .ptr_like,
1414 .slice_like,
1415 => try dg.renderUndefValue(w, .fromInterned(child_type), location),
1416
1417 .opv_payload => {
16041418 if (!location.isInitializer()) {
16051419 try w.writeByte('(');
1606 try dg.renderCType(w, ctype);
1420 try dg.renderType(w, ty);
16071421 try w.writeByte(')');
16081422 }
1609 try w.writeByte('{');
1610 for (0..aggregate.fields.len) |field_index| {
1611 if (field_index > 0) try w.writeByte(',');
1612 try dg.renderUndefValue(w, .fromInterned(
1613 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
1614 .is_null => .bool_type,
1615 .payload => child_type,
1616 else => unreachable,
1617 },
1618 ), initializer_type);
1423 try w.writeAll(if (safety_on) "{.is_null=0xaa}" else "{.is_null=false}");
1424 },
1425
1426 .@"struct" => {
1427 if (!location.isInitializer()) {
1428 try w.writeByte('(');
1429 try dg.renderType(w, ty);
1430 try w.writeByte(')');
16191431 }
1620 try w.writeByte('}');
1432 try w.writeAll("{ .is_null = ");
1433 try dg.renderUndefValue(w, .bool, initializer_type);
1434 try w.writeAll(", .payload = ");
1435 try dg.renderUndefValue(w, .fromInterned(child_type), initializer_type);
1436 try w.writeAll(" }");
16211437 },
16221438 },
16231439 .struct_type => {
......@@ -1626,16 +1442,15 @@ pub const DeclGen = struct {
16261442 .auto, .@"extern" => {
16271443 if (!location.isInitializer()) {
16281444 try w.writeByte('(');
1629 try dg.renderCType(w, ctype);
1445 try dg.renderType(w, ty);
16301446 try w.writeByte(')');
16311447 }
1632
16331448 try w.writeByte('{');
16341449 var field_it = loaded_struct.iterateRuntimeOrder(ip);
16351450 var need_comma = false;
16361451 while (field_it.next()) |field_index| {
16371452 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
1638 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
1453 if (!field_ty.hasRuntimeBits(zcu)) continue;
16391454
16401455 if (need_comma) try w.writeByte(',');
16411456 need_comma = true;
......@@ -1643,17 +1458,13 @@ pub const DeclGen = struct {
16431458 }
16441459 return w.writeByte('}');
16451460 },
1646 .@"packed" => return dg.renderUndefValue(
1647 w,
1648 .fromInterned(loaded_struct.backingIntTypeUnordered(ip)),
1649 location,
1650 ),
1461 .@"packed" => return dg.renderUndefValue(w, ty.bitpackBackingInt(zcu), location),
16511462 }
16521463 },
16531464 .tuple_type => |tuple_info| {
16541465 if (!location.isInitializer()) {
16551466 try w.writeByte('(');
1656 try dg.renderCType(w, ctype);
1467 try dg.renderType(w, ty);
16571468 try w.writeByte(')');
16581469 }
16591470
......@@ -1662,7 +1473,7 @@ pub const DeclGen = struct {
16621473 for (0..tuple_info.types.len) |field_index| {
16631474 if (tuple_info.values.get(ip)[field_index] != .none) continue;
16641475 const field_ty: Type = .fromInterned(tuple_info.types.get(ip)[field_index]);
1665 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
1476 if (!field_ty.hasRuntimeBits(zcu)) continue;
16661477
16671478 if (need_comma) try w.writeByte(',');
16681479 need_comma = true;
......@@ -1672,88 +1483,65 @@ pub const DeclGen = struct {
16721483 },
16731484 .union_type => {
16741485 const loaded_union = ip.loadUnionType(ty.toIntern());
1675 switch (loaded_union.flagsUnordered(ip).layout) {
1486 switch (loaded_union.layout) {
16761487 .auto, .@"extern" => {
16771488 if (!location.isInitializer()) {
16781489 try w.writeByte('(');
1679 try dg.renderCType(w, ctype);
1490 try dg.renderType(w, ty);
16801491 try w.writeByte(')');
16811492 }
16821493
1683 const has_tag = loaded_union.hasTag(ip);
1684 if (has_tag) try w.writeByte('{');
1685 const aggregate = ctype.info(ctype_pool).aggregate;
1686 for (0..if (has_tag) aggregate.fields.len else 1) |outer_field_index| {
1687 if (outer_field_index > 0) try w.writeByte(',');
1688 switch (if (has_tag)
1689 aggregate.fields.at(outer_field_index, ctype_pool).name.index
1690 else
1691 .payload) {
1692 .tag => try dg.renderUndefValue(
1693 w,
1694 .fromInterned(loaded_union.enum_tag_ty),
1695 initializer_type,
1696 ),
1697 .payload => {
1698 try w.writeByte('{');
1699 for (0..loaded_union.field_types.len) |inner_field_index| {
1700 const inner_field_ty: Type = .fromInterned(
1701 loaded_union.field_types.get(ip)[inner_field_index],
1702 );
1703 if (!inner_field_ty.hasRuntimeBits(pt.zcu)) continue;
1704 try dg.renderUndefValue(
1705 w,
1706 inner_field_ty,
1707 initializer_type,
1708 );
1709 break;
1710 }
1711 try w.writeByte('}');
1712 },
1713 else => unreachable,
1714 }
1494 const first_field_ty: Type = for (loaded_union.field_types.get(ip)) |field_ty_ip| {
1495 const field_ty: Type = .fromInterned(field_ty_ip);
1496 if (!field_ty.hasRuntimeBits(pt.zcu)) continue;
1497 break field_ty;
1498 } else {
1499 assert(loaded_union.has_runtime_tag); // otherwise it does not have runtime bits
1500 try w.writeAll("{ .tag = ");
1501 try dg.renderUndefValue(w, .fromInterned(loaded_union.enum_tag_type), initializer_type);
1502 try w.writeAll(" }");
1503 return;
1504 };
1505
1506 if (loaded_union.layout == .auto) try w.writeByte('{');
1507
1508 if (loaded_union.has_runtime_tag) {
1509 try w.writeAll(" .tag = ");
1510 try dg.renderUndefValue(w, .fromInterned(loaded_union.enum_tag_type), initializer_type);
1511 try w.writeAll(", .payload = ");
17151512 }
1716 if (has_tag) try w.writeByte('}');
1513
1514 try w.writeByte('{');
1515 try dg.renderUndefValue(w, first_field_ty, initializer_type);
1516 try w.writeByte('}');
1517
1518 if (loaded_union.has_runtime_tag) try w.writeByte(' ');
1519 if (loaded_union.layout == .auto) try w.writeByte('}');
17171520 },
1718 .@"packed" => return dg.renderUndefValue(
1719 w,
1720 try ty.unionBackingType(pt),
1721 location,
1722 ),
1521 .@"packed" => return dg.renderUndefValue(w, ty.bitpackBackingInt(zcu), location),
17231522 }
17241523 },
1725 .error_union_type => |error_union_type| switch (ctype.info(ctype_pool)) {
1726 .basic => try dg.renderUndefValue(
1727 w,
1728 .fromInterned(error_union_type.error_set_type),
1729 location,
1730 ),
1731 .pointer, .aligned, .array, .vector, .fwd_decl, .function => unreachable,
1732 .aggregate => |aggregate| {
1733 if (!location.isInitializer()) {
1734 try w.writeByte('(');
1735 try dg.renderCType(w, ctype);
1736 try w.writeByte(')');
1737 }
1738 try w.writeByte('{');
1739 for (0..aggregate.fields.len) |field_index| {
1740 if (field_index > 0) try w.writeByte(',');
1741 try dg.renderUndefValue(
1742 w,
1743 .fromInterned(
1744 switch (aggregate.fields.at(field_index, ctype_pool).name.index) {
1745 .@"error" => error_union_type.error_set_type,
1746 .payload => error_union_type.payload_type,
1747 else => unreachable,
1748 },
1749 ),
1750 initializer_type,
1751 );
1752 }
1753 try w.writeByte('}');
1754 },
1524 .error_union_type => |error_union| {
1525 if (!location.isInitializer()) {
1526 try w.writeByte('(');
1527 try dg.renderType(w, ty);
1528 try w.writeByte(')');
1529 }
1530 try w.writeAll("{ .error = ");
1531 try dg.renderUndefValue(w, .fromInterned(error_union.error_set_type), initializer_type);
1532 if (Type.fromInterned(error_union.payload_type).hasRuntimeBits(zcu)) {
1533 try w.writeAll(", .payload = ");
1534 try dg.renderUndefValue(w, .fromInterned(error_union.payload_type), initializer_type);
1535 }
1536 try w.writeAll(" }");
17551537 },
17561538 .array_type, .vector_type => {
1539 if (!location.isInitializer()) {
1540 try w.writeByte('(');
1541 try dg.renderType(w, ty);
1542 try w.writeByte(')');
1543 }
1544 try w.writeByte('{');
17571545 const ai = ty.arrayInfo(zcu);
17581546 if (ai.elem_type.eql(.u8, zcu)) {
17591547 var literal: StringLiteral = .init(w, @intCast(ty.arrayLenIncludingSentinel(zcu)));
......@@ -1764,14 +1552,8 @@ pub const DeclGen = struct {
17641552 const s_u8: u8 = @intCast(s.toUnsignedInt(zcu));
17651553 if (s_u8 != 0) try literal.writeChar(s_u8);
17661554 }
1767 return literal.end();
1555 try literal.end();
17681556 } else {
1769 if (!location.isInitializer()) {
1770 try w.writeByte('(');
1771 try dg.renderCType(w, ctype);
1772 try w.writeByte(')');
1773 }
1774
17751557 try w.writeByte('{');
17761558 var index: u64 = 0;
17771559 while (index < ai.len) : (index += 1) {
......@@ -1782,8 +1564,9 @@ pub const DeclGen = struct {
17821564 if (index > 0) try w.writeAll(", ");
17831565 try dg.renderValue(w, s, location);
17841566 }
1785 return w.writeByte('}');
1567 try w.writeByte('}');
17861568 }
1569 try w.writeByte('}');
17871570 },
17881571 .anyframe_type,
17891572 .opaque_type,
......@@ -1800,13 +1583,13 @@ pub const DeclGen = struct {
18001583 .error_union,
18011584 .enum_literal,
18021585 .enum_tag,
1803 .empty_enum_value,
18041586 .float,
18051587 .ptr,
18061588 .slice,
18071589 .opt,
18081590 .aggregate,
18091591 .un,
1592 .bitpack,
18101593 .memoized_call,
18111594 => unreachable, // values, not types
18121595 },
......@@ -1818,10 +1601,11 @@ pub const DeclGen = struct {
18181601 w: *Writer,
18191602 fn_val: Value,
18201603 fn_align: InternPool.Alignment,
1821 kind: CType.Kind,
1604 kind: enum { forward_decl, definition },
18221605 name: union(enum) {
18231606 nav: InternPool.Nav.Index,
1824 fmt_ctype_pool_string: std.fmt.Alt(CTypePoolStringFormatData, formatCTypePoolString),
1607 nav_never_tail: InternPool.Nav.Index,
1608 nav_never_inline: InternPool.Nav.Index,
18251609 @"export": struct {
18261610 main_name: InternPool.NullTerminatedString,
18271611 extern_name: InternPool.NullTerminatedString,
......@@ -1832,14 +1616,12 @@ pub const DeclGen = struct {
18321616 const ip = &zcu.intern_pool;
18331617
18341618 const fn_ty = fn_val.typeOf(zcu);
1835 const fn_ctype = try dg.ctypeFromType(fn_ty, kind);
18361619
18371620 const fn_info = zcu.typeToFunc(fn_ty).?;
18381621 if (fn_info.cc == .naked) {
18391622 switch (kind) {
1840 .forward => try w.writeAll("zig_naked_decl "),
1841 .complete => try w.writeAll("zig_naked "),
1842 else => unreachable,
1623 .forward_decl => try w.writeAll("zig_naked_decl "),
1624 .definition => try w.writeAll("zig_naked "),
18431625 }
18441626 }
18451627
......@@ -1849,45 +1631,63 @@ pub const DeclGen = struct {
18491631 if (func_analysis.branch_hint == .cold)
18501632 try w.writeAll("zig_cold ");
18511633
1852 if (kind == .complete and func_analysis.disable_intrinsics or dg.mod.no_builtin)
1634 if (kind == .definition and func_analysis.disable_intrinsics or dg.mod.no_builtin)
18531635 try w.writeAll("zig_no_builtin ");
18541636 }
18551637
18561638 if (fn_info.return_type == .noreturn_type) try w.writeAll("zig_noreturn ");
18571639
1858 var trailing = try renderTypePrefix(dg.pass, &dg.ctype_pool, zcu, w, fn_ctype, .suffix, .{});
1640 // While incomplete types are usually an acceptable substitute for "void", this is not true
1641 // in function return types, where "void" is the only incomplete type permitted.
1642 const actual_return_type: Type = .fromInterned(fn_info.return_type);
1643 const effective_return_type: Type = switch (actual_return_type.classify(zcu)) {
1644 .no_possible_value => .noreturn,
1645 .one_possible_value, .fully_comptime => .void, // no runtime bits
1646 .partially_comptime, .runtime => actual_return_type, // yes runtime bits
1647 };
18591648
1649 const ret_cty: CType = try .lower(effective_return_type, &dg.ctype_deps, dg.arena, zcu);
1650 try w.print("{f}", .{ret_cty.fmtDeclaratorPrefix(zcu)});
18601651 if (toCallingConvention(fn_info.cc, zcu)) |call_conv| {
1861 try w.print("{f}zig_callconv({s})", .{ trailing, call_conv });
1862 trailing = .maybe_space;
1652 try w.print("zig_callconv({s}) ", .{call_conv});
18631653 }
1864
1865 try w.print("{f}", .{trailing});
18661654 switch (name) {
1867 .nav => |nav| try dg.renderNavName(w, nav),
1868 .fmt_ctype_pool_string => |fmt| try w.print("{f}", .{fmt}),
1655 .nav => |nav| try renderNavName(w, nav, ip),
1656 .nav_never_tail => |nav| try w.print("zig_never_tail_{f}__{d}", .{
1657 fmtIdentUnsolo(ip.getNav(nav).name.toSlice(ip)), @intFromEnum(nav),
1658 }),
1659 .nav_never_inline => |nav| try w.print("zig_never_inline_{f}__{d}", .{
1660 fmtIdentUnsolo(ip.getNav(nav).name.toSlice(ip)), @intFromEnum(nav),
1661 }),
18691662 .@"export" => |@"export"| try w.print("{f}", .{fmtIdentSolo(@"export".extern_name.toSlice(ip))}),
18701663 }
1871
1872 try renderTypeSuffix(
1873 dg.pass,
1874 &dg.ctype_pool,
1875 zcu,
1876 w,
1877 fn_ctype,
1878 .suffix,
1879 CQualifiers.init(.{ .@"const" = switch (kind) {
1880 .forward => false,
1881 .complete => true,
1882 else => unreachable,
1883 } }),
1884 );
1664 {
1665 try w.writeByte('(');
1666 var c_param_index: u32 = 0;
1667 for (fn_info.param_types.get(ip)) |param_ty_ip| {
1668 const param_ty: Type = .fromInterned(param_ty_ip);
1669 if (!param_ty.hasRuntimeBits(zcu)) continue;
1670 if (c_param_index != 0) try w.writeAll(", ");
1671 try dg.renderTypeAndName(w, param_ty, .{ .arg = c_param_index }, .{
1672 .@"const" = kind == .definition,
1673 }, .none);
1674 c_param_index += 1;
1675 }
1676 if (fn_info.is_var_args) {
1677 if (c_param_index != 0) try w.writeAll(", ");
1678 try w.writeAll("...");
1679 } else if (c_param_index == 0) {
1680 try w.writeAll("void");
1681 }
1682 try w.writeByte(')');
1683 }
1684 try w.print("{f}", .{ret_cty.fmtDeclaratorSuffixIgnoreNonstring(zcu)});
18851685
18861686 switch (kind) {
1887 .forward => {
1687 .forward_decl => {
18881688 if (fn_align.toByteUnits()) |a| try w.print(" zig_align_fn({})", .{a});
18891689 switch (name) {
1890 .nav, .fmt_ctype_pool_string => {},
1690 .nav, .nav_never_tail, .nav_never_inline => {},
18911691 .@"export" => |@"export"| {
18921692 const extern_name = @"export".extern_name.toSlice(ip);
18931693 const is_mangled = isMangledIdent(extern_name, true);
......@@ -1911,38 +1711,16 @@ pub const DeclGen = struct {
19111711 },
19121712 }
19131713 },
1914 .complete => {},
1915 else => unreachable,
1714 .definition => {},
19161715 }
19171716 }
19181717
1919 fn ctypeFromType(dg: *DeclGen, ty: Type, kind: CType.Kind) !CType {
1920 defer std.debug.assert(dg.scratch.items.len == 0);
1921 return dg.ctype_pool.fromType(dg.gpa, &dg.scratch, ty, dg.pt, dg.mod, kind);
1922 }
1923
1924 fn byteSize(dg: *DeclGen, ctype: CType) u64 {
1925 return ctype.byteSize(&dg.ctype_pool, dg.mod);
1926 }
1927
1928 /// Renders a type as a single identifier, generating intermediate typedefs
1929 /// if necessary.
1930 ///
1931 /// This is guaranteed to be valid in both typedefs and declarations/definitions.
1932 ///
1933 /// There are three type formats in total that we support rendering:
1934 /// | Function | Example 1 (*u8) | Example 2 ([10]*u8) |
1935 /// |---------------------|-----------------|---------------------|
1936 /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" |
1937 /// | `renderType` | "uint8_t *" | "uint8_t *[10]" |
1938 ///
1939 fn renderType(dg: *DeclGen, w: *Writer, t: Type) Error!void {
1940 try dg.renderCType(w, try dg.ctypeFromType(t, .complete));
1941 }
1942
1943 fn renderCType(dg: *DeclGen, w: *Writer, ctype: CType) Error!void {
1944 _ = try renderTypePrefix(dg.pass, &dg.ctype_pool, dg.pt.zcu, w, ctype, .suffix, .{});
1945 try renderTypeSuffix(dg.pass, &dg.ctype_pool, dg.pt.zcu, w, ctype, .suffix, .{});
1718 /// Renders the C lowering of the given Zig type to `w`. This renders the type name---to render
1719 /// a declarator with this type, see instead `renderTypeAndName`.
1720 fn renderType(dg: *DeclGen, w: *Writer, ty: Type) (Writer.Error || Allocator.Error)!void {
1721 const zcu = dg.pt.zcu;
1722 const cty: CType = try .lower(ty, &dg.ctype_deps, dg.arena, zcu);
1723 try w.print("{f}", .{cty.fmtTypeName(zcu)});
19461724 }
19471725
19481726 const IntCastContext = union(enum) {
......@@ -2046,7 +1824,7 @@ pub const DeclGen = struct {
20461824 try w.writeAll("zig_lo_");
20471825 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
20481826 try w.writeByte('(');
2049 try context.writeValue(dg, w, .FunctionArgument);
1827 try context.writeValue(dg, w, .other);
20501828 try w.writeByte(')');
20511829 } else if (dest_bits > 64 and src_bits <= 64) {
20521830 try w.writeAll("zig_make_");
......@@ -2057,7 +1835,7 @@ pub const DeclGen = struct {
20571835 try dg.renderType(w, src_eff_ty);
20581836 try w.writeByte(')');
20591837 }
2060 try context.writeValue(dg, w, .FunctionArgument);
1838 try context.writeValue(dg, w, .other);
20611839 try w.writeByte(')');
20621840 } else {
20631841 assert(!src_is_ptr);
......@@ -2066,23 +1844,16 @@ pub const DeclGen = struct {
20661844 try w.writeAll("(zig_hi_");
20671845 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
20681846 try w.writeByte('(');
2069 try context.writeValue(dg, w, .FunctionArgument);
1847 try context.writeValue(dg, w, .other);
20701848 try w.writeAll("), zig_lo_");
20711849 try dg.renderTypeForBuiltinFnName(w, src_eff_ty);
20721850 try w.writeByte('(');
2073 try context.writeValue(dg, w, .FunctionArgument);
1851 try context.writeValue(dg, w, .other);
20741852 try w.writeAll("))");
20751853 }
20761854 }
20771855
2078 /// Renders a type and name in field declaration/definition format.
2079 ///
2080 /// There are three type formats in total that we support rendering:
2081 /// | Function | Example 1 (*u8) | Example 2 ([10]*u8) |
2082 /// |---------------------|-----------------|---------------------|
2083 /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" |
2084 /// | `renderType` | "uint8_t *" | "uint8_t *[10]" |
2085 ///
1856 /// Renders to `w` a C declarator whose type is the C lowering of the given Zig type.
20861857 fn renderTypeAndName(
20871858 dg: *DeclGen,
20881859 w: *Writer,
......@@ -2090,73 +1861,47 @@ pub const DeclGen = struct {
20901861 name: CValue,
20911862 qualifiers: CQualifiers,
20921863 alignment: Alignment,
2093 kind: CType.Kind,
2094 ) !void {
2095 try dg.renderCTypeAndName(
2096 w,
2097 try dg.ctypeFromType(ty, kind),
2098 name,
2099 qualifiers,
2100 CType.AlignAs.fromAlignment(.{
2101 .@"align" = alignment,
2102 .abi = ty.abiAlignment(dg.pt.zcu),
2103 }),
2104 );
2105 }
2106
2107 fn renderCTypeAndName(
2108 dg: *DeclGen,
2109 w: *Writer,
2110 ctype: CType,
2111 name: CValue,
2112 qualifiers: CQualifiers,
2113 alignas: CType.AlignAs,
21141864 ) !void {
21151865 const zcu = dg.pt.zcu;
2116 switch (alignas.abiOrder()) {
2117 .lt => try w.print("zig_under_align({}) ", .{alignas.toByteUnits()}),
1866 const ip = &zcu.intern_pool;
1867 const cty: CType = try .lower(ty, &dg.ctype_deps, dg.arena, zcu);
1868 try w.print("{f}", .{cty.fmtDeclaratorPrefix(zcu)});
1869 if (alignment != .none) switch (alignment.order(ty.abiAlignment(zcu))) {
1870 .lt => try w.print("zig_under_align({d}) ", .{alignment.toByteUnits().?}),
21181871 .eq => {},
2119 .gt => try w.print("zig_align({}) ", .{alignas.toByteUnits()}),
2120 }
2121
2122 try w.print("{f}", .{
2123 try renderTypePrefix(dg.pass, &dg.ctype_pool, zcu, w, ctype, .suffix, qualifiers),
2124 });
2125 try dg.writeName(w, name);
2126 try renderTypeSuffix(dg.pass, &dg.ctype_pool, zcu, w, ctype, .suffix, .{});
2127 if (ctype.isNonString(&dg.ctype_pool)) try w.writeAll(" zig_nonstring");
2128 }
2129
2130 fn writeName(dg: *DeclGen, w: *Writer, c_value: CValue) !void {
2131 switch (c_value) {
1872 .gt => try w.print("zig_align({d}) ", .{alignment.toByteUnits().?}),
1873 };
1874 if (qualifiers.@"const") try w.writeAll("const ");
1875 if (qualifiers.@"volatile") try w.writeAll("volatile ");
1876 if (qualifiers.restrict) try w.writeAll("restrict ");
1877 switch (name) {
21321878 .new_local, .local => |i| try w.print("t{d}", .{i}),
1879 .arg => |i| try w.print("a{d}", .{i}),
21331880 .constant => |uav| try renderUavName(w, uav),
2134 .nav => |nav| try dg.renderNavName(w, nav),
1881 .nav => |nav| try renderNavName(w, nav, ip),
21351882 .identifier => |ident| try w.print("{f}", .{fmtIdentSolo(ident)}),
21361883 else => unreachable,
21371884 }
1885 try w.print("{f}", .{cty.fmtDeclaratorSuffix(zcu)});
21381886 }
21391887
21401888 fn writeCValue(dg: *DeclGen, w: *Writer, c_value: CValue) Error!void {
21411889 switch (c_value) {
21421890 .none, .new_local, .local, .local_ref => unreachable,
21431891 .constant => |uav| try renderUavName(w, uav),
2144 .arg, .arg_array => unreachable,
1892 .arg => unreachable,
21451893 .field => |i| try w.print("f{d}", .{i}),
2146 .nav => |nav| try dg.renderNavName(w, nav),
1894 .nav => |nav| try renderNavName(w, nav, &dg.pt.zcu.intern_pool),
21471895 .nav_ref => |nav| {
21481896 try w.writeByte('&');
2149 try dg.renderNavName(w, nav);
1897 try renderNavName(w, nav, &dg.pt.zcu.intern_pool);
21501898 },
2151 .undef => |ty| try dg.renderUndefValue(w, ty, .Other),
1899 .undef => |ty| try dg.renderUndefValue(w, ty, .other),
21521900 .identifier => |ident| try w.print("{f}", .{fmtIdentSolo(ident)}),
21531901 .payload_identifier => |ident| try w.print("{f}.{f}", .{
21541902 fmtIdentSolo("payload"),
21551903 fmtIdentSolo(ident),
21561904 }),
2157 .ctype_pool_string => |string| try w.print("{f}", .{
2158 fmtCTypePoolString(string, &dg.ctype_pool, true),
2159 }),
21601905 }
21611906 }
21621907
......@@ -2168,16 +1913,14 @@ pub const DeclGen = struct {
21681913 .local_ref,
21691914 .constant,
21701915 .arg,
2171 .arg_array,
2172 .ctype_pool_string,
21731916 => unreachable,
21741917 .field => |i| try w.print("f{d}", .{i}),
21751918 .nav => |nav| {
21761919 try w.writeAll("(*");
2177 try dg.renderNavName(w, nav);
1920 try renderNavName(w, nav, &dg.pt.zcu.intern_pool);
21781921 try w.writeByte(')');
21791922 },
2180 .nav_ref => |nav| try dg.renderNavName(w, nav),
1923 .nav_ref => |nav| try renderNavName(w, nav, &dg.pt.zcu.intern_pool),
21811924 .undef => unreachable,
21821925 .identifier => |ident| try w.print("(*{f})", .{fmtIdentSolo(ident)}),
21831926 .payload_identifier => |ident| try w.print("(*{f}.{f})", .{
......@@ -2213,8 +1956,6 @@ pub const DeclGen = struct {
22131956 .field,
22141957 .undef,
22151958 .arg,
2216 .arg_array,
2217 .ctype_pool_string,
22181959 => unreachable,
22191960 .nav, .identifier, .payload_identifier => {
22201961 try dg.writeCValue(w, c_value);
......@@ -2228,101 +1969,36 @@ pub const DeclGen = struct {
22281969 try dg.writeCValue(w, member);
22291970 }
22301971
2231 fn renderFwdDecl(
2232 dg: *DeclGen,
2233 nav_index: InternPool.Nav.Index,
2234 flags: packed struct {
2235 is_const: bool,
2236 is_threadlocal: bool,
2237 linkage: std.builtin.GlobalLinkage,
2238 visibility: std.builtin.SymbolVisibility,
2239 },
2240 ) !void {
1972 fn renderTypeForBuiltinFnName(dg: *DeclGen, w: *Writer, ty: Type) !void {
22411973 const zcu = dg.pt.zcu;
2242 const ip = &zcu.intern_pool;
2243 const nav = ip.getNav(nav_index);
2244 const fwd = &dg.fwd_decl.writer;
2245 try fwd.writeAll(switch (flags.linkage) {
2246 .internal => "static ",
2247 .strong, .weak, .link_once => "zig_extern ",
2248 });
2249 switch (flags.linkage) {
2250 .internal, .strong => {},
2251 .weak => try fwd.writeAll("zig_weak_linkage "),
2252 .link_once => return dg.fail("TODO: CBE: implement linkonce linkage?", .{}),
2253 }
2254 switch (flags.linkage) {
2255 .internal => {},
2256 .strong, .weak, .link_once => try fwd.print("zig_visibility({s}) ", .{@tagName(flags.visibility)}),
1974 switch (ty.zigTypeTag(zcu)) {
1975 .bool => return w.writeAll("u8"),
1976 .float => return w.print("f{d}", .{ty.floatBits(zcu.getTarget())}),
1977 else => {},
22571978 }
2258 if (flags.is_threadlocal and !dg.mod.single_threaded) try fwd.writeAll("zig_threadlocal ");
2259 try dg.renderTypeAndName(
2260 fwd,
2261 .fromInterned(nav.typeOf(ip)),
2262 .{ .nav = nav_index },
2263 CQualifiers.init(.{ .@"const" = flags.is_const }),
2264 nav.getAlignment(),
2265 .complete,
2266 );
2267 try fwd.writeAll(";\n");
2268 }
2269
2270 fn renderNavName(dg: *DeclGen, w: *Writer, nav_index: InternPool.Nav.Index) !void {
2271 const zcu = dg.pt.zcu;
2272 const ip = &zcu.intern_pool;
2273 const nav = ip.getNav(nav_index);
2274 if (nav.getExtern(ip)) |@"extern"| {
2275 try w.print("{f}", .{
2276 fmtIdentSolo(ip.getNav(@"extern".owner_nav).name.toSlice(ip)),
2277 });
2278 } else {
2279 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),
2280 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.
2281 const fqn_slice = ip.getNav(nav_index).fqn.toSlice(ip);
2282 try w.print("{f}__{d}", .{
2283 fmtIdentUnsolo(fqn_slice[0..@min(fqn_slice.len, 100)]),
2284 @intFromEnum(nav_index),
2285 });
1979 if (ty.isPtrAtRuntime(zcu)) {
1980 return w.print("p{d}", .{zcu.getTarget().ptrBitWidth()});
22861981 }
2287 }
2288
2289 fn renderUavName(w: *Writer, uav: Value) !void {
2290 try w.print("__anon_{d}", .{@intFromEnum(uav.toIntern())});
2291 }
2292
2293 fn renderTypeForBuiltinFnName(dg: *DeclGen, w: *Writer, ty: Type) !void {
2294 try dg.renderCTypeForBuiltinFnName(w, try dg.ctypeFromType(ty, .complete));
2295 }
2296
2297 fn renderCTypeForBuiltinFnName(dg: *DeclGen, w: *Writer, ctype: CType) !void {
2298 switch (ctype.info(&dg.ctype_pool)) {
2299 else => |ctype_info| try w.print("{c}{d}", .{
2300 if (ctype.isBool())
2301 signAbbrev(.unsigned)
2302 else if (ctype.isInteger())
2303 signAbbrev(ctype.signedness(dg.mod))
2304 else if (ctype.isFloat())
2305 @as(u8, 'f')
2306 else if (ctype_info == .pointer)
2307 @as(u8, 'p')
2308 else
2309 return dg.fail("TODO: CBE: implement renderTypeForBuiltinFnName for {s} type", .{@tagName(ctype_info)}),
2310 if (ctype.isFloat()) ctype.floatActiveBits(dg.mod) else dg.byteSize(ctype) * 8,
1982 switch (CType.classifyInt(ty, zcu)) {
1983 .void => unreachable, // opv
1984 .small => try w.print("{c}{d}", .{
1985 signAbbrev(ty.intInfo(zcu).signedness),
1986 ty.abiSize(zcu) * 8,
23111987 }),
2312 .array => try w.writeAll("big"),
1988 .big => try w.writeAll("big"),
23131989 }
23141990 }
23151991
23161992 fn renderBuiltinInfo(dg: *DeclGen, w: *Writer, ty: Type, info: BuiltinInfo) !void {
2317 const ctype = try dg.ctypeFromType(ty, .complete);
2318 const is_big = ctype.info(&dg.ctype_pool) == .array;
1993 const pt = dg.pt;
1994 const zcu = pt.zcu;
1995
1996 const is_big = lowersToBigInt(ty, zcu);
23191997 switch (info) {
23201998 .none => if (!is_big) return,
23211999 .bits => {},
23222000 }
23232001
2324 const pt = dg.pt;
2325 const zcu = pt.zcu;
23262002 const int_info: std.builtin.Type.Int = if (ty.isAbiInt(zcu)) ty.intInfo(zcu) else .{
23272003 .signedness = .unsigned,
23282004 .bits = @intCast(ty.bitSize(zcu)),
......@@ -2331,7 +2007,7 @@ pub const DeclGen = struct {
23312007 if (is_big) try w.print(", {}", .{int_info.signedness == .signed});
23322008 try w.print(", {f}", .{try dg.fmtIntLiteralDec(
23332009 try pt.intValue(if (is_big) .u16 else .u8, int_info.bits),
2334 .FunctionArgument,
2010 .other,
23352011 )});
23362012 }
23372013
......@@ -2342,15 +2018,13 @@ pub const DeclGen = struct {
23422018 base: u8,
23432019 case: std.fmt.Case,
23442020 ) !std.fmt.Alt(FormatIntLiteralContext, formatIntLiteral) {
2345 const zcu = dg.pt.zcu;
2346 const kind = loc.toCTypeKind();
2347 const ty = val.typeOf(zcu);
2021 // If there's a bigint type involved, mark a dependency on it.
2022 const cty: CType = try .lower(val.typeOf(dg.pt.zcu), &dg.ctype_deps, dg.arena, dg.pt.zcu);
23482023 return .{ .data = .{
23492024 .dg = dg,
2350 .int_info = ty.intInfo(zcu),
2351 .kind = kind,
2352 .ctype = try dg.ctypeFromType(ty, kind),
2025 .loc = loc,
23532026 .val = val,
2027 .cty = cty,
23542028 .base = base,
23552029 .case = case,
23562030 } };
......@@ -2373,339 +2047,11 @@ pub const DeclGen = struct {
23732047 }
23742048};
23752049
2376const CTypeFix = enum { prefix, suffix };
2377const CQualifiers = std.enums.EnumSet(enum { @"const", @"volatile", restrict });
2378const Const = CQualifiers.init(.{ .@"const" = true });
2379const RenderCTypeTrailing = enum {
2380 no_space,
2381 maybe_space,
2382
2383 pub fn format(self: @This(), w: *Writer) Writer.Error!void {
2384 switch (self) {
2385 .no_space => {},
2386 .maybe_space => try w.writeByte(' '),
2387 }
2388 }
2050const CQualifiers = packed struct {
2051 @"const": bool = false,
2052 @"volatile": bool = false,
2053 restrict: bool = false,
23892054};
2390fn renderAlignedTypeName(w: *Writer, ctype: CType) !void {
2391 try w.print("anon__aligned_{d}", .{@intFromEnum(ctype.index)});
2392}
2393fn renderFwdDeclTypeName(
2394 zcu: *Zcu,
2395 w: *Writer,
2396 ctype: CType,
2397 fwd_decl: CType.Info.FwdDecl,
2398 attributes: []const u8,
2399) !void {
2400 const ip = &zcu.intern_pool;
2401 try w.print("{s} {s}", .{ @tagName(fwd_decl.tag), attributes });
2402 switch (fwd_decl.name) {
2403 .anon => try w.print("anon__lazy_{d}", .{@intFromEnum(ctype.index)}),
2404 .index => |index| try w.print("{f}__{d}", .{
2405 fmtIdentUnsolo(Type.fromInterned(index).containerTypeName(ip).toSlice(&zcu.intern_pool)),
2406 @intFromEnum(index),
2407 }),
2408 }
2409}
2410fn renderTypePrefix(
2411 pass: DeclGen.Pass,
2412 ctype_pool: *const CType.Pool,
2413 zcu: *Zcu,
2414 w: *Writer,
2415 ctype: CType,
2416 parent_fix: CTypeFix,
2417 qualifiers: CQualifiers,
2418) Writer.Error!RenderCTypeTrailing {
2419 var trailing = RenderCTypeTrailing.maybe_space;
2420 switch (ctype.info(ctype_pool)) {
2421 .basic => |basic_info| try w.writeAll(@tagName(basic_info)),
2422
2423 .pointer => |pointer_info| {
2424 try w.print("{f}*", .{try renderTypePrefix(
2425 pass,
2426 ctype_pool,
2427 zcu,
2428 w,
2429 pointer_info.elem_ctype,
2430 .prefix,
2431 CQualifiers.init(.{
2432 .@"const" = pointer_info.@"const",
2433 .@"volatile" = pointer_info.@"volatile",
2434 }),
2435 )});
2436 trailing = .no_space;
2437 },
2438
2439 .aligned => switch (pass) {
2440 .nav => |nav| try w.print("nav__{d}_{d}", .{
2441 @intFromEnum(nav), @intFromEnum(ctype.index),
2442 }),
2443 .uav => |uav| try w.print("uav__{d}_{d}", .{
2444 @intFromEnum(uav), @intFromEnum(ctype.index),
2445 }),
2446 .flush => try renderAlignedTypeName(w, ctype),
2447 },
2448
2449 .array, .vector => |sequence_info| {
2450 const child_trailing = try renderTypePrefix(
2451 pass,
2452 ctype_pool,
2453 zcu,
2454 w,
2455 sequence_info.elem_ctype,
2456 .suffix,
2457 qualifiers,
2458 );
2459 switch (parent_fix) {
2460 .prefix => {
2461 try w.print("{f}(", .{child_trailing});
2462 return .no_space;
2463 },
2464 .suffix => return child_trailing,
2465 }
2466 },
2467
2468 .fwd_decl => |fwd_decl_info| switch (fwd_decl_info.name) {
2469 .anon => switch (pass) {
2470 .nav => |nav| try w.print("nav__{d}_{d}", .{
2471 @intFromEnum(nav), @intFromEnum(ctype.index),
2472 }),
2473 .uav => |uav| try w.print("uav__{d}_{d}", .{
2474 @intFromEnum(uav), @intFromEnum(ctype.index),
2475 }),
2476 .flush => try renderFwdDeclTypeName(zcu, w, ctype, fwd_decl_info, ""),
2477 },
2478 .index => try renderFwdDeclTypeName(zcu, w, ctype, fwd_decl_info, ""),
2479 },
2480
2481 .aggregate => |aggregate_info| switch (aggregate_info.name) {
2482 .anon => {
2483 try w.print("{s} {s}", .{
2484 @tagName(aggregate_info.tag),
2485 if (aggregate_info.@"packed") "zig_packed(" else "",
2486 });
2487 try renderFields(zcu, w, ctype_pool, aggregate_info, 1);
2488 if (aggregate_info.@"packed") try w.writeByte(')');
2489 },
2490 .fwd_decl => |fwd_decl| return renderTypePrefix(
2491 pass,
2492 ctype_pool,
2493 zcu,
2494 w,
2495 fwd_decl,
2496 parent_fix,
2497 qualifiers,
2498 ),
2499 },
2500
2501 .function => |function_info| {
2502 const child_trailing = try renderTypePrefix(
2503 pass,
2504 ctype_pool,
2505 zcu,
2506 w,
2507 function_info.return_ctype,
2508 .suffix,
2509 .{},
2510 );
2511 switch (parent_fix) {
2512 .prefix => {
2513 try w.print("{f}(", .{child_trailing});
2514 return .no_space;
2515 },
2516 .suffix => return child_trailing,
2517 }
2518 },
2519 }
2520 var qualifier_it = qualifiers.iterator();
2521 while (qualifier_it.next()) |qualifier| {
2522 try w.print("{f}{s}", .{ trailing, @tagName(qualifier) });
2523 trailing = .maybe_space;
2524 }
2525 return trailing;
2526}
2527fn renderTypeSuffix(
2528 pass: DeclGen.Pass,
2529 ctype_pool: *const CType.Pool,
2530 zcu: *Zcu,
2531 w: *Writer,
2532 ctype: CType,
2533 parent_fix: CTypeFix,
2534 qualifiers: CQualifiers,
2535) Writer.Error!void {
2536 switch (ctype.info(ctype_pool)) {
2537 .basic, .aligned, .fwd_decl, .aggregate => {},
2538 .pointer => |pointer_info| try renderTypeSuffix(
2539 pass,
2540 ctype_pool,
2541 zcu,
2542 w,
2543 pointer_info.elem_ctype,
2544 .prefix,
2545 .{},
2546 ),
2547 .array, .vector => |sequence_info| {
2548 switch (parent_fix) {
2549 .prefix => try w.writeByte(')'),
2550 .suffix => {},
2551 }
2552
2553 try w.print("[{}]", .{sequence_info.len});
2554 try renderTypeSuffix(pass, ctype_pool, zcu, w, sequence_info.elem_ctype, .suffix, .{});
2555 },
2556 .function => |function_info| {
2557 switch (parent_fix) {
2558 .prefix => try w.writeByte(')'),
2559 .suffix => {},
2560 }
2561
2562 try w.writeByte('(');
2563 var need_comma = false;
2564 for (0..function_info.param_ctypes.len) |param_index| {
2565 const param_type = function_info.param_ctypes.at(param_index, ctype_pool);
2566 if (need_comma) try w.writeAll(", ");
2567 need_comma = true;
2568 const trailing =
2569 try renderTypePrefix(pass, ctype_pool, zcu, w, param_type, .suffix, qualifiers);
2570 if (qualifiers.contains(.@"const")) try w.print("{f}a{d}", .{ trailing, param_index });
2571 try renderTypeSuffix(pass, ctype_pool, zcu, w, param_type, .suffix, .{});
2572 }
2573 if (function_info.varargs) {
2574 if (need_comma) try w.writeAll(", ");
2575 need_comma = true;
2576 try w.writeAll("...");
2577 }
2578 if (!need_comma) try w.writeAll("void");
2579 try w.writeByte(')');
2580
2581 try renderTypeSuffix(pass, ctype_pool, zcu, w, function_info.return_ctype, .suffix, .{});
2582 },
2583 }
2584}
2585fn renderFields(
2586 zcu: *Zcu,
2587 w: *Writer,
2588 ctype_pool: *const CType.Pool,
2589 aggregate_info: CType.Info.Aggregate,
2590 indent: usize,
2591) !void {
2592 try w.writeAll("{\n");
2593 for (0..aggregate_info.fields.len) |field_index| {
2594 const field_info = aggregate_info.fields.at(field_index, ctype_pool);
2595 try w.splatByteAll(' ', indent + 1);
2596 switch (field_info.alignas.abiOrder()) {
2597 .lt => {
2598 std.debug.assert(aggregate_info.@"packed");
2599 if (field_info.alignas.@"align" != .@"1") try w.print("zig_under_align({}) ", .{
2600 field_info.alignas.toByteUnits(),
2601 });
2602 },
2603 .eq => if (aggregate_info.@"packed" and field_info.alignas.@"align" != .@"1")
2604 try w.print("zig_align({}) ", .{field_info.alignas.toByteUnits()}),
2605 .gt => {
2606 std.debug.assert(field_info.alignas.@"align" != .@"1");
2607 try w.print("zig_align({}) ", .{field_info.alignas.toByteUnits()});
2608 },
2609 }
2610 const trailing = try renderTypePrefix(
2611 .flush,
2612 ctype_pool,
2613 zcu,
2614 w,
2615 field_info.ctype,
2616 .suffix,
2617 .{},
2618 );
2619 try w.print("{f}{f}", .{ trailing, fmtCTypePoolString(field_info.name, ctype_pool, true) });
2620 try renderTypeSuffix(.flush, ctype_pool, zcu, w, field_info.ctype, .suffix, .{});
2621 if (field_info.ctype.isNonString(ctype_pool)) try w.writeAll(" zig_nonstring");
2622 try w.writeAll(";\n");
2623 }
2624 try w.splatByteAll(' ', indent);
2625 try w.writeByte('}');
2626}
2627
2628pub fn genTypeDecl(
2629 zcu: *Zcu,
2630 w: *Writer,
2631 global_ctype_pool: *const CType.Pool,
2632 global_ctype: CType,
2633 pass: DeclGen.Pass,
2634 decl_ctype_pool: *const CType.Pool,
2635 decl_ctype: CType,
2636 found_existing: bool,
2637) !void {
2638 switch (global_ctype.info(global_ctype_pool)) {
2639 .basic, .pointer, .array, .vector, .function => {},
2640 .aligned => |aligned_info| {
2641 if (!found_existing) {
2642 std.debug.assert(aligned_info.alignas.abiOrder().compare(.lt));
2643 try w.print("typedef zig_under_align({d}) ", .{aligned_info.alignas.toByteUnits()});
2644 try w.print("{f}", .{try renderTypePrefix(
2645 .flush,
2646 global_ctype_pool,
2647 zcu,
2648 w,
2649 aligned_info.ctype,
2650 .suffix,
2651 .{},
2652 )});
2653 try renderAlignedTypeName(w, global_ctype);
2654 try renderTypeSuffix(.flush, global_ctype_pool, zcu, w, aligned_info.ctype, .suffix, .{});
2655 try w.writeAll(";\n");
2656 }
2657 switch (pass) {
2658 .nav, .uav => {
2659 try w.writeAll("typedef ");
2660 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, w, global_ctype, .suffix, .{});
2661 try w.writeByte(' ');
2662 _ = try renderTypePrefix(pass, decl_ctype_pool, zcu, w, decl_ctype, .suffix, .{});
2663 try w.writeAll(";\n");
2664 },
2665 .flush => {},
2666 }
2667 },
2668 .fwd_decl => |fwd_decl_info| switch (fwd_decl_info.name) {
2669 .anon => switch (pass) {
2670 .nav, .uav => {
2671 try w.writeAll("typedef ");
2672 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, w, global_ctype, .suffix, .{});
2673 try w.writeByte(' ');
2674 _ = try renderTypePrefix(pass, decl_ctype_pool, zcu, w, decl_ctype, .suffix, .{});
2675 try w.writeAll(";\n");
2676 },
2677 .flush => {},
2678 },
2679 .index => |index| if (!found_existing) {
2680 const ip = &zcu.intern_pool;
2681 const ty: Type = .fromInterned(index);
2682 _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, w, global_ctype, .suffix, .{});
2683 try w.writeByte(';');
2684 const file_scope = ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip);
2685 if (!zcu.fileByIndex(file_scope).mod.?.strip) try w.print(" /* {f} */", .{
2686 ty.containerTypeName(ip).fmt(ip),
2687 });
2688 try w.writeByte('\n');
2689 },
2690 },
2691 .aggregate => |aggregate_info| switch (aggregate_info.name) {
2692 .anon => {},
2693 .fwd_decl => |fwd_decl| if (!found_existing) {
2694 try renderFwdDeclTypeName(
2695 zcu,
2696 w,
2697 fwd_decl,
2698 fwd_decl.info(global_ctype_pool).fwd_decl,
2699 if (aggregate_info.@"packed") "zig_packed(" else "",
2700 );
2701 try w.writeByte(' ');
2702 try renderFields(zcu, w, global_ctype_pool, aggregate_info, 0);
2703 if (aggregate_info.@"packed") try w.writeByte(')');
2704 try w.writeAll(";\n");
2705 },
2706 },
2707 }
2708}
27092055
27102056pub fn genGlobalAsm(zcu: *Zcu, w: *Writer) !void {
27112057 for (zcu.global_assembly.values()) |asm_source| {
......@@ -2713,200 +2059,128 @@ pub fn genGlobalAsm(zcu: *Zcu, w: *Writer) !void {
27132059 }
27142060}
27152061
2716pub fn genErrDecls(o: *Object) Error!void {
2717 const pt = o.dg.pt;
2718 const zcu = pt.zcu;
2062pub fn genErrDecls(
2063 zcu: *const Zcu,
2064 w: *Writer,
2065 slice_const_u8_sentinel_0_type_name: []const u8,
2066) Writer.Error!void {
27192067 const ip = &zcu.intern_pool;
2720 const w = &o.code.writer;
27212068
2722 var max_name_len: usize = 0;
2723 // do not generate an invalid empty enum when the global error set is empty
27242069 const names = ip.global_error_set.getNamesFromMainThread();
2070 // Don't generate an invalid empty enum if the global error set is empty!
27252071 if (names.len > 0) {
2726 try w.writeAll("enum {");
2727 o.indent();
2728 try o.newline();
2072 try w.writeAll("enum {\n");
27292073 for (names, 1..) |name_nts, value| {
2730 const name = name_nts.toSlice(ip);
2731 max_name_len = @max(name.len, max_name_len);
2732 const err_val = try pt.intern(.{ .err = .{
2733 .ty = .anyerror_type,
2734 .name = name_nts,
2735 } });
2736 try o.dg.renderValue(w, Value.fromInterned(err_val), .Other);
2737 try w.print(" = {d}u,", .{value});
2738 try o.newline();
2074 try w.writeByte(' ');
2075 try renderErrorName(w, name_nts.toSlice(ip));
2076 try w.print(" = {d}u,\n", .{value});
27392077 }
2740 try o.outdent();
2741 try w.writeAll("};");
2742 try o.newline();
2743 }
2744 const array_identifier = "zig_errorName";
2745 const name_prefix = array_identifier ++ "_";
2746 const name_buf = try o.dg.gpa.alloc(u8, name_prefix.len + max_name_len);
2747 defer o.dg.gpa.free(name_buf);
2748
2749 @memcpy(name_buf[0..name_prefix.len], name_prefix);
2750 for (names) |name| {
2751 const name_slice = name.toSlice(ip);
2752 @memcpy(name_buf[name_prefix.len..][0..name_slice.len], name_slice);
2753 const identifier = name_buf[0 .. name_prefix.len + name_slice.len];
2754
2755 const name_ty = try pt.arrayType(.{
2756 .len = name_slice.len,
2757 .child = .u8_type,
2758 .sentinel = .zero_u8,
2759 });
2760 const name_val = try pt.intern(.{ .aggregate = .{
2761 .ty = name_ty.toIntern(),
2762 .storage = .{ .bytes = name.toString() },
2763 } });
2078 try w.writeAll("};\n");
2079 }
27642080
2765 try w.writeAll("static ");
2766 try o.dg.renderTypeAndName(
2767 w,
2768 name_ty,
2769 .{ .identifier = identifier },
2770 Const,
2771 .none,
2772 .complete,
2081 for (names) |name_nts| {
2082 const name = name_nts.toSlice(ip);
2083 try w.print(
2084 "static uint8_t const zig_errorName_{f}[] = {f};\n",
2085 .{ fmtIdentUnsolo(name), fmtStringLiteral(name, 0) },
27732086 );
2774 try w.writeAll(" = ");
2775 try o.dg.renderValue(w, Value.fromInterned(name_val), .StaticInitializer);
2776 try w.writeByte(';');
2777 try o.newline();
27782087 }
27792088
2780 const name_array_ty = try pt.arrayType(.{
2781 .len = 1 + names.len,
2782 .child = .slice_const_u8_sentinel_0_type,
2783 });
2784
2785 try w.writeAll("static ");
2786 try o.dg.renderTypeAndName(
2787 w,
2788 name_array_ty,
2789 .{ .identifier = array_identifier },
2790 Const,
2791 .none,
2792 .complete,
2089 try w.print(
2090 "static {s} const zig_errorName[{d}] = {{",
2091 .{ slice_const_u8_sentinel_0_type_name, names.len },
27932092 );
2794 try w.writeAll(" = {");
2795 for (names, 1..) |name_nts, val| {
2093 if (names.len > 0) try w.writeByte('\n');
2094 for (names) |name_nts| {
27962095 const name = name_nts.toSlice(ip);
2797 if (val > 1) try w.writeAll(", ");
2798 try w.print("{{" ++ name_prefix ++ "{f}, {f}}}", .{
2799 fmtIdentUnsolo(name),
2800 try o.dg.fmtIntLiteralDec(try pt.intValue(.usize, name.len), .StaticInitializer),
2096 try w.print(
2097 " {{zig_errorName_{f},{d}}},\n",
2098 .{ fmtIdentUnsolo(name), name.len },
2099 );
2100 }
2101 try w.writeAll("};\n");
2102}
2103
2104pub fn genTagNameFn(
2105 zcu: *const Zcu,
2106 w: *Writer,
2107 slice_const_u8_sentinel_0_type_name: []const u8,
2108 enum_ty: Type,
2109 enum_type_name: []const u8,
2110) Writer.Error!void {
2111 const ip = &zcu.intern_pool;
2112 const loaded_enum = ip.loadEnumType(enum_ty.toIntern());
2113 assert(loaded_enum.field_names.len > 0);
2114 if (Type.fromInterned(loaded_enum.int_tag_type).bitSize(zcu) > 64) {
2115 @panic("TODO CBE: tagName for enum over 64 bits");
2116 }
2117
2118 try w.print("static {s} zig_tagName_{f}__{d}({s} tag) {{\n", .{
2119 slice_const_u8_sentinel_0_type_name,
2120 fmtIdentUnsolo(loaded_enum.name.toSlice(ip)),
2121 @intFromEnum(enum_ty.toIntern()),
2122 enum_type_name,
2123 });
2124 for (loaded_enum.field_names.get(ip), 0..) |field_name, field_index| {
2125 try w.print(" static uint8_t const name{d}[] = {f};\n", .{
2126 field_index, fmtStringLiteral(field_name.toSlice(ip), 0),
28012127 });
28022128 }
2803 try w.writeAll("};");
2804 try o.newline();
2129
2130 try w.writeAll(" switch (tag) {\n");
2131 const field_values = loaded_enum.field_values.get(ip);
2132 for (loaded_enum.field_names.get(ip), 0..) |field_name, field_index| {
2133 const field_int: i65 = int: {
2134 if (field_values.len == 0) break :int field_index;
2135 const field_val: Value = .fromInterned(field_values[field_index]);
2136 break :int field_val.getUnsignedInt(zcu) orelse field_val.toSignedInt(zcu);
2137 };
2138 try w.print(" case {d}: return ({s}){{name{d},{d}}};\n", .{
2139 field_int,
2140 slice_const_u8_sentinel_0_type_name,
2141 field_index,
2142 field_name.toSlice(ip).len,
2143 });
2144 }
2145 try w.writeAll(
2146 \\ }
2147 \\ zig_unreachable();
2148 \\}
2149 \\
2150 );
28052151}
28062152
2807pub fn genLazyFn(o: *Object, lazy_ctype_pool: *const CType.Pool, lazy_fn: LazyFnMap.Entry) Error!void {
2808 const pt = o.dg.pt;
2809 const zcu = pt.zcu;
2153pub fn genLazyCallModifierFn(
2154 dg: *DeclGen,
2155 fn_nav: InternPool.Nav.Index,
2156 kind: enum { never_tail, never_inline },
2157 w: *Writer,
2158) Error!void {
2159 const zcu = dg.pt.zcu;
28102160 const ip = &zcu.intern_pool;
2811 const ctype_pool = &o.dg.ctype_pool;
2812 const w = &o.code.writer;
2813 const key = lazy_fn.key_ptr.*;
2814 const val = lazy_fn.value_ptr;
2815 switch (key) {
2816 .tag_name => |enum_ty_ip| {
2817 const enum_ty: Type = .fromInterned(enum_ty_ip);
2818 const name_slice_ty: Type = .slice_const_u8_sentinel_0;
2819
2820 try w.writeAll("static ");
2821 try o.dg.renderType(w, name_slice_ty);
2822 try w.print(" {f}(", .{val.fn_name.fmt(lazy_ctype_pool)});
2823 try o.dg.renderTypeAndName(w, enum_ty, .{ .identifier = "tag" }, Const, .none, .complete);
2824 try w.writeAll(") {");
2825 o.indent();
2826 try o.newline();
2827 try w.writeAll("switch (tag) {");
2828 o.indent();
2829 try o.newline();
2830 const tag_names = enum_ty.enumFields(zcu);
2831 for (0..tag_names.len) |tag_index| {
2832 const tag_name = tag_names.get(ip)[tag_index];
2833 const tag_name_len = tag_name.length(ip);
2834 const tag_val = try pt.enumValueFieldIndex(enum_ty, @intCast(tag_index));
2835
2836 const name_ty = try pt.arrayType(.{
2837 .len = tag_name_len,
2838 .child = .u8_type,
2839 .sentinel = .zero_u8,
2840 });
2841 const name_val = try pt.intern(.{ .aggregate = .{
2842 .ty = name_ty.toIntern(),
2843 .storage = .{ .bytes = tag_name.toString() },
2844 } });
28452161
2846 try w.print("case {f}: {{", .{
2847 try o.dg.fmtIntLiteralDec(try tag_val.intFromEnum(enum_ty, pt), .Other),
2848 });
2849 o.indent();
2850 try o.newline();
2851 try w.writeAll("static ");
2852 try o.dg.renderTypeAndName(w, name_ty, .{ .identifier = "name" }, Const, .none, .complete);
2853 try w.writeAll(" = ");
2854 try o.dg.renderValue(w, Value.fromInterned(name_val), .StaticInitializer);
2855 try w.writeByte(';');
2856 try o.newline();
2857 try w.writeAll("return (");
2858 try o.dg.renderType(w, name_slice_ty);
2859 try w.print("){{{f}, {f}}};", .{
2860 fmtIdentUnsolo("name"),
2861 try o.dg.fmtIntLiteralDec(try pt.intValue(.usize, tag_name_len), .Other),
2862 });
2863 try o.newline();
2864 try o.outdent();
2865 try w.writeByte('}');
2866 try o.newline();
2867 }
2868 try o.outdent();
2869 try w.writeByte('}');
2870 try o.newline();
2871 try airUnreach(o);
2872 try o.outdent();
2873 try w.writeByte('}');
2874 try o.newline();
2875 },
2876 .never_tail, .never_inline => |fn_nav_index| {
2877 const fn_val = zcu.navValue(fn_nav_index);
2878 const fn_ctype = try o.dg.ctypeFromType(fn_val.typeOf(zcu), .complete);
2879 const fn_info = fn_ctype.info(ctype_pool).function;
2880 const fn_name = fmtCTypePoolString(val.fn_name, lazy_ctype_pool, true);
2881
2882 const fwd = &o.dg.fwd_decl.writer;
2883 try fwd.print("static zig_{s} ", .{@tagName(key)});
2884 try o.dg.renderFunctionSignature(fwd, fn_val, ip.getNav(fn_nav_index).getAlignment(), .forward, .{
2885 .fmt_ctype_pool_string = fn_name,
2886 });
2887 try fwd.writeAll(";\n");
2162 const fn_val = zcu.navValue(fn_nav);
28882163
2889 try w.print("zig_{s} ", .{@tagName(key)});
2890 try o.dg.renderFunctionSignature(w, fn_val, .none, .complete, .{
2891 .fmt_ctype_pool_string = fn_name,
2892 });
2893 try w.writeAll(" {");
2894 o.indent();
2895 try o.newline();
2896 try w.writeAll("return ");
2897 try o.dg.renderNavName(w, fn_nav_index);
2898 try w.writeByte('(');
2899 for (0..fn_info.param_ctypes.len) |arg| {
2900 if (arg > 0) try w.writeAll(", ");
2901 try w.print("a{d}", .{arg});
2902 }
2903 try w.writeAll(");");
2904 try o.newline();
2905 try o.outdent();
2906 try w.writeByte('}');
2907 try o.newline();
2908 },
2164 try w.print("static zig_{t} ", .{kind});
2165 try dg.renderFunctionSignature(w, fn_val, .none, .definition, switch (kind) {
2166 .never_tail => .{ .nav_never_tail = fn_nav },
2167 .never_inline => .{ .nav_never_inline = fn_nav },
2168 });
2169 try w.writeAll(" {\n return ");
2170 try renderNavName(w, fn_nav, ip);
2171 try w.writeByte('(');
2172 {
2173 const func_type = ip.indexToKey(fn_val.typeOf(zcu).toIntern()).func_type;
2174 var c_param_index: u32 = 0;
2175 for (func_type.param_types.get(ip)) |param_ty_ip| {
2176 const param_ty: Type = .fromInterned(param_ty_ip);
2177 if (!param_ty.hasRuntimeBits(zcu)) continue;
2178 if (c_param_index != 0) try w.writeAll(", ");
2179 try w.print("a{d}", .{c_param_index});
2180 c_param_index += 1;
2181 }
29092182 }
2183 try w.writeAll(");\n}\n");
29102184}
29112185
29122186pub fn generate(
......@@ -2925,110 +2199,109 @@ pub fn generate(
29252199
29262200 const func = zcu.funcInfo(func_index);
29272201
2202 var arena: std.heap.ArenaAllocator = .init(gpa);
2203 defer arena.deinit();
2204
29282205 var function: Function = .{
29292206 .value_map = .init(gpa),
29302207 .air = air.*,
29312208 .liveness = liveness.*.?,
29322209 .func_index = func_index,
2933 .object = .{
2934 .dg = .{
2935 .gpa = gpa,
2936 .pt = pt,
2937 .mod = zcu.navFileScope(func.owner_nav).mod.?,
2938 .error_msg = null,
2939 .pass = .{ .nav = func.owner_nav },
2940 .is_naked_fn = Type.fromInterned(func.ty).fnCallingConvention(zcu) == .naked,
2941 .expected_block = null,
2942 .fwd_decl = .init(gpa),
2943 .ctype_pool = .empty,
2944 .scratch = .empty,
2945 .uavs = .empty,
2946 },
2947 .code_header = .init(gpa),
2948 .code = .init(gpa),
2949 .indent_counter = 0,
2210 .dg = .{
2211 .gpa = gpa,
2212 .arena = arena.allocator(),
2213 .pt = pt,
2214 .mod = zcu.navFileScope(func.owner_nav).mod.?,
2215 .error_msg = null,
2216 .owner_nav = func.owner_nav.toOptional(),
2217 .is_naked_fn = Type.fromInterned(func.ty).fnCallingConvention(zcu) == .naked,
2218 .expected_block = null,
2219 .ctype_deps = .empty,
2220 .uavs = .empty,
29502221 },
2951 .lazy_fns = .empty,
2222 .code = .init(gpa),
2223 .indent_counter = 0,
2224 .need_tag_name_funcs = .empty,
2225 .need_never_tail_funcs = .empty,
2226 .need_never_inline_funcs = .empty,
29522227 };
29532228 defer {
2954 function.object.code_header.deinit();
2955 function.object.code.deinit();
2956 function.object.dg.fwd_decl.deinit();
2957 function.object.dg.ctype_pool.deinit(gpa);
2958 function.object.dg.scratch.deinit(gpa);
2959 function.object.dg.uavs.deinit(gpa);
2229 function.code.deinit();
2230 function.dg.ctype_deps.deinit(gpa);
2231 function.dg.uavs.deinit(gpa);
29602232 function.deinit();
29612233 }
2962 try function.object.dg.ctype_pool.init(gpa);
29632234
2964 genFunc(&function) catch |err| switch (err) {
2965 error.AnalysisFail => return zcu.codegenFailMsg(func.owner_nav, function.object.dg.error_msg.?),
2966 error.OutOfMemory => return error.OutOfMemory,
2235 var fwd_decl: Writer.Allocating = .init(gpa);
2236 defer fwd_decl.deinit();
2237
2238 var code_header: Writer.Allocating = .init(gpa);
2239 defer code_header.deinit();
2240
2241 genFunc(&function, &fwd_decl.writer, &code_header.writer) catch |err| switch (err) {
2242 error.AnalysisFail => return zcu.codegenFailMsg(func.owner_nav, function.dg.error_msg.?),
29672243 error.WriteFailed => return error.OutOfMemory,
2244 error.OutOfMemory => |e| return e,
29682245 };
29692246
29702247 var mir: Mir = .{
2971 .uavs = .empty,
2972 .code = &.{},
2973 .code_header = &.{},
29742248 .fwd_decl = &.{},
2975 .ctype_pool = .empty,
2976 .lazy_fns = .empty,
2249 .code_header = &.{},
2250 .code = &.{},
2251 .ctype_deps = function.dg.ctype_deps.move(),
2252 .need_uavs = function.dg.uavs.move(),
2253 .need_tag_name_funcs = function.need_tag_name_funcs.move(),
2254 .need_never_tail_funcs = function.need_never_tail_funcs.move(),
2255 .need_never_inline_funcs = function.need_never_inline_funcs.move(),
29772256 };
29782257 errdefer mir.deinit(gpa);
2979 mir.uavs = function.object.dg.uavs.move();
2980 mir.code_header = try function.object.code_header.toOwnedSlice();
2981 mir.code = try function.object.code.toOwnedSlice();
2982 mir.fwd_decl = try function.object.dg.fwd_decl.toOwnedSlice();
2983 mir.ctype_pool = function.object.dg.ctype_pool.move();
2984 mir.lazy_fns = function.lazy_fns.move();
2258 mir.fwd_decl = try fwd_decl.toOwnedSlice();
2259 mir.code_header = try code_header.toOwnedSlice();
2260 mir.code = try function.code.toOwnedSlice();
29852261 return mir;
29862262}
29872263
2988pub fn genFunc(f: *Function) Error!void {
2264pub fn genFunc(f: *Function, fwd_decl_writer: *Writer, header_writer: *Writer) Error!void {
29892265 const tracy = trace(@src());
29902266 defer tracy.end();
29912267
2992 const o = &f.object;
2993 const zcu = o.dg.pt.zcu;
2268 const zcu = f.dg.pt.zcu;
29942269 const ip = &zcu.intern_pool;
2995 const gpa = o.dg.gpa;
2996 const nav_index = o.dg.pass.nav;
2270 const gpa = f.dg.gpa;
2271 const nav_index = f.dg.owner_nav.unwrap().?;
29972272 const nav_val = zcu.navValue(nav_index);
29982273 const nav = ip.getNav(nav_index);
29992274
3000 const fwd = &o.dg.fwd_decl.writer;
3001 try fwd.writeAll("static ");
3002 try o.dg.renderFunctionSignature(
3003 fwd,
2275 try fwd_decl_writer.writeAll("static ");
2276 try f.dg.renderFunctionSignature(
2277 fwd_decl_writer,
30042278 nav_val,
30052279 nav.status.fully_resolved.alignment,
3006 .forward,
2280 .forward_decl,
30072281 .{ .nav = nav_index },
30082282 );
3009 try fwd.writeAll(";\n");
2283 try fwd_decl_writer.writeAll(";\n");
30102284
3011 const ch = &o.code_header.writer;
30122285 if (nav.status.fully_resolved.@"linksection".toSlice(ip)) |s|
3013 try ch.print("zig_linksection_fn({f}) ", .{fmtStringLiteral(s, null)});
3014 try o.dg.renderFunctionSignature(
3015 ch,
2286 try header_writer.print("zig_linksection_fn({f}) ", .{fmtStringLiteral(s, null)});
2287 try f.dg.renderFunctionSignature(
2288 header_writer,
30162289 nav_val,
30172290 .none,
3018 .complete,
2291 .definition,
30192292 .{ .nav = nav_index },
30202293 );
3021 try ch.writeAll(" {\n ");
2294 try header_writer.writeAll(" {\n ");
30222295
30232296 f.free_locals_map.clearRetainingCapacity();
30242297
30252298 const main_body = f.air.getMainBody();
3026 o.indent();
2299 f.indent();
30272300 try genBodyResolveState(f, undefined, &.{}, main_body, true);
3028 try o.outdent();
3029 try o.code.writer.writeByte('}');
3030 try o.newline();
3031 if (o.dg.expected_block) |_|
2301 try f.outdent();
2302 try f.code.writer.writeByte('}');
2303 try f.newline();
2304 if (f.dg.expected_block) |_|
30322305 return f.fail("runtime code not allowed in naked function", .{});
30332306
30342307 // Take advantage of the free_locals map to bucket locals per type. All
......@@ -3042,155 +2315,204 @@ pub fn genFunc(f: *Function) Error!void {
30422315 if (!should_emit) continue;
30432316 const local = f.locals.items[local_index];
30442317 log.debug("inserting local {d} into free_locals", .{local_index});
3045 const gop = try free_locals.getOrPut(gpa, local.getType());
2318 const gop = try free_locals.getOrPut(gpa, local);
30462319 if (!gop.found_existing) gop.value_ptr.* = .{};
30472320 try gop.value_ptr.putNoClobber(gpa, local_index, {});
30482321 }
30492322
30502323 const SortContext = struct {
2324 zcu: *const Zcu,
30512325 keys: []const LocalType,
30522326
30532327 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {
3054 const lhs_ty = ctx.keys[lhs_index];
3055 const rhs_ty = ctx.keys[rhs_index];
3056 return lhs_ty.alignas.order(rhs_ty.alignas).compare(.gt);
2328 const lhs = ctx.keys[lhs_index];
2329 const rhs = ctx.keys[rhs_index];
2330 const lhs_align = switch (lhs.alignment) {
2331 .none => lhs.type.abiAlignment(ctx.zcu),
2332 else => |a| a,
2333 };
2334 const rhs_align = switch (rhs.alignment) {
2335 .none => rhs.type.abiAlignment(ctx.zcu),
2336 else => |a| a,
2337 };
2338 return Alignment.compareStrict(lhs_align, .gt, rhs_align);
30572339 }
30582340 };
3059 free_locals.sort(SortContext{ .keys = free_locals.keys() });
2341 free_locals.sort(SortContext{
2342 .zcu = zcu,
2343 .keys = free_locals.keys(),
2344 });
30602345
30612346 for (free_locals.values()) |list| {
30622347 for (list.keys()) |local_index| {
30632348 const local = f.locals.items[local_index];
3064 try o.dg.renderCTypeAndName(ch, local.ctype, .{ .local = local_index }, .{}, local.flags.alignas);
3065 try ch.writeAll(";\n ");
2349 try f.dg.renderTypeAndName(header_writer, local.type, .{ .local = local_index }, .{}, local.alignment);
2350 try header_writer.writeAll(";\n ");
30662351 }
30672352 }
30682353}
30692354
3070pub fn genDecl(o: *Object) Error!void {
2355pub fn genDecl(dg: *DeclGen, w: *Writer) Error!void {
30712356 const tracy = trace(@src());
30722357 defer tracy.end();
30732358
3074 const pt = o.dg.pt;
2359 const pt = dg.pt;
30752360 const zcu = pt.zcu;
30762361 const ip = &zcu.intern_pool;
3077 const nav = ip.getNav(o.dg.pass.nav);
2362 const nav = ip.getNav(dg.owner_nav.unwrap().?);
30782363 const nav_ty: Type = .fromInterned(nav.typeOf(ip));
30792364
3080 if (!nav_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return;
3081 switch (ip.indexToKey(nav.status.fully_resolved.val)) {
3082 .@"extern" => |@"extern"| {
3083 if (!ip.isFunctionType(nav_ty.toIntern())) return o.dg.renderFwdDecl(o.dg.pass.nav, .{
3084 .is_const = @"extern".is_const,
3085 .is_threadlocal = @"extern".is_threadlocal,
3086 .linkage = @"extern".linkage,
3087 .visibility = @"extern".visibility,
3088 });
2365 const is_const: bool, const is_threadlocal: bool, const init_val: Value = switch (ip.indexToKey(nav.status.fully_resolved.val)) {
2366 else => .{ true, false, .fromInterned(nav.status.fully_resolved.val) },
2367 .variable => |v| .{ false, v.is_threadlocal, .fromInterned(v.init) },
2368 .@"extern" => return,
2369 };
30892370
3090 const fwd = &o.dg.fwd_decl.writer;
3091 try fwd.writeAll("zig_extern ");
3092 try o.dg.renderFunctionSignature(
3093 fwd,
3094 Value.fromInterned(nav.status.fully_resolved.val),
3095 nav.status.fully_resolved.alignment,
3096 .forward,
3097 .{ .@"export" = .{
3098 .main_name = nav.name,
3099 .extern_name = nav.name,
3100 } },
3101 );
3102 try fwd.writeAll(";\n");
3103 },
3104 .variable => |variable| {
3105 try o.dg.renderFwdDecl(o.dg.pass.nav, .{
3106 .is_const = false,
3107 .is_threadlocal = variable.is_threadlocal,
3108 .linkage = .internal,
3109 .visibility = .default,
3110 });
3111 const w = &o.code.writer;
3112 if (variable.is_threadlocal and !o.dg.mod.single_threaded) try w.writeAll("zig_threadlocal ");
3113 if (nav.status.fully_resolved.@"linksection".toSlice(&zcu.intern_pool)) |s|
3114 try w.print("zig_linksection({f}) ", .{fmtStringLiteral(s, null)});
3115 try o.dg.renderTypeAndName(
3116 w,
3117 nav_ty,
3118 .{ .nav = o.dg.pass.nav },
3119 .{},
3120 nav.status.fully_resolved.alignment,
3121 .complete,
3122 );
3123 try w.writeAll(" = ");
3124 try o.dg.renderValue(w, Value.fromInterned(variable.init), .StaticInitializer);
3125 try w.writeByte(';');
3126 try o.newline();
3127 },
3128 else => try genDeclValue(
3129 o,
3130 Value.fromInterned(nav.status.fully_resolved.val),
3131 .{ .nav = o.dg.pass.nav },
3132 nav.status.fully_resolved.alignment,
3133 nav.status.fully_resolved.@"linksection",
3134 ),
2371 if (nav.status.fully_resolved.@"linksection".toSlice(ip)) |s| {
2372 try w.print("zig_linksection({f}) ", .{fmtStringLiteral(s, null)});
31352373 }
2374
2375 // We don't bother underaligning---it's unnecessary and hurts compatibility.
2376 const a = nav.status.fully_resolved.alignment;
2377 if (a != .none and a.compareStrict(.gt, nav_ty.abiAlignment(zcu))) {
2378 try w.print("zig_align({d}) ", .{a.toByteUnits().?});
2379 }
2380
2381 try genDeclValue(dg, w, .{
2382 .name = .{ .nav = dg.owner_nav.unwrap().? },
2383 .@"const" = is_const,
2384 .@"threadlocal" = is_threadlocal,
2385 .init_val = init_val,
2386 });
31362387}
2388pub fn genDeclFwd(dg: *DeclGen, w: *Writer) Error!void {
2389 const tracy = trace(@src());
2390 defer tracy.end();
31372391
3138pub fn genDeclValue(
3139 o: *Object,
3140 val: Value,
3141 decl_c_value: CValue,
3142 alignment: Alignment,
3143 @"linksection": InternPool.OptionalNullTerminatedString,
3144) Error!void {
3145 const zcu = o.dg.pt.zcu;
3146 const ty = val.typeOf(zcu);
2392 const pt = dg.pt;
2393 const zcu = pt.zcu;
2394 const ip = &zcu.intern_pool;
2395 const nav = ip.getNav(dg.owner_nav.unwrap().?);
2396 const nav_ty: Type = .fromInterned(nav.typeOf(ip));
31472397
3148 const fwd = &o.dg.fwd_decl.writer;
3149 try fwd.writeAll("static ");
3150 try o.dg.renderTypeAndName(fwd, ty, decl_c_value, Const, alignment, .complete);
3151 try fwd.writeAll(";\n");
2398 const is_const: bool, const is_threadlocal: bool, const init_val: Value = switch (ip.indexToKey(nav.status.fully_resolved.val)) {
2399 else => .{ true, false, .fromInterned(nav.status.fully_resolved.val) },
2400 .variable => |v| .{ false, v.is_threadlocal, .fromInterned(v.init) },
31522401
3153 const w = &o.code.writer;
3154 if (@"linksection".toSlice(&zcu.intern_pool)) |s|
3155 try w.print("zig_linksection({f}) ", .{fmtStringLiteral(s, null)});
3156 try o.dg.renderTypeAndName(w, ty, decl_c_value, Const, alignment, .complete);
2402 .@"extern" => |@"extern"| switch (nav_ty.zigTypeTag(zcu)) {
2403 .@"fn" => {
2404 try w.writeAll("zig_extern ");
2405 try dg.renderFunctionSignature(
2406 w,
2407 Value.fromInterned(nav.status.fully_resolved.val),
2408 nav.status.fully_resolved.alignment,
2409 .forward_decl,
2410 .{ .@"export" = .{
2411 .main_name = nav.name,
2412 .extern_name = nav.name,
2413 } },
2414 );
2415 try w.writeAll(";\n");
2416 return;
2417 },
2418 else => {
2419 switch (@"extern".linkage) {
2420 .internal => try w.writeAll("static "),
2421 .strong => try w.print("zig_extern zig_visibility({t}) ", .{@"extern".visibility}),
2422 .weak => try w.print("zig_extern zig_weak_linkage zig_visibility({t}) ", .{@"extern".visibility}),
2423 .link_once => return dg.fail("TODO: CBE: implement linkonce linkage?", .{}),
2424 }
2425 if (@"extern".is_threadlocal and !dg.mod.single_threaded) {
2426 try w.writeAll("zig_threadlocal ");
2427 }
2428 try dg.renderTypeAndName(
2429 w,
2430 .fromInterned(nav.typeOf(ip)),
2431 .{ .nav = dg.owner_nav.unwrap().? },
2432 .{ .@"const" = @"extern".is_const },
2433 nav.getAlignment(),
2434 );
2435 try w.writeAll(";\n");
2436 return;
2437 },
2438 },
2439 };
2440
2441 // We don't bother underaligning---it's unnecessary and hurts compatibility.
2442 const a = nav.status.fully_resolved.alignment;
2443 if (a != .none and a.compareStrict(.gt, nav_ty.abiAlignment(zcu))) {
2444 try w.print("zig_align({d}) ", .{a.toByteUnits().?});
2445 }
2446
2447 try genDeclValueFwd(dg, w, .{
2448 .name = .{ .nav = dg.owner_nav.unwrap().? },
2449 .@"const" = is_const,
2450 .@"threadlocal" = is_threadlocal,
2451 .init_val = init_val,
2452 });
2453}
2454pub fn genDeclValue(dg: *DeclGen, w: *Writer, options: struct {
2455 name: CValue,
2456 @"const": bool,
2457 @"threadlocal": bool,
2458 init_val: Value,
2459}) Error!void {
2460 const zcu = dg.pt.zcu;
2461 const ty = options.init_val.typeOf(zcu);
2462 if (options.@"threadlocal" and !dg.mod.single_threaded) {
2463 try w.writeAll("zig_threadlocal ");
2464 }
2465 try dg.renderTypeAndName(w, ty, options.name, .{ .@"const" = options.@"const" }, .none);
31572466 try w.writeAll(" = ");
3158 try o.dg.renderValue(w, val, .StaticInitializer);
3159 try w.writeByte(';');
3160 try o.newline();
2467 try dg.renderValue(w, options.init_val, .static_initializer);
2468 try w.writeAll(";\n");
2469}
2470pub fn genDeclValueFwd(dg: *DeclGen, w: *Writer, options: struct {
2471 name: CValue,
2472 @"const": bool,
2473 @"threadlocal": bool,
2474 init_val: Value,
2475}) Error!void {
2476 const zcu = dg.pt.zcu;
2477 const ty = options.init_val.typeOf(zcu);
2478 try w.writeAll("static ");
2479 if (options.@"threadlocal" and !dg.mod.single_threaded) {
2480 try w.writeAll("zig_threadlocal ");
2481 }
2482 try dg.renderTypeAndName(w, ty, options.name, .{ .@"const" = options.@"const" }, .none);
2483 try w.writeAll(";\n");
31612484}
31622485
3163pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const Zcu.Export.Index) !void {
2486pub fn genExports(dg: *DeclGen, w: *Writer, exported: Zcu.Exported, export_indices: []const Zcu.Export.Index) !void {
31642487 const zcu = dg.pt.zcu;
31652488 const ip = &zcu.intern_pool;
3166 const fwd = &dg.fwd_decl.writer;
31672489
31682490 const main_name = export_indices[0].ptr(zcu).opts.name;
3169 try fwd.writeAll("#define ");
2491 try w.writeAll("#define ");
31702492 switch (exported) {
3171 .nav => |nav| try dg.renderNavName(fwd, nav),
3172 .uav => |uav| try DeclGen.renderUavName(fwd, Value.fromInterned(uav)),
2493 .nav => |nav| try renderNavName(w, nav, ip),
2494 .uav => |uav| try renderUavName(w, Value.fromInterned(uav)),
31732495 }
3174 try fwd.writeByte(' ');
3175 try fwd.print("{f}", .{fmtIdentSolo(main_name.toSlice(ip))});
3176 try fwd.writeByte('\n');
2496 try w.writeByte(' ');
2497 try w.print("{f}", .{fmtIdentSolo(main_name.toSlice(ip))});
2498 try w.writeByte('\n');
31772499
31782500 const exported_val = exported.getValue(zcu);
31792501 if (ip.isFunctionType(exported_val.typeOf(zcu).toIntern())) return for (export_indices) |export_index| {
31802502 const @"export" = export_index.ptr(zcu);
3181 try fwd.writeAll("zig_extern ");
3182 if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage_fn ");
2503 try w.writeAll("zig_extern ");
2504 if (@"export".opts.linkage == .weak) try w.writeAll("zig_weak_linkage_fn ");
31832505 try dg.renderFunctionSignature(
3184 fwd,
2506 w,
31852507 exported.getValue(zcu),
31862508 exported.getAlign(zcu),
3187 .forward,
2509 .forward_decl,
31882510 .{ .@"export" = .{
31892511 .main_name = main_name,
31902512 .extern_name = @"export".opts.name,
31912513 } },
31922514 );
3193 try fwd.writeAll(";\n");
2515 try w.writeAll(";\n");
31942516 };
31952517 const is_const = switch (ip.indexToKey(exported_val.toIntern())) {
31962518 .func => unreachable,
......@@ -3200,39 +2522,38 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const
32002522 };
32012523 for (export_indices) |export_index| {
32022524 const @"export" = export_index.ptr(zcu);
3203 try fwd.writeAll("zig_extern ");
3204 if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage ");
3205 if (@"export".opts.section.toSlice(ip)) |s| try fwd.print("zig_linksection({f}) ", .{
2525 try w.writeAll("zig_extern ");
2526 if (@"export".opts.linkage == .weak) try w.writeAll("zig_weak_linkage ");
2527 if (@"export".opts.section.toSlice(ip)) |s| try w.print("zig_linksection({f}) ", .{
32062528 fmtStringLiteral(s, null),
32072529 });
32082530 const extern_name = @"export".opts.name.toSlice(ip);
32092531 const is_mangled = isMangledIdent(extern_name, true);
32102532 const is_export = @"export".opts.name != main_name;
32112533 try dg.renderTypeAndName(
3212 fwd,
2534 w,
32132535 exported.getValue(zcu).typeOf(zcu),
32142536 .{ .identifier = extern_name },
3215 CQualifiers.init(.{ .@"const" = is_const }),
2537 .{ .@"const" = is_const },
32162538 exported.getAlign(zcu),
3217 .complete,
32182539 );
32192540 if (is_mangled and is_export) {
3220 try fwd.print(" zig_mangled_export({f}, {f}, {f})", .{
2541 try w.print(" zig_mangled_export({f}, {f}, {f})", .{
32212542 fmtIdentSolo(extern_name),
32222543 fmtStringLiteral(extern_name, null),
32232544 fmtStringLiteral(main_name.toSlice(ip), null),
32242545 });
32252546 } else if (is_mangled) {
3226 try fwd.print(" zig_mangled({f}, {f})", .{
2547 try w.print(" zig_mangled({f}, {f})", .{
32272548 fmtIdentSolo(extern_name), fmtStringLiteral(extern_name, null),
32282549 });
32292550 } else if (is_export) {
3230 try fwd.print(" zig_export({f}, {f})", .{
2551 try w.print(" zig_export({f}, {f})", .{
32312552 fmtStringLiteral(main_name.toSlice(ip), null),
32322553 fmtStringLiteral(extern_name, null),
32332554 });
32342555 }
3235 try fwd.writeAll(";\n");
2556 try w.writeAll(";\n");
32362557 }
32372558}
32382559
......@@ -3241,15 +2562,15 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const
32412562/// have been added to `free_locals_map`. For a version of this function that restores this state,
32422563/// see `genBodyResolveState`.
32432564fn genBody(f: *Function, body: []const Air.Inst.Index) Error!void {
3244 const w = &f.object.code.writer;
2565 const w = &f.code.writer;
32452566 if (body.len == 0) {
32462567 try w.writeAll("{}");
32472568 } else {
32482569 try w.writeByte('{');
3249 f.object.indent();
3250 try f.object.newline();
2570 f.indent();
2571 try f.newline();
32512572 try genBodyInner(f, body);
3252 try f.object.outdent();
2573 try f.outdent();
32532574 try w.writeByte('}');
32542575 }
32552576}
......@@ -3263,13 +2584,13 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) Error!void {
32632584fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []const Air.Inst.Index, body: []const Air.Inst.Index, inner: bool) Error!void {
32642585 if (body.len == 0) {
32652586 // Don't go to the expense of cloning everything!
3266 if (!inner) try f.object.code.writer.writeAll("{}");
2587 if (!inner) try f.code.writer.writeAll("{}");
32672588 return;
32682589 }
32692590
32702591 // TODO: we can probably avoid the copies in some other common cases too.
32712592
3272 const gpa = f.object.dg.gpa;
2593 const gpa = f.dg.gpa;
32732594
32742595 // Save the original value_map and free_locals_map so that we can restore them after the body.
32752596 var old_value_map = try f.value_map.clone();
......@@ -3310,13 +2631,13 @@ fn genBodyResolveState(f: *Function, inst: Air.Inst.Index, leading_deaths: []con
33102631}
33112632
33122633fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {
3313 const zcu = f.object.dg.pt.zcu;
2634 const zcu = f.dg.pt.zcu;
33142635 const ip = &zcu.intern_pool;
33152636 const air_tags = f.air.instructions.items(.tag);
33162637 const air_datas = f.air.instructions.items(.data);
33172638
33182639 for (body) |inst| {
3319 if (f.object.dg.expected_block) |_|
2640 if (f.dg.expected_block) |_|
33202641 return f.fail("runtime code not allowed in naked function", .{});
33212642 if (f.liveness.isUnused(inst) and !f.air.mustLower(inst, ip))
33222643 continue;
......@@ -3585,8 +2906,8 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) Error!void {
35852906 .ret => return airRet(f, inst, false),
35862907 .ret_safe => return airRet(f, inst, false), // TODO
35872908 .ret_load => return airRet(f, inst, true),
3588 .trap => return airTrap(f, &f.object.code.writer),
3589 .unreach => return airUnreach(&f.object),
2909 .trap => return airTrap(f),
2910 .unreach => return airUnreach(f),
35902911
35912912 // Instructions which may be `noreturn`.
35922913 .block => res: {
......@@ -3629,177 +2950,159 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
36292950 const operand = try f.resolveInst(ty_op.operand);
36302951 try reap(f, inst, &.{ty_op.operand});
36312952
3632 const w = &f.object.code.writer;
2953 const w = &f.code.writer;
36332954 const local = try f.allocLocal(inst, inst_ty);
3634 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
3635 try f.writeCValue(w, local, .Other);
3636 try a.assign(f, w);
2955 try f.writeCValue(w, local, .other);
2956 try w.writeAll(" = ");
36372957 if (is_ptr) {
36382958 try w.writeByte('&');
36392959 try f.writeCValueDerefMember(w, operand, .{ .identifier = field_name });
36402960 } else try f.writeCValueMember(w, operand, .{ .identifier = field_name });
3641 try a.end(f, w);
2961 try w.writeByte(';');
2962 try f.newline();
36422963 return local;
36432964}
36442965
36452966fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3646 const zcu = f.object.dg.pt.zcu;
2967 const zcu = f.dg.pt.zcu;
36472968 const inst_ty = f.typeOfIndex(inst);
36482969 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3649 if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
3650 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3651 return .none;
3652 }
2970 assert(inst_ty.hasRuntimeBits(zcu));
36532971
36542972 const ptr = try f.resolveInst(bin_op.lhs);
36552973 const index = try f.resolveInst(bin_op.rhs);
36562974 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
36572975
3658 const w = &f.object.code.writer;
2976 const w = &f.code.writer;
36592977 const local = try f.allocLocal(inst, inst_ty);
3660 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
3661 try f.writeCValue(w, local, .Other);
3662 try a.assign(f, w);
3663 try f.writeCValue(w, ptr, .Other);
2978 try f.writeCValue(w, local, .other);
2979 try w.writeAll(" = ");
2980 switch (f.typeOf(bin_op.lhs).ptrSize(zcu)) {
2981 .one => try f.writeCValueDerefMember(w, ptr, .{ .identifier = "array" }),
2982 .many, .c => try f.writeCValue(w, ptr, .other),
2983 .slice => unreachable,
2984 }
36642985 try w.writeByte('[');
3665 try f.writeCValue(w, index, .Other);
3666 try w.writeByte(']');
3667 try a.end(f, w);
2986 try f.writeCValue(w, index, .other);
2987 try w.writeAll("];");
2988 try f.newline();
36682989 return local;
36692990}
36702991
36712992fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3672 const pt = f.object.dg.pt;
2993 const pt = f.dg.pt;
36732994 const zcu = pt.zcu;
36742995 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
36752996 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
36762997
36772998 const inst_ty = f.typeOfIndex(inst);
36782999 const ptr_ty = f.typeOf(bin_op.lhs);
3679 const elem_has_bits = ptr_ty.elemType2(zcu).hasRuntimeBitsIgnoreComptime(zcu);
3000 assert(ptr_ty.indexableElem(zcu).hasRuntimeBits(zcu));
36803001
36813002 const ptr = try f.resolveInst(bin_op.lhs);
36823003 const index = try f.resolveInst(bin_op.rhs);
36833004 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
36843005
3685 const w = &f.object.code.writer;
3006 const w = &f.code.writer;
36863007 const local = try f.allocLocal(inst, inst_ty);
3687 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
3688 try f.writeCValue(w, local, .Other);
3689 try a.assign(f, w);
3690 try w.writeByte('(');
3691 try f.renderType(w, inst_ty);
3692 try w.writeByte(')');
3693 if (elem_has_bits) try w.writeByte('&');
3694 if (elem_has_bits and ptr_ty.ptrSize(zcu) == .one) {
3695 // It's a pointer to an array, so we need to de-reference.
3696 try f.writeCValueDeref(w, ptr);
3697 } else try f.writeCValue(w, ptr, .Other);
3698 if (elem_has_bits) {
3699 try w.writeByte('[');
3700 try f.writeCValue(w, index, .Other);
3701 try w.writeByte(']');
3008 try f.writeCValue(w, local, .other);
3009 try w.writeAll(" = ");
3010 try w.writeByte('&');
3011 if (ptr_ty.ptrSize(zcu) == .one) {
3012 // `*[n]T` was turned into a pointer to `struct { T array[n]; }`
3013 try f.writeCValueDerefMember(w, ptr, .{ .identifier = "array" });
3014 } else {
3015 try f.writeCValue(w, ptr, .other);
37023016 }
3703 try a.end(f, w);
3017 try w.writeByte('[');
3018 try f.writeCValue(w, index, .other);
3019 try w.writeAll("];");
3020 try f.newline();
37043021 return local;
37053022}
37063023
37073024fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3708 const zcu = f.object.dg.pt.zcu;
3025 const zcu = f.dg.pt.zcu;
37093026 const inst_ty = f.typeOfIndex(inst);
37103027 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
3711 if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
3712 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3713 return .none;
3714 }
3028 assert(inst_ty.hasRuntimeBits(zcu));
37153029
37163030 const slice = try f.resolveInst(bin_op.lhs);
37173031 const index = try f.resolveInst(bin_op.rhs);
37183032 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
37193033
3720 const w = &f.object.code.writer;
3034 const w = &f.code.writer;
37213035 const local = try f.allocLocal(inst, inst_ty);
3722 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
3723 try f.writeCValue(w, local, .Other);
3724 try a.assign(f, w);
3036 try f.writeCValue(w, local, .other);
3037 try w.writeAll(" = ");
37253038 try f.writeCValueMember(w, slice, .{ .identifier = "ptr" });
37263039 try w.writeByte('[');
3727 try f.writeCValue(w, index, .Other);
3728 try w.writeByte(']');
3729 try a.end(f, w);
3040 try f.writeCValue(w, index, .other);
3041 try w.writeAll("];");
3042 try f.newline();
37303043 return local;
37313044}
37323045
37333046fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3734 const pt = f.object.dg.pt;
3047 const pt = f.dg.pt;
37353048 const zcu = pt.zcu;
37363049 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
37373050 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
37383051
37393052 const inst_ty = f.typeOfIndex(inst);
37403053 const slice_ty = f.typeOf(bin_op.lhs);
3741 const elem_ty = slice_ty.elemType2(zcu);
3742 const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(zcu);
3054 const elem_ty = slice_ty.childType(zcu);
3055 assert(elem_ty.hasRuntimeBits(zcu));
37433056
37443057 const slice = try f.resolveInst(bin_op.lhs);
37453058 const index = try f.resolveInst(bin_op.rhs);
37463059 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
37473060
3748 const w = &f.object.code.writer;
3061 const w = &f.code.writer;
37493062 const local = try f.allocLocal(inst, inst_ty);
3750 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
3751 try f.writeCValue(w, local, .Other);
3752 try a.assign(f, w);
3753 if (elem_has_bits) try w.writeByte('&');
3063 try f.writeCValue(w, local, .other);
3064 try w.writeAll(" = ");
3065 try w.writeByte('&');
37543066 try f.writeCValueMember(w, slice, .{ .identifier = "ptr" });
3755 if (elem_has_bits) {
3756 try w.writeByte('[');
3757 try f.writeCValue(w, index, .Other);
3758 try w.writeByte(']');
3759 }
3760 try a.end(f, w);
3067 try w.writeByte('[');
3068 try f.writeCValue(w, index, .other);
3069 try w.writeAll("];");
3070 try f.newline();
37613071 return local;
37623072}
37633073
37643074fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
3765 const zcu = f.object.dg.pt.zcu;
3075 const zcu = f.dg.pt.zcu;
37663076 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
37673077 const inst_ty = f.typeOfIndex(inst);
3768 if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
3769 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
3770 return .none;
3771 }
3078 assert(inst_ty.hasRuntimeBits(zcu));
37723079
37733080 const array = try f.resolveInst(bin_op.lhs);
37743081 const index = try f.resolveInst(bin_op.rhs);
37753082 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
37763083
3777 const w = &f.object.code.writer;
3084 const w = &f.code.writer;
37783085 const local = try f.allocLocal(inst, inst_ty);
3779 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
3780 try f.writeCValue(w, local, .Other);
3781 try a.assign(f, w);
3782 try f.writeCValue(w, array, .Other);
3086 try f.writeCValue(w, local, .other);
3087 try w.writeAll(" = ");
3088 try f.writeCValueMember(w, array, .{ .identifier = "array" });
37833089 try w.writeByte('[');
3784 try f.writeCValue(w, index, .Other);
3785 try w.writeByte(']');
3786 try a.end(f, w);
3090 try f.writeCValue(w, index, .other);
3091 try w.writeAll("];");
3092 try f.newline();
37873093 return local;
37883094}
37893095
37903096fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
3791 const pt = f.object.dg.pt;
3097 const pt = f.dg.pt;
37923098 const zcu = pt.zcu;
37933099 const inst_ty = f.typeOfIndex(inst);
37943100 const elem_ty = inst_ty.childType(zcu);
3795 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return .{ .undef = inst_ty };
3101 if (!elem_ty.hasRuntimeBits(zcu)) return .{ .undef = inst_ty };
37963102
37973103 const local = try f.allocLocalValue(.{
3798 .ctype = try f.ctypeFromType(elem_ty, .complete),
3799 .alignas = CType.AlignAs.fromAlignment(.{
3800 .@"align" = inst_ty.ptrInfo(zcu).flags.alignment,
3801 .abi = elem_ty.abiAlignment(zcu),
3802 }),
3104 .type = elem_ty,
3105 .alignment = inst_ty.ptrInfo(zcu).flags.alignment,
38033106 });
38043107 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });
38053108 try f.allocs.put(zcu.gpa, local.new_local, true);
......@@ -3810,11 +3113,11 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
38103113 // For packed aggregates, we zero-initialize to try and work around a design flaw
38113114 // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore`
38123115 // for details.
3813 const w = &f.object.code.writer;
3116 const w = &f.code.writer;
38143117 try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local});
38153118 try f.renderType(w, elem_ty);
38163119 try w.writeAll("));");
3817 try f.object.newline();
3120 try f.newline();
38183121 },
38193122 .auto, .@"extern" => {},
38203123 },
......@@ -3825,18 +3128,15 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue {
38253128}
38263129
38273130fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {
3828 const pt = f.object.dg.pt;
3131 const pt = f.dg.pt;
38293132 const zcu = pt.zcu;
38303133 const inst_ty = f.typeOfIndex(inst);
38313134 const elem_ty = inst_ty.childType(zcu);
3832 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return .{ .undef = inst_ty };
3135 if (!elem_ty.hasRuntimeBits(zcu)) return .{ .undef = inst_ty };
38333136
38343137 const local = try f.allocLocalValue(.{
3835 .ctype = try f.ctypeFromType(elem_ty, .complete),
3836 .alignas = CType.AlignAs.fromAlignment(.{
3837 .@"align" = inst_ty.ptrInfo(zcu).flags.alignment,
3838 .abi = elem_ty.abiAlignment(zcu),
3839 }),
3138 .type = elem_ty,
3139 .alignment = inst_ty.ptrInfo(zcu).flags.alignment,
38403140 });
38413141 log.debug("%{d}: allocated unfreeable t{d}", .{ inst, local.new_local });
38423142 try f.allocs.put(zcu.gpa, local.new_local, true);
......@@ -3847,11 +3147,11 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {
38473147 // For packed aggregates, we zero-initialize to try and work around a design flaw
38483148 // related to how `packed`, `undefined`, and RLS interact. See comment in `airStore`
38493149 // for details.
3850 const w = &f.object.code.writer;
3150 const w = &f.code.writer;
38513151 try w.print("memset(&t{d}, 0x00, sizeof(", .{local.new_local});
38523152 try f.renderType(w, elem_ty);
38533153 try w.writeAll("));");
3854 try f.object.newline();
3154 try f.newline();
38553155 },
38563156 .auto, .@"extern" => {},
38573157 },
......@@ -3862,24 +3162,18 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue {
38623162}
38633163
38643164fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {
3865 const inst_ty = f.typeOfIndex(inst);
3866 const inst_ctype = try f.ctypeFromType(inst_ty, .parameter);
3867
38683165 const i = f.next_arg_index;
38693166 f.next_arg_index += 1;
3870 const result: CValue = if (inst_ctype.eql(try f.ctypeFromType(inst_ty, .complete)))
3871 .{ .arg = i }
3872 else
3873 .{ .arg_array = i };
3167 const result: CValue = .{ .arg = i };
38743168
38753169 if (f.liveness.isUnused(inst)) {
3876 const w = &f.object.code.writer;
3170 const w = &f.code.writer;
38773171 try w.writeByte('(');
38783172 try f.renderType(w, .void);
38793173 try w.writeByte(')');
3880 try f.writeCValue(w, result, .Other);
3174 try f.writeCValue(w, result, .other);
38813175 try w.writeByte(';');
3882 try f.object.newline();
3176 try f.newline();
38833177 return .none;
38843178 }
38853179
......@@ -3887,7 +3181,7 @@ fn airArg(f: *Function, inst: Air.Inst.Index) !CValue {
38873181}
38883182
38893183fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
3890 const pt = f.object.dg.pt;
3184 const pt = f.dg.pt;
38913185 const zcu = pt.zcu;
38923186 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
38933187
......@@ -3900,10 +3194,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
39003194 // bit-pointers we see here are vector element pointers.
39013195 assert(ptr_info.packed_offset.host_size == 0 or ptr_info.flags.vector_index != .none);
39023196
3903 if (!src_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
3904 try reap(f, inst, &.{ty_op.operand});
3905 return .none;
3906 }
3197 assert(src_ty.hasRuntimeBits(zcu));
39073198
39083199 const operand = try f.resolveInst(ty_op.operand);
39093200
......@@ -3913,94 +3204,69 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue {
39133204 ptr_info.flags.alignment.order(src_ty.abiAlignment(zcu)).compare(.gte)
39143205 else
39153206 true;
3916 const is_array = lowersToArray(src_ty, zcu);
3917 const need_memcpy = !is_aligned or is_array;
39183207
3919 const w = &f.object.code.writer;
3208 const w = &f.code.writer;
39203209 const local = try f.allocLocal(inst, src_ty);
39213210 const v = try Vectorize.start(f, inst, w, ptr_ty);
39223211
3923 if (need_memcpy) {
3924 try w.writeAll("memcpy(");
3925 if (!is_array) try w.writeByte('&');
3926 try f.writeCValue(w, local, .Other);
3212 if (!is_aligned) {
3213 try w.writeAll("memcpy(&");
3214 try f.writeCValue(w, local, .other);
39273215 try v.elem(f, w);
39283216 try w.writeAll(", (const char *)");
3929 try f.writeCValue(w, operand, .Other);
3217 try f.writeCValue(w, operand, .other);
39303218 try v.elem(f, w);
39313219 try w.writeAll(", sizeof(");
39323220 try f.renderType(w, src_ty);
39333221 try w.writeAll("))");
39343222 } else {
3935 try f.writeCValue(w, local, .Other);
3223 try f.writeCValue(w, local, .other);
39363224 try v.elem(f, w);
39373225 try w.writeAll(" = ");
39383226 try f.writeCValueDeref(w, operand);
39393227 try v.elem(f, w);
39403228 }
39413229 try w.writeByte(';');
3942 try f.object.newline();
3230 try f.newline();
39433231 try v.end(f, inst, w);
39443232
39453233 return local;
39463234}
39473235
39483236fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !void {
3949 const pt = f.object.dg.pt;
3237 const pt = f.dg.pt;
39503238 const zcu = pt.zcu;
39513239 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
3952 const w = &f.object.code.writer;
3240 const w = &f.code.writer;
39533241 const op_inst = un_op.toIndex();
39543242 const op_ty = f.typeOf(un_op);
39553243 const ret_ty = if (is_ptr) op_ty.childType(zcu) else op_ty;
3956 const ret_ctype = try f.ctypeFromType(ret_ty, .parameter);
39573244
39583245 if (op_inst != null and f.air.instructions.items(.tag)[@intFromEnum(op_inst.?)] == .call_always_tail) {
39593246 try reap(f, inst, &.{un_op});
39603247 _ = try airCall(f, op_inst.?, .always_tail);
3961 } else if (ret_ctype.index != .void) {
3248 } else if (ret_ty.hasRuntimeBits(zcu)) {
39623249 const operand = try f.resolveInst(un_op);
39633250 try reap(f, inst, &.{un_op});
3964 var deref = is_ptr;
3965 const is_array = lowersToArray(ret_ty, zcu);
3966 const ret_val = if (is_array) ret_val: {
3967 const array_local = try f.allocAlignedLocal(inst, .{
3968 .ctype = ret_ctype,
3969 .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(zcu)),
3970 });
3971 try w.writeAll("memcpy(");
3972 try f.writeCValueMember(w, array_local, .{ .identifier = "array" });
3973 try w.writeAll(", ");
3974 if (deref)
3975 try f.writeCValueDeref(w, operand)
3976 else
3977 try f.writeCValue(w, operand, .FunctionArgument);
3978 deref = false;
3979 try w.writeAll(", sizeof(");
3980 try f.renderType(w, ret_ty);
3981 try w.writeAll("));");
3982 try f.object.newline();
3983 break :ret_val array_local;
3984 } else operand;
39853251
39863252 try w.writeAll("return ");
3987 if (deref)
3988 try f.writeCValueDeref(w, ret_val)
3989 else
3990 try f.writeCValue(w, ret_val, .Other);
3991 try w.writeAll(";\n");
3992 if (is_array) {
3993 try freeLocal(f, inst, ret_val.new_local, null);
3253 if (is_ptr) {
3254 try f.writeCValueDeref(w, operand);
3255 } else switch (operand) {
3256 // Instead of 'return &local', emit 'return undefined'.
3257 .local_ref => try f.dg.renderUndefValue(w, ret_ty, .other),
3258 else => try f.writeCValue(w, operand, .other),
39943259 }
3260 try w.writeAll(";\n");
39953261 } else {
39963262 try reap(f, inst, &.{un_op});
39973263 // Not even allowed to return void in a naked function.
3998 if (!f.object.dg.is_naked_fn) try w.writeAll("return;\n");
3264 if (!f.dg.is_naked_fn) try w.writeAll("return;\n");
39993265 }
40003266}
40013267
40023268fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
4003 const pt = f.object.dg.pt;
3269 const pt = f.dg.pt;
40043270 const zcu = pt.zcu;
40053271 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
40063272
......@@ -4012,23 +3278,26 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue {
40123278 const operand_ty = f.typeOf(ty_op.operand);
40133279 const scalar_ty = operand_ty.scalarType(zcu);
40143280
4015 if (f.object.dg.intCastIsNoop(inst_scalar_ty, scalar_ty)) return f.moveCValue(inst, inst_ty, operand);
3281 // `intCastIsNoop` doesn't apply to vectors because every vector lowers to a different C struct.
3282 if (inst_ty.zigTypeTag(zcu) != .vector and f.dg.intCastIsNoop(inst_scalar_ty, scalar_ty)) {
3283 return f.moveCValue(inst, inst_ty, operand);
3284 }
40163285
4017 const w = &f.object.code.writer;
3286 const w = &f.code.writer;
40183287 const local = try f.allocLocal(inst, inst_ty);
40193288 const v = try Vectorize.start(f, inst, w, operand_ty);
4020 const a = try Assignment.start(f, w, try f.ctypeFromType(scalar_ty, .complete));
4021 try f.writeCValue(w, local, .Other);
3289 try f.writeCValue(w, local, .other);
40223290 try v.elem(f, w);
4023 try a.assign(f, w);
4024 try f.renderIntCast(w, inst_scalar_ty, operand, v, scalar_ty, .Other);
4025 try a.end(f, w);
3291 try w.writeAll(" = ");
3292 try f.renderIntCast(w, inst_scalar_ty, operand, v, scalar_ty, .other);
3293 try w.writeByte(';');
3294 try f.newline();
40263295 try v.end(f, inst, w);
40273296 return local;
40283297}
40293298
40303299fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
4031 const pt = f.object.dg.pt;
3300 const pt = f.dg.pt;
40323301 const zcu = pt.zcu;
40333302 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
40343303
......@@ -4050,13 +3319,12 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
40503319 const need_mask = dest_bits < 8 or !std.math.isPowerOfTwo(dest_bits);
40513320 if (!need_cast and !need_lo and !need_mask) return f.moveCValue(inst, inst_ty, operand);
40523321
4053 const w = &f.object.code.writer;
3322 const w = &f.code.writer;
40543323 const local = try f.allocLocal(inst, inst_ty);
40553324 const v = try Vectorize.start(f, inst, w, operand_ty);
4056 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_scalar_ty, .complete));
4057 try f.writeCValue(w, local, .Other);
3325 try f.writeCValue(w, local, .other);
40583326 try v.elem(f, w);
4059 try a.assign(f, w);
3327 try w.writeAll(" = ");
40603328 if (need_cast) {
40613329 try w.writeByte('(');
40623330 try f.renderType(w, inst_scalar_ty);
......@@ -4064,18 +3332,18 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
40643332 }
40653333 if (need_lo) {
40663334 try w.writeAll("zig_lo_");
4067 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
3335 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
40683336 try w.writeByte('(');
40693337 }
40703338 if (!need_mask) {
4071 try f.writeCValue(w, operand, .Other);
3339 try f.writeCValue(w, operand, .other);
40723340 try v.elem(f, w);
40733341 } else switch (dest_int_info.signedness) {
40743342 .unsigned => {
40753343 try w.writeAll("zig_and_");
4076 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
3344 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
40773345 try w.writeByte('(');
4078 try f.writeCValue(w, operand, .FunctionArgument);
3346 try f.writeCValue(w, operand, .other);
40793347 try v.elem(f, w);
40803348 try w.print(", {f})", .{
40813349 try f.fmtIntLiteralHex(try inst_scalar_ty.maxIntScalar(pt, scalar_ty)),
......@@ -4087,7 +3355,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
40873355 const shift_val = try pt.intValue(.u8, c_bits - dest_bits);
40883356
40893357 try w.writeAll("zig_shr_");
4090 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
3358 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
40913359 if (c_bits == 128) {
40923360 try w.print("(zig_bitCast_i{d}(", .{c_bits});
40933361 } else {
......@@ -4099,7 +3367,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
40993367 } else {
41003368 try w.print("(uint{d}_t)", .{c_bits});
41013369 }
4102 try f.writeCValue(w, operand, .FunctionArgument);
3370 try f.writeCValue(w, operand, .other);
41033371 try v.elem(f, w);
41043372 if (c_bits == 128) try w.writeByte(')');
41053373 try w.print(", {f})", .{try f.fmtIntLiteralDec(shift_val)});
......@@ -4108,13 +3376,14 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
41083376 },
41093377 }
41103378 if (need_lo) try w.writeByte(')');
4111 try a.end(f, w);
3379 try w.writeByte(';');
3380 try f.newline();
41123381 try v.end(f, inst, w);
41133382 return local;
41143383}
41153384
41163385fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
4117 const pt = f.object.dg.pt;
3386 const pt = f.dg.pt;
41183387 const zcu = pt.zcu;
41193388 // *a = b;
41203389 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
......@@ -4132,7 +3401,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
41323401
41333402 const val_is_undef = if (try f.air.value(bin_op.rhs, pt)) |v| v.isUndef(zcu) else false;
41343403
4135 const w = &f.object.code.writer;
3404 const w = &f.code.writer;
41363405 if (val_is_undef) {
41373406 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
41383407 if (safety and ptr_info.packed_offset.host_size == 0) {
......@@ -4152,11 +3421,11 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
41523421 },
41533422 };
41543423 try w.writeAll("memset(");
4155 try f.writeCValue(w, ptr_val, .FunctionArgument);
3424 try f.writeCValue(w, ptr_val, .other);
41563425 try w.print(", {s}, sizeof(", .{byte_str});
41573426 try f.renderType(w, .fromInterned(ptr_info.child));
41583427 try w.writeAll("));");
4159 try f.object.newline();
3428 try f.newline();
41603429 }
41613430 return .none;
41623431 }
......@@ -4165,46 +3434,29 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
41653434 ptr_info.flags.alignment.order(src_ty.abiAlignment(zcu)).compare(.gte)
41663435 else
41673436 true;
4168 const is_array = lowersToArray(.fromInterned(ptr_info.child), zcu);
4169 const need_memcpy = !is_aligned or is_array;
41703437
41713438 const src_val = try f.resolveInst(bin_op.rhs);
41723439 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
41733440
4174 const src_scalar_ctype = try f.ctypeFromType(src_ty.scalarType(zcu), .complete);
4175 if (need_memcpy) {
4176 // For this memcpy to safely work we need the rhs to have the same
4177 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
4178 assert(src_ty.eql(.fromInterned(ptr_info.child), zcu));
4179
4180 // If the source is a constant, writeCValue will emit a brace initialization
4181 // so work around this by initializing into new local.
4182 // TODO this should be done by manually initializing elements of the dest array
4183 const array_src = if (src_val == .constant) blk: {
4184 const new_local = try f.allocLocal(inst, src_ty);
4185 try f.writeCValue(w, new_local, .Other);
4186 try w.writeAll(" = ");
4187 try f.writeCValue(w, src_val, .Other);
4188 try w.writeByte(';');
4189 try f.object.newline();
4190
4191 break :blk new_local;
4192 } else src_val;
3441 if (!is_aligned) {
3442 // For this memcpy to safely work we need the rhs to have the same
3443 // underlying type as the lhs (i.e. they must both be arrays of the same underlying type).
3444 assert(src_ty.eql(.fromInterned(ptr_info.child), zcu));
41933445
41943446 const v = try Vectorize.start(f, inst, w, ptr_ty);
41953447 try w.writeAll("memcpy((char *)");
4196 try f.writeCValue(w, ptr_val, .FunctionArgument);
3448 try f.writeCValue(w, ptr_val, .other);
41973449 try v.elem(f, w);
4198 try w.writeAll(", ");
4199 if (!is_array) try w.writeByte('&');
4200 try f.writeCValue(w, array_src, .FunctionArgument);
3450 try w.writeAll(", &");
3451 switch (src_val) {
3452 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
3453 else => try f.writeCValue(w, src_val, .other),
3454 }
42013455 try v.elem(f, w);
42023456 try w.writeAll(", sizeof(");
42033457 try f.renderType(w, src_ty);
4204 try w.writeAll("))");
4205 try f.freeCValue(inst, array_src);
4206 try w.writeByte(';');
4207 try f.object.newline();
3458 try w.writeAll("));");
3459 try f.newline();
42083460 try v.end(f, inst, w);
42093461 } else {
42103462 switch (ptr_val) {
......@@ -4216,20 +3468,20 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
42163468 else => {},
42173469 }
42183470 const v = try Vectorize.start(f, inst, w, ptr_ty);
4219 const a = try Assignment.start(f, w, src_scalar_ctype);
42203471 try f.writeCValueDeref(w, ptr_val);
42213472 try v.elem(f, w);
4222 try a.assign(f, w);
4223 try f.writeCValue(w, src_val, .Other);
3473 try w.writeAll(" = ");
3474 try f.writeCValue(w, src_val, .other);
42243475 try v.elem(f, w);
4225 try a.end(f, w);
3476 try w.writeByte(';');
3477 try f.newline();
42263478 try v.end(f, inst, w);
42273479 }
42283480 return .none;
42293481}
42303482
42313483fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: BuiltinInfo) !CValue {
4232 const pt = f.object.dg.pt;
3484 const pt = f.dg.pt;
42333485 const zcu = pt.zcu;
42343486 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
42353487 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
......@@ -4242,7 +3494,9 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
42423494 const operand_ty = f.typeOf(bin_op.lhs);
42433495 const scalar_ty = operand_ty.scalarType(zcu);
42443496
4245 const w = &f.object.code.writer;
3497 const ref_arg = lowersToBigInt(scalar_ty, zcu);
3498
3499 const w = &f.code.writer;
42463500 const local = try f.allocLocal(inst, inst_ty);
42473501 const v = try Vectorize.start(f, inst, w, operand_ty);
42483502 try f.writeCValueMember(w, local, .{ .field = 1 });
......@@ -4250,26 +3504,28 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info:
42503504 try w.writeAll(" = zig_");
42513505 try w.writeAll(operation);
42523506 try w.writeAll("o_");
4253 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
3507 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
42543508 try w.writeAll("(&");
42553509 try f.writeCValueMember(w, local, .{ .field = 0 });
42563510 try v.elem(f, w);
42573511 try w.writeAll(", ");
4258 try f.writeCValue(w, lhs, .FunctionArgument);
3512 if (ref_arg) try w.writeByte('&');
3513 try f.writeCValue(w, lhs, .other);
42593514 try v.elem(f, w);
42603515 try w.writeAll(", ");
4261 try f.writeCValue(w, rhs, .FunctionArgument);
3516 if (ref_arg) try w.writeByte('&');
3517 try f.writeCValue(w, rhs, .other);
42623518 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, w);
4263 try f.object.dg.renderBuiltinInfo(w, scalar_ty, info);
3519 try f.dg.renderBuiltinInfo(w, scalar_ty, info);
42643520 try w.writeAll(");");
4265 try f.object.newline();
3521 try f.newline();
42663522 try v.end(f, inst, w);
42673523
42683524 return local;
42693525}
42703526
42713527fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
4272 const pt = f.object.dg.pt;
3528 const pt = f.dg.pt;
42733529 const zcu = pt.zcu;
42743530 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
42753531 const operand_ty = f.typeOf(ty_op.operand);
......@@ -4281,17 +3537,17 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
42813537
42823538 const inst_ty = f.typeOfIndex(inst);
42833539
4284 const w = &f.object.code.writer;
3540 const w = &f.code.writer;
42853541 const local = try f.allocLocal(inst, inst_ty);
42863542 const v = try Vectorize.start(f, inst, w, operand_ty);
4287 try f.writeCValue(w, local, .Other);
3543 try f.writeCValue(w, local, .other);
42883544 try v.elem(f, w);
42893545 try w.writeAll(" = ");
42903546 try w.writeByte('!');
4291 try f.writeCValue(w, op, .Other);
3547 try f.writeCValue(w, op, .other);
42923548 try v.elem(f, w);
42933549 try w.writeByte(';');
4294 try f.object.newline();
3550 try f.newline();
42953551 try v.end(f, inst, w);
42963552
42973553 return local;
......@@ -4304,7 +3560,7 @@ fn airBinOp(
43043560 operation: []const u8,
43053561 info: BuiltinInfo,
43063562) !CValue {
4307 const pt = f.object.dg.pt;
3563 const pt = f.dg.pt;
43083564 const zcu = pt.zcu;
43093565 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
43103566 const operand_ty = f.typeOf(bin_op.lhs);
......@@ -4318,21 +3574,21 @@ fn airBinOp(
43183574
43193575 const inst_ty = f.typeOfIndex(inst);
43203576
4321 const w = &f.object.code.writer;
3577 const w = &f.code.writer;
43223578 const local = try f.allocLocal(inst, inst_ty);
43233579 const v = try Vectorize.start(f, inst, w, operand_ty);
4324 try f.writeCValue(w, local, .Other);
3580 try f.writeCValue(w, local, .other);
43253581 try v.elem(f, w);
43263582 try w.writeAll(" = ");
4327 try f.writeCValue(w, lhs, .Other);
3583 try f.writeCValue(w, lhs, .other);
43283584 try v.elem(f, w);
43293585 try w.writeByte(' ');
43303586 try w.writeAll(operator);
43313587 try w.writeByte(' ');
4332 try f.writeCValue(w, rhs, .Other);
3588 try f.writeCValue(w, rhs, .other);
43333589 try v.elem(f, w);
43343590 try w.writeByte(';');
4335 try f.object.newline();
3591 try f.newline();
43363592 try v.end(f, inst, w);
43373593
43383594 return local;
......@@ -4344,7 +3600,7 @@ fn airCmpOp(
43443600 data: anytype,
43453601 operator: std.math.CompareOperator,
43463602) !CValue {
4347 const pt = f.object.dg.pt;
3603 const pt = f.dg.pt;
43483604 const zcu = pt.zcu;
43493605 const lhs_ty = f.typeOf(data.lhs);
43503606 const scalar_ty = lhs_ty.scalarType(zcu);
......@@ -4369,26 +3625,26 @@ fn airCmpOp(
43693625
43703626 const rhs_ty = f.typeOf(data.rhs);
43713627 const need_cast = lhs_ty.isSinglePointer(zcu) or rhs_ty.isSinglePointer(zcu);
4372 const w = &f.object.code.writer;
3628 const w = &f.code.writer;
43733629 const local = try f.allocLocal(inst, inst_ty);
43743630 const v = try Vectorize.start(f, inst, w, lhs_ty);
4375 const a = try Assignment.start(f, w, try f.ctypeFromType(scalar_ty, .complete));
4376 try f.writeCValue(w, local, .Other);
3631 try f.writeCValue(w, local, .other);
43773632 try v.elem(f, w);
4378 try a.assign(f, w);
3633 try w.writeAll(" = ");
43793634 if (lhs != .undef and lhs.eql(rhs)) try w.writeAll(switch (operator) {
43803635 .lt, .neq, .gt => "false",
43813636 .lte, .eq, .gte => "true",
43823637 }) else {
43833638 if (need_cast) try w.writeAll("(void*)");
4384 try f.writeCValue(w, lhs, .Other);
3639 try f.writeCValue(w, lhs, .other);
43853640 try v.elem(f, w);
43863641 try w.writeAll(compareOperatorC(operator));
43873642 if (need_cast) try w.writeAll("(void*)");
4388 try f.writeCValue(w, rhs, .Other);
3643 try f.writeCValue(w, rhs, .other);
43893644 try v.elem(f, w);
43903645 }
4391 try a.end(f, w);
3646 try w.writeByte(';');
3647 try f.newline();
43923648 try v.end(f, inst, w);
43933649
43943650 return local;
......@@ -4399,9 +3655,8 @@ fn airEquality(
43993655 inst: Air.Inst.Index,
44003656 operator: std.math.CompareOperator,
44013657) !CValue {
4402 const pt = f.object.dg.pt;
3658 const pt = f.dg.pt;
44033659 const zcu = pt.zcu;
4404 const ctype_pool = &f.object.dg.ctype_pool;
44053660 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
44063661
44073662 const operand_ty = f.typeOf(bin_op.lhs);
......@@ -4422,54 +3677,64 @@ fn airEquality(
44223677 const rhs = try f.resolveInst(bin_op.rhs);
44233678 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
44243679
4425 const w = &f.object.code.writer;
3680 if (lhs.eql(rhs)) {
3681 // Avoid emitting a tautological comparison.
3682 return .{ .constant = .makeBool(switch (operator) {
3683 .eq, .lte, .gte => true,
3684 .neq, .lt, .gt => false,
3685 }) };
3686 }
3687
3688 const w = &f.code.writer;
44263689 const local = try f.allocLocal(inst, .bool);
4427 const a = try Assignment.start(f, w, .bool);
4428 try f.writeCValue(w, local, .Other);
4429 try a.assign(f, w);
3690 try f.writeCValue(w, local, .other);
3691 try w.writeAll(" = ");
44303692
4431 const operand_ctype = try f.ctypeFromType(operand_ty, .complete);
4432 if (lhs != .undef and lhs.eql(rhs)) try w.writeAll(switch (operator) {
4433 .lt, .lte, .gte, .gt => unreachable,
4434 .neq => "false",
4435 .eq => "true",
4436 }) else switch (operand_ctype.info(ctype_pool)) {
4437 .basic, .pointer => {
4438 try f.writeCValue(w, lhs, .Other);
4439 try w.writeAll(compareOperatorC(operator));
4440 try f.writeCValue(w, rhs, .Other);
4441 },
4442 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
4443 .aggregate => |aggregate| if (aggregate.fields.len == 2 and
4444 (aggregate.fields.at(0, ctype_pool).name.index == .is_null or
4445 aggregate.fields.at(1, ctype_pool).name.index == .is_null))
4446 {
4447 try f.writeCValueMember(w, lhs, .{ .identifier = "is_null" });
4448 try w.writeAll(" || ");
4449 try f.writeCValueMember(w, rhs, .{ .identifier = "is_null" });
4450 try w.writeAll(" ? ");
4451 try f.writeCValueMember(w, lhs, .{ .identifier = "is_null" });
4452 try w.writeAll(compareOperatorC(operator));
4453 try f.writeCValueMember(w, rhs, .{ .identifier = "is_null" });
4454 try w.writeAll(" : ");
4455 try f.writeCValueMember(w, lhs, .{ .identifier = "payload" });
4456 try w.writeAll(compareOperatorC(operator));
4457 try f.writeCValueMember(w, rhs, .{ .identifier = "payload" });
4458 } else for (0..aggregate.fields.len) |field_index| {
4459 if (field_index > 0) try w.writeAll(switch (operator) {
4460 .lt, .lte, .gte, .gt => unreachable,
4461 .eq => " && ",
4462 .neq => " || ",
4463 });
4464 const field_name: CValue = .{
4465 .ctype_pool_string = aggregate.fields.at(field_index, ctype_pool).name,
4466 };
4467 try f.writeCValueMember(w, lhs, field_name);
4468 try w.writeAll(compareOperatorC(operator));
4469 try f.writeCValueMember(w, rhs, field_name);
3693 switch (operand_ty.zigTypeTag(zcu)) {
3694 .optional => switch (CType.classifyOptional(operand_ty, zcu)) {
3695 .npv_payload => unreachable, // opv optional
3696
3697 .error_set, .ptr_like => {},
3698
3699 .slice_like => unreachable, // equality is not defined on slices
3700
3701 .opv_payload => {
3702 try f.writeCValueMember(w, lhs, .{ .identifier = "is_null" });
3703 try w.writeAll(compareOperatorC(operator));
3704 try f.writeCValueMember(w, rhs, .{ .identifier = "is_null" });
3705 try w.writeByte(';');
3706 try f.newline();
3707 return local;
3708 },
3709
3710 .@"struct" => {
3711 // `lhs.is_null || rhs.is_null ? lhs.is_null == rhs.is_null : lhs.payload == rhs.payload`
3712 try f.writeCValueMember(w, lhs, .{ .identifier = "is_null" });
3713 try w.writeAll(" || ");
3714 try f.writeCValueMember(w, rhs, .{ .identifier = "is_null" });
3715 try w.writeAll(" ? ");
3716 try f.writeCValueMember(w, lhs, .{ .identifier = "is_null" });
3717 try w.writeAll(compareOperatorC(operator));
3718 try f.writeCValueMember(w, rhs, .{ .identifier = "is_null" });
3719 try w.writeAll(" : ");
3720 try f.writeCValueMember(w, lhs, .{ .identifier = "payload" });
3721 try w.writeAll(compareOperatorC(operator));
3722 try f.writeCValueMember(w, rhs, .{ .identifier = "payload" });
3723 try w.writeByte(';');
3724 try f.newline();
3725 return local;
3726 },
44703727 },
3728 .bool, .int, .pointer, .@"enum", .error_set => {},
3729 .@"struct", .@"union" => assert(operand_ty.containerLayout(zcu) == .@"packed"),
3730 else => unreachable,
44713731 }
4472 try a.end(f, w);
3732
3733 try f.writeCValue(w, lhs, .other);
3734 try w.writeAll(compareOperatorC(operator));
3735 try f.writeCValue(w, rhs, .other);
3736 try w.writeByte(';');
3737 try f.newline();
44733738
44743739 return local;
44753740}
......@@ -4480,18 +3745,18 @@ fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue {
44803745 const operand = try f.resolveInst(un_op);
44813746 try reap(f, inst, &.{un_op});
44823747
4483 const w = &f.object.code.writer;
3748 const w = &f.code.writer;
44843749 const local = try f.allocLocal(inst, .bool);
4485 try f.writeCValue(w, local, .Other);
3750 try f.writeCValue(w, local, .other);
44863751 try w.writeAll(" = ");
4487 try f.writeCValue(w, operand, .Other);
3752 try f.writeCValue(w, operand, .other);
44883753 try w.print(" < sizeof({f}) / sizeof(*{0f});", .{fmtIdentSolo("zig_errorName")});
4489 try f.object.newline();
3754 try f.newline();
44903755 return local;
44913756}
44923757
44933758fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
4494 const pt = f.object.dg.pt;
3759 const pt = f.dg.pt;
44953760 const zcu = pt.zcu;
44963761 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
44973762 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
......@@ -4502,40 +3767,36 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue {
45023767
45033768 const inst_ty = f.typeOfIndex(inst);
45043769 const inst_scalar_ty = inst_ty.scalarType(zcu);
4505 const elem_ty = inst_scalar_ty.elemType2(zcu);
4506 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) return f.moveCValue(inst, inst_ty, lhs);
4507 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
3770 const elem_ty = inst_scalar_ty.indexableElem(zcu);
3771 assert(elem_ty.hasRuntimeBits(zcu));
45083772
45093773 const local = try f.allocLocal(inst, inst_ty);
4510 const w = &f.object.code.writer;
3774 const w = &f.code.writer;
45113775 const v = try Vectorize.start(f, inst, w, inst_ty);
4512 const a = try Assignment.start(f, w, inst_scalar_ctype);
4513 try f.writeCValue(w, local, .Other);
3776 try f.writeCValue(w, local, .other);
45143777 try v.elem(f, w);
4515 try a.assign(f, w);
3778 try w.writeAll(" = ");
45163779 // We must convert to and from integer types to prevent UB if the operation
45173780 // results in a NULL pointer, or if LHS is NULL. The operation is only UB
45183781 // if the result is NULL and then dereferenced.
45193782 try w.writeByte('(');
4520 try f.renderCType(w, inst_scalar_ctype);
3783 try f.renderType(w, inst_scalar_ty);
45213784 try w.writeAll(")(((uintptr_t)");
4522 try f.writeCValue(w, lhs, .Other);
3785 try f.writeCValue(w, lhs, .other);
45233786 try v.elem(f, w);
4524 try w.writeAll(") ");
4525 try w.writeByte(operator);
4526 try w.writeAll(" (");
4527 try f.writeCValue(w, rhs, .Other);
3787 try w.print(") {c} (", .{operator});
3788 try f.writeCValue(w, rhs, .other);
45283789 try v.elem(f, w);
45293790 try w.writeAll("*sizeof(");
45303791 try f.renderType(w, elem_ty);
4531 try w.writeAll(")))");
4532 try a.end(f, w);
3792 try w.writeAll(")));");
3793 try f.newline();
45333794 try v.end(f, inst, w);
45343795 return local;
45353796}
45363797
45373798fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []const u8) !CValue {
4538 const pt = f.object.dg.pt;
3799 const pt = f.dg.pt;
45393800 const zcu = pt.zcu;
45403801 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
45413802
......@@ -4549,36 +3810,34 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
45493810 const rhs = try f.resolveInst(bin_op.rhs);
45503811 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
45513812
4552 const w = &f.object.code.writer;
3813 const w = &f.code.writer;
45533814 const local = try f.allocLocal(inst, inst_ty);
45543815 const v = try Vectorize.start(f, inst, w, inst_ty);
4555 try f.writeCValue(w, local, .Other);
3816 try f.writeCValue(w, local, .other);
45563817 try v.elem(f, w);
45573818 // (lhs <> rhs) ? lhs : rhs
45583819 try w.writeAll(" = (");
4559 try f.writeCValue(w, lhs, .Other);
3820 try f.writeCValue(w, lhs, .other);
45603821 try v.elem(f, w);
45613822 try w.writeByte(' ');
45623823 try w.writeByte(operator);
45633824 try w.writeByte(' ');
4564 try f.writeCValue(w, rhs, .Other);
3825 try f.writeCValue(w, rhs, .other);
45653826 try v.elem(f, w);
45663827 try w.writeAll(") ? ");
4567 try f.writeCValue(w, lhs, .Other);
3828 try f.writeCValue(w, lhs, .other);
45683829 try v.elem(f, w);
45693830 try w.writeAll(" : ");
4570 try f.writeCValue(w, rhs, .Other);
3831 try f.writeCValue(w, rhs, .other);
45713832 try v.elem(f, w);
45723833 try w.writeByte(';');
4573 try f.object.newline();
3834 try f.newline();
45743835 try v.end(f, inst, w);
45753836
45763837 return local;
45773838}
45783839
45793840fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
4580 const pt = f.object.dg.pt;
4581 const zcu = pt.zcu;
45823841 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
45833842 const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
45843843
......@@ -4587,24 +3846,22 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
45873846 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
45883847
45893848 const inst_ty = f.typeOfIndex(inst);
4590 const ptr_ty = inst_ty.slicePtrFieldType(zcu);
45913849
4592 const w = &f.object.code.writer;
3850 const w = &f.code.writer;
45933851 const local = try f.allocLocal(inst, inst_ty);
4594 {
4595 const a = try Assignment.start(f, w, try f.ctypeFromType(ptr_ty, .complete));
4596 try f.writeCValueMember(w, local, .{ .identifier = "ptr" });
4597 try a.assign(f, w);
4598 try f.writeCValue(w, ptr, .Other);
4599 try a.end(f, w);
4600 }
4601 {
4602 const a = try Assignment.start(f, w, .usize);
4603 try f.writeCValueMember(w, local, .{ .identifier = "len" });
4604 try a.assign(f, w);
4605 try f.writeCValue(w, len, .Other);
4606 try a.end(f, w);
4607 }
3852
3853 try f.writeCValueMember(w, local, .{ .identifier = "ptr" });
3854 try w.writeAll(" = ");
3855 try f.writeCValue(w, ptr, .other);
3856 try w.writeByte(';');
3857 try f.newline();
3858
3859 try f.writeCValueMember(w, local, .{ .identifier = "len" });
3860 try w.writeAll(" = ");
3861 try f.writeCValue(w, len, .other);
3862 try w.writeByte(';');
3863 try f.newline();
3864
46083865 return local;
46093866}
46103867
......@@ -4613,14 +3870,14 @@ fn airCall(
46133870 inst: Air.Inst.Index,
46143871 modifier: std.builtin.CallModifier,
46153872) !CValue {
4616 const pt = f.object.dg.pt;
3873 const pt = f.dg.pt;
46173874 const zcu = pt.zcu;
46183875 const ip = &zcu.intern_pool;
46193876 // Not even allowed to call panic in a naked function.
4620 if (f.object.dg.is_naked_fn) return .none;
3877 if (f.dg.is_naked_fn) return .none;
46213878
4622 const gpa = f.object.dg.gpa;
4623 const w = &f.object.code.writer;
3879 const gpa = f.dg.gpa;
3880 const w = &f.code.writer;
46243881
46253882 const call = f.air.unwrapCall(inst);
46263883 const args = call.args;
......@@ -4629,27 +3886,11 @@ fn airCall(
46293886 defer gpa.free(resolved_args);
46303887 for (resolved_args, args) |*resolved_arg, arg| {
46313888 const arg_ty = f.typeOf(arg);
4632 const arg_ctype = try f.ctypeFromType(arg_ty, .parameter);
4633 if (arg_ctype.index == .void) {
3889 if (!arg_ty.hasRuntimeBits(zcu)) {
46343890 resolved_arg.* = .none;
46353891 continue;
46363892 }
46373893 resolved_arg.* = try f.resolveInst(arg);
4638 if (!arg_ctype.eql(try f.ctypeFromType(arg_ty, .complete))) {
4639 const array_local = try f.allocAlignedLocal(inst, .{
4640 .ctype = arg_ctype,
4641 .alignas = CType.AlignAs.fromAbiAlignment(arg_ty.abiAlignment(zcu)),
4642 });
4643 try w.writeAll("memcpy(");
4644 try f.writeCValueMember(w, array_local, .{ .identifier = "array" });
4645 try w.writeAll(", ");
4646 try f.writeCValue(w, resolved_arg.*, .FunctionArgument);
4647 try w.writeAll(", sizeof(");
4648 try f.renderCType(w, arg_ctype);
4649 try w.writeAll("));");
4650 try f.object.newline();
4651 resolved_arg.* = array_local;
4652 }
46533894 }
46543895
46553896 const callee = try f.resolveInst(call.callee);
......@@ -4668,28 +3909,22 @@ fn airCall(
46683909 };
46693910 const fn_info = zcu.typeToFunc(if (callee_is_ptr) callee_ty.childType(zcu) else callee_ty).?;
46703911 const ret_ty: Type = .fromInterned(fn_info.return_type);
4671 const ret_ctype: CType = if (ret_ty.isNoReturn(zcu))
4672 .void
4673 else
4674 try f.ctypeFromType(ret_ty, .parameter);
46753912
46763913 const result_local = result: {
46773914 if (modifier == .always_tail) {
46783915 try w.writeAll("zig_always_tail return ");
46793916 break :result .none;
4680 } else if (ret_ctype.index == .void) {
3917 } else if (!ret_ty.hasRuntimeBits(zcu)) {
46813918 break :result .none;
46823919 } else if (f.liveness.isUnused(inst)) {
4683 try w.writeByte('(');
4684 try f.renderCType(w, .void);
4685 try w.writeByte(')');
3920 try w.writeAll("(void)");
46863921 break :result .none;
46873922 } else {
46883923 const local = try f.allocAlignedLocal(inst, .{
4689 .ctype = ret_ctype,
4690 .alignas = CType.AlignAs.fromAbiAlignment(ret_ty.abiAlignment(zcu)),
3924 .type = ret_ty,
3925 .alignment = .none,
46913926 });
4692 try f.writeCValue(w, local, .Other);
3927 try f.writeCValue(w, local, .other);
46933928 try w.writeAll(" = ");
46943929 break :result local;
46953930 }
......@@ -4716,8 +3951,19 @@ fn airCall(
47163951 if (!callee_is_ptr) try w.writeByte('&');
47173952 }
47183953 switch (modifier) {
4719 .auto, .always_tail => try f.object.dg.renderNavName(w, fn_nav),
4720 inline .never_tail, .never_inline => |m| try w.writeAll(try f.getLazyFnName(@unionInit(LazyFnKey, @tagName(m), fn_nav))),
3954 .auto, .always_tail => try renderNavName(w, fn_nav, ip),
3955 .never_tail => {
3956 try f.need_never_tail_funcs.put(gpa, fn_nav, {});
3957 try w.print("zig_never_tail_{f}__{d}", .{
3958 fmtIdentUnsolo(ip.getNav(fn_nav).name.toSlice(ip)), @intFromEnum(fn_nav),
3959 });
3960 },
3961 .never_inline => {
3962 try f.need_never_inline_funcs.put(gpa, fn_nav, {});
3963 try w.print("zig_never_inline_{f}__{d}", .{
3964 fmtIdentUnsolo(ip.getNav(fn_nav).name.toSlice(ip)), @intFromEnum(fn_nav),
3965 });
3966 },
47213967 else => unreachable,
47223968 }
47233969 if (need_cast) try w.writeByte(')');
......@@ -4730,7 +3976,7 @@ fn airCall(
47303976 else => unreachable,
47313977 }
47323978 // Fall back to function pointer call.
4733 try f.writeCValue(w, callee, .Other);
3979 try f.writeCValue(w, callee, .other);
47343980 }
47353981
47363982 try w.writeByte('(');
......@@ -4739,38 +3985,20 @@ fn airCall(
47393985 if (resolved_arg == .none) continue;
47403986 if (need_comma) try w.writeAll(", ");
47413987 need_comma = true;
4742 try f.writeCValue(w, resolved_arg, .FunctionArgument);
4743 try f.freeCValue(inst, resolved_arg);
3988 try f.writeCValue(w, resolved_arg, .other);
47443989 }
47453990 try w.writeAll(");");
47463991 switch (modifier) {
47473992 .always_tail => try w.writeByte('\n'),
4748 else => try f.object.newline(),
3993 else => try f.newline(),
47493994 }
47503995
4751 const result = result: {
4752 if (result_local == .none or !lowersToArray(ret_ty, zcu))
4753 break :result result_local;
4754
4755 const array_local = try f.allocLocal(inst, ret_ty);
4756 try w.writeAll("memcpy(");
4757 try f.writeCValue(w, array_local, .FunctionArgument);
4758 try w.writeAll(", ");
4759 try f.writeCValueMember(w, result_local, .{ .identifier = "array" });
4760 try w.writeAll(", sizeof(");
4761 try f.renderType(w, ret_ty);
4762 try w.writeAll("));");
4763 try f.object.newline();
4764 try freeLocal(f, inst, result_local.new_local, null);
4765 break :result array_local;
4766 };
4767
4768 return result;
3996 return result_local;
47693997}
47703998
47713999fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
47724000 const dbg_stmt = f.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
4773 const w = &f.object.code.writer;
4001 const w = &f.code.writer;
47744002 // TODO re-evaluate whether to emit these or not. If we naively emit
47754003 // these directives, the output file will report bogus line numbers because
47764004 // every newline after the #line directive adds one to the line.
......@@ -4779,32 +4007,32 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
47794007 // newlines until the next dbg_stmt occurs.
47804008 // Perhaps an additional compilation option is in order?
47814009 //try w.print("#line {d}", .{dbg_stmt.line + 1});
4782 //try f.object.newline();
4010 //try f.newline();
47834011 try w.print("/* file:{d}:{d} */", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });
4784 try f.object.newline();
4012 try f.newline();
47854013 return .none;
47864014}
47874015
47884016fn airDbgEmptyStmt(f: *Function, _: Air.Inst.Index) !CValue {
4789 try f.object.code.writer.writeAll("(void)0;");
4790 try f.object.newline();
4017 try f.code.writer.writeAll("(void)0;");
4018 try f.newline();
47914019 return .none;
47924020}
47934021
47944022fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4795 const pt = f.object.dg.pt;
4023 const pt = f.dg.pt;
47964024 const zcu = pt.zcu;
47974025 const ip = &zcu.intern_pool;
47984026 const block = f.air.unwrapDbgBlock(inst);
47994027 const owner_nav = ip.getNav(zcu.funcInfo(block.func).owner_nav);
4800 const w = &f.object.code.writer;
4028 const w = &f.code.writer;
48014029 try w.print("/* inline:{f} */", .{owner_nav.fqn.fmt(&zcu.intern_pool)});
4802 try f.object.newline();
4030 try f.newline();
48034031 return lowerBlock(f, inst, block.body);
48044032}
48054033
48064034fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
4807 const pt = f.object.dg.pt;
4035 const pt = f.dg.pt;
48084036 const zcu = pt.zcu;
48094037 const tag = f.air.instructions.items(.tag)[@intFromEnum(inst)];
48104038 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
......@@ -4813,9 +4041,9 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
48134041 if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand);
48144042
48154043 try reap(f, inst, &.{pl_op.operand});
4816 const w = &f.object.code.writer;
4044 const w = &f.code.writer;
48174045 try w.print("/* {s}:{s} */", .{ @tagName(tag), name.toSlice(f.air) });
4818 try f.object.newline();
4046 try f.newline();
48194047 return .none;
48204048}
48214049
......@@ -4825,21 +4053,21 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
48254053}
48264054
48274055fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index) !CValue {
4828 const pt = f.object.dg.pt;
4056 const pt = f.dg.pt;
48294057 const zcu = pt.zcu;
48304058 const liveness_block = f.liveness.getBlock(inst);
48314059
48324060 const block_id = f.next_block_index;
48334061 f.next_block_index += 1;
4834 const w = &f.object.code.writer;
4062 const w = &f.code.writer;
48354063
48364064 const inst_ty = f.typeOfIndex(inst);
4837 const result = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu) and !f.liveness.isUnused(inst))
4065 const result = if (inst_ty.hasRuntimeBits(zcu) and !f.liveness.isUnused(inst))
48384066 try f.allocLocal(inst, inst_ty)
48394067 else
48404068 .none;
48414069
4842 try f.blocks.putNoClobber(f.object.dg.gpa, inst, .{
4070 try f.blocks.putNoClobber(f.dg.gpa, inst, .{
48434071 .block_id = block_id,
48444072 .result = result,
48454073 });
......@@ -4854,23 +4082,23 @@ fn lowerBlock(f: *Function, inst: Air.Inst.Index, body: []const Air.Inst.Index)
48544082 }
48554083
48564084 // noreturn blocks have no `br` instructions reaching them, so we don't want a label
4857 if (f.object.dg.is_naked_fn) {
4858 if (f.object.dg.expected_block) |expected_block| {
4085 if (f.dg.is_naked_fn) {
4086 if (f.dg.expected_block) |expected_block| {
48594087 if (block_id != expected_block)
48604088 return f.fail("runtime code not allowed in naked function", .{});
4861 f.object.dg.expected_block = null;
4089 f.dg.expected_block = null;
48624090 }
48634091 } else if (!f.typeOfIndex(inst).isNoReturn(zcu)) {
48644092 // label must be followed by an expression, include an empty one.
48654093 try w.print("\nzig_block_{d}:;", .{block_id});
4866 try f.object.newline();
4094 try f.newline();
48674095 }
48684096
48694097 return result;
48704098}
48714099
48724100fn airTry(f: *Function, inst: Air.Inst.Index) !CValue {
4873 const pt = f.object.dg.pt;
4101 const pt = f.dg.pt;
48744102 const unwrapped_try = f.air.unwrapTry(inst);
48754103 const body = unwrapped_try.else_body;
48764104 const err_union_ty = f.air.typeOf(unwrapped_try.error_union, &pt.zcu.intern_pool);
......@@ -4878,7 +4106,7 @@ fn airTry(f: *Function, inst: Air.Inst.Index) !CValue {
48784106}
48794107
48804108fn airTryPtr(f: *Function, inst: Air.Inst.Index) !CValue {
4881 const pt = f.object.dg.pt;
4109 const pt = f.dg.pt;
48824110 const unwrapped_try = f.air.unwrapTryPtr(inst);
48834111 const body = unwrapped_try.else_body;
48844112 const err_union_ty = f.air.typeOf(unwrapped_try.error_union_ptr, &pt.zcu.intern_pool).childType(pt.zcu);
......@@ -4893,46 +4121,38 @@ fn lowerTry(
48934121 err_union_ty: Type,
48944122 is_ptr: bool,
48954123) !CValue {
4896 const pt = f.object.dg.pt;
4124 const pt = f.dg.pt;
48974125 const zcu = pt.zcu;
48984126 const err_union = try f.resolveInst(operand);
48994127 const inst_ty = f.typeOfIndex(inst);
49004128 const liveness_condbr = f.liveness.getCondBr(inst);
4901 const w = &f.object.code.writer;
4129 const w = &f.code.writer;
49024130 const payload_ty = err_union_ty.errorUnionPayload(zcu);
4903 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(zcu);
49044131
4905 if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {
4906 try w.writeAll("if (");
4907 if (!payload_has_bits) {
4908 if (is_ptr)
4909 try f.writeCValueDeref(w, err_union)
4910 else
4911 try f.writeCValue(w, err_union, .Other);
4912 } else {
4913 // Reap the operand so that it can be reused inside genBody.
4914 // Remember we must avoid calling reap() twice for the same operand
4915 // in this function.
4916 try reap(f, inst, &.{operand});
4917 if (is_ptr)
4918 try f.writeCValueDerefMember(w, err_union, .{ .identifier = "error" })
4919 else
4920 try f.writeCValueMember(w, err_union, .{ .identifier = "error" });
4921 }
4922 try w.writeAll(") ");
4132 try w.writeAll("if (");
49234133
4924 try genBodyResolveState(f, inst, liveness_condbr.else_deaths, body, false);
4925 try f.object.newline();
4926 if (f.object.dg.expected_block) |_|
4927 return f.fail("runtime code not allowed in naked function", .{});
4928 }
4134 // Reap the operand so that it can be reused inside genBody.
4135 // Remember we must avoid calling reap() twice for the same operand
4136 // in this function.
4137 try reap(f, inst, &.{operand});
4138 if (is_ptr)
4139 try f.writeCValueDerefMember(w, err_union, .{ .identifier = "error" })
4140 else
4141 try f.writeCValueMember(w, err_union, .{ .identifier = "error" });
4142
4143 try w.writeAll(") ");
4144
4145 try genBodyResolveState(f, inst, liveness_condbr.else_deaths, body, false);
4146 try f.newline();
4147 if (f.dg.expected_block) |_|
4148 return f.fail("runtime code not allowed in naked function", .{});
49294149
49304150 // Now we have the "then branch" (in terms of the liveness data); process any deaths.
49314151 for (liveness_condbr.then_deaths) |death| {
49324152 try die(f, inst, death.toRef());
49334153 }
49344154
4935 if (!payload_has_bits) {
4155 if (!payload_ty.hasRuntimeBits(zcu)) {
49364156 if (!is_ptr) {
49374157 return .none;
49384158 } else {
......@@ -4945,14 +4165,14 @@ fn lowerTry(
49454165 if (f.liveness.isUnused(inst)) return .none;
49464166
49474167 const local = try f.allocLocal(inst, inst_ty);
4948 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
4949 try f.writeCValue(w, local, .Other);
4950 try a.assign(f, w);
4168 try f.writeCValue(w, local, .other);
4169 try w.writeAll(" = ");
49514170 if (is_ptr) {
49524171 try w.writeByte('&');
49534172 try f.writeCValueDerefMember(w, err_union, .{ .identifier = "payload" });
49544173 } else try f.writeCValueMember(w, err_union, .{ .identifier = "payload" });
4955 try a.end(f, w);
4174 try w.writeByte(';');
4175 try f.newline();
49564176 return local;
49574177}
49584178
......@@ -4960,25 +4180,24 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !void {
49604180 const branch = f.air.instructions.items(.data)[@intFromEnum(inst)].br;
49614181 const block = f.blocks.get(branch.block_inst).?;
49624182 const result = block.result;
4963 const w = &f.object.code.writer;
4183 const w = &f.code.writer;
49644184
4965 if (f.object.dg.is_naked_fn) {
4185 if (f.dg.is_naked_fn) {
49664186 if (result != .none) return f.fail("runtime code not allowed in naked function", .{});
4967 f.object.dg.expected_block = block.block_id;
4187 f.dg.expected_block = block.block_id;
49684188 return;
49694189 }
49704190
49714191 // If result is .none then the value of the block is unused.
49724192 if (result != .none) {
4973 const operand_ty = f.typeOf(branch.operand);
49744193 const operand = try f.resolveInst(branch.operand);
49754194 try reap(f, inst, &.{branch.operand});
49764195
4977 const a = try Assignment.start(f, w, try f.ctypeFromType(operand_ty, .complete));
4978 try f.writeCValue(w, result, .Other);
4979 try a.assign(f, w);
4980 try f.writeCValue(w, operand, .Other);
4981 try a.end(f, w);
4196 try f.writeCValue(w, result, .other);
4197 try w.writeAll(" = ");
4198 try f.writeCValue(w, operand, .other);
4199 try w.writeByte(';');
4200 try f.newline();
49824201 }
49834202
49844203 try w.print("goto zig_block_{d};\n", .{block.block_id});
......@@ -4986,14 +4205,14 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !void {
49864205
49874206fn airRepeat(f: *Function, inst: Air.Inst.Index) !void {
49884207 const repeat = f.air.instructions.items(.data)[@intFromEnum(inst)].repeat;
4989 try f.object.code.writer.print("goto zig_loop_{d};\n", .{@intFromEnum(repeat.loop_inst)});
4208 try f.code.writer.print("goto zig_loop_{d};\n", .{@intFromEnum(repeat.loop_inst)});
49904209}
49914210
49924211fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void {
4993 const pt = f.object.dg.pt;
4212 const pt = f.dg.pt;
49944213 const zcu = pt.zcu;
49954214 const br = f.air.instructions.items(.data)[@intFromEnum(inst)].br;
4996 const w = &f.object.code.writer;
4215 const w = &f.code.writer;
49974216
49984217 if (try f.air.value(br.operand, pt)) |cond_val| {
49994218 // Comptime-known dispatch. Iterate the cases to find the correct
......@@ -5022,11 +4241,11 @@ fn airSwitchDispatch(f: *Function, inst: Air.Inst.Index) !void {
50224241 // Runtime-known dispatch. Set the switch condition, and branch back.
50234242 const cond = try f.resolveInst(br.operand);
50244243 const cond_local = f.loop_switch_conds.get(br.block_inst).?;
5025 try f.writeCValue(w, .{ .local = cond_local }, .Other);
4244 try f.writeCValue(w, .{ .local = cond_local }, .other);
50264245 try w.writeAll(" = ");
5027 try f.writeCValue(w, cond, .Other);
4246 try f.writeCValue(w, cond, .other);
50284247 try w.writeByte(';');
5029 try f.object.newline();
4248 try f.newline();
50304249 try w.print("goto zig_switch_{d}_loop;\n", .{@intFromEnum(br.block_inst)});
50314250}
50324251
......@@ -5043,11 +4262,10 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
50434262}
50444263
50454264fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CValue {
5046 const pt = f.object.dg.pt;
4265 const pt = f.dg.pt;
50474266 const zcu = pt.zcu;
5048 const target = &f.object.dg.mod.resolved_target.result;
5049 const ctype_pool = &f.object.dg.ctype_pool;
5050 const w = &f.object.code.writer;
4267 const target = &f.dg.mod.resolved_target.result;
4268 const w = &f.code.writer;
50514269
50524270 if (operand_ty.isAbiInt(zcu) and dest_ty.isAbiInt(zcu)) {
50534271 const src_info = dest_ty.intInfo(zcu);
......@@ -5058,26 +4276,16 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
50584276
50594277 if (dest_ty.isPtrAtRuntime(zcu) or operand_ty.isPtrAtRuntime(zcu)) {
50604278 const local = try f.allocLocal(null, dest_ty);
5061 try f.writeCValue(w, local, .Other);
4279 try f.writeCValue(w, local, .other);
50624280 try w.writeAll(" = (");
50634281 try f.renderType(w, dest_ty);
50644282 try w.writeByte(')');
5065 try f.writeCValue(w, operand, .Other);
4283 try f.writeCValue(w, operand, .other);
50664284 try w.writeByte(';');
5067 try f.object.newline();
4285 try f.newline();
50684286 return local;
50694287 }
50704288
5071 const operand_lval = if (operand == .constant) blk: {
5072 const operand_local = try f.allocLocal(null, operand_ty);
5073 try f.writeCValue(w, operand_local, .Other);
5074 try w.writeAll(" = ");
5075 try f.writeCValue(w, operand, .Other);
5076 try w.writeByte(';');
5077 try f.object.newline();
5078 break :blk operand_local;
5079 } else operand;
5080
50814289 const local = try f.allocLocal(null, dest_ty);
50824290 // On big-endian targets, copying ABI integers with padding bits is awkward, because the padding bits are at the low bytes of the value.
50834291 // We need to offset the source or destination pointer appropriately and copy the right number of bytes.
......@@ -5085,141 +4293,134 @@ fn bitcast(f: *Function, dest_ty: Type, operand: CValue, operand_ty: Type) !CVal
50854293 // e.g. [10]u8 -> u80. We need to offset the destination so that we copy to the least significant bits of the integer.
50864294 const offset = dest_ty.abiSize(zcu) - operand_ty.abiSize(zcu);
50874295 try w.writeAll("memcpy((char *)&");
5088 try f.writeCValue(w, local, .Other);
4296 try f.writeCValue(w, local, .other);
50894297 try w.print(" + {d}, &", .{offset});
5090 try f.writeCValue(w, operand_lval, .Other);
4298 switch (operand) {
4299 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
4300 else => try f.writeCValue(w, operand, .other),
4301 }
50914302 try w.print(", {d});", .{operand_ty.abiSize(zcu)});
50924303 } else if (target.cpu.arch.endian() == .big and operand_ty.isAbiInt(zcu) and !dest_ty.isAbiInt(zcu)) {
50934304 // e.g. u80 -> [10]u8. We need to offset the source so that we copy from the least significant bits of the integer.
50944305 const offset = operand_ty.abiSize(zcu) - dest_ty.abiSize(zcu);
50954306 try w.writeAll("memcpy(&");
5096 try f.writeCValue(w, local, .Other);
4307 try f.writeCValue(w, local, .other);
50974308 try w.writeAll(", (const char *)&");
5098 try f.writeCValue(w, operand_lval, .Other);
4309 switch (operand) {
4310 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
4311 else => try f.writeCValue(w, operand, .other),
4312 }
50994313 try w.print(" + {d}, {d});", .{ offset, dest_ty.abiSize(zcu) });
51004314 } else {
51014315 try w.writeAll("memcpy(&");
5102 try f.writeCValue(w, local, .Other);
4316 try f.writeCValue(w, local, .other);
51034317 try w.writeAll(", &");
5104 try f.writeCValue(w, operand_lval, .Other);
4318 switch (operand) {
4319 .constant => |val| try f.dg.renderValueAsLvalue(w, val),
4320 else => try f.writeCValue(w, operand, .other),
4321 }
51054322 try w.print(", {d});", .{@min(dest_ty.abiSize(zcu), operand_ty.abiSize(zcu))});
51064323 }
51074324
5108 try f.object.newline();
4325 try f.newline();
51094326
51104327 // Ensure padding bits have the expected value.
51114328 if (dest_ty.isAbiInt(zcu)) {
5112 const dest_ctype = try f.ctypeFromType(dest_ty, .complete);
5113 const dest_info = dest_ty.intInfo(zcu);
5114 var bits: u16 = dest_info.bits;
5115 var wrap_ctype: ?CType = null;
5116 var need_bitcasts = false;
5117
5118 try f.writeCValue(w, local, .Other);
5119 switch (dest_ctype.info(ctype_pool)) {
5120 else => {},
5121 .array => |array_info| {
5122 try w.print("[{d}]", .{switch (target.cpu.arch.endian()) {
5123 .little => array_info.len - 1,
5124 .big => 0,
5125 }});
5126 wrap_ctype = array_info.elem_ctype.toSignedness(dest_info.signedness);
5127 need_bitcasts = wrap_ctype.?.index == .zig_i128;
5128 bits -= 1;
5129 bits %= @as(u16, @intCast(f.byteSize(array_info.elem_ctype) * 8));
5130 bits += 1;
4329 switch (CType.classifyInt(dest_ty, zcu)) {
4330 .void => unreachable, // opv
4331 .small => {
4332 try f.writeCValue(w, local, .other);
4333 try w.writeAll(" = zig_wrap_");
4334 try f.dg.renderTypeForBuiltinFnName(w, dest_ty);
4335 try w.writeByte('(');
4336 try f.writeCValue(w, local, .other);
4337 try f.dg.renderBuiltinInfo(w, dest_ty, .bits);
4338 try w.writeAll(");");
4339 try f.newline();
51314340 },
5132 }
5133 try w.writeAll(" = ");
5134 if (need_bitcasts) {
5135 try w.writeAll("zig_bitCast_");
5136 try f.object.dg.renderCTypeForBuiltinFnName(w, wrap_ctype.?.toUnsigned());
5137 try w.writeByte('(');
5138 }
5139 try w.writeAll("zig_wrap_");
5140 const info_ty = try pt.intType(dest_info.signedness, bits);
5141 if (wrap_ctype) |ctype|
5142 try f.object.dg.renderCTypeForBuiltinFnName(w, ctype)
5143 else
5144 try f.object.dg.renderTypeForBuiltinFnName(w, info_ty);
5145 try w.writeByte('(');
5146 if (need_bitcasts) {
5147 try w.writeAll("zig_bitCast_");
5148 try f.object.dg.renderCTypeForBuiltinFnName(w, wrap_ctype.?);
5149 try w.writeByte('(');
5150 }
5151 try f.writeCValue(w, local, .Other);
5152 switch (dest_ctype.info(ctype_pool)) {
5153 else => {},
5154 .array => |array_info| try w.print("[{d}]", .{
5155 switch (target.cpu.arch.endian()) {
5156 .little => array_info.len - 1,
4341 .big => |big| {
4342 const dest_info = dest_ty.intInfo(zcu);
4343 const padding_index: u16 = switch (target.cpu.arch.endian()) {
4344 .little => big.limbs_len - 1,
51574345 .big => 0,
5158 },
5159 }),
4346 };
4347 const wrap_bits = ((dest_info.bits - 1) % big.limb_size.bits()) + 1;
4348 if (big.limb_size != .@"128" or dest_info.signedness == .unsigned) {
4349 try f.writeCValueMember(w, local, .{ .identifier = "limbs" });
4350 try w.print("[{d}] = zig_wrap_{c}{d}(", .{
4351 padding_index,
4352 signAbbrev(dest_info.signedness),
4353 big.limb_size.bits(),
4354 });
4355 try f.writeCValueMember(w, local, .{ .identifier = "limbs" });
4356 try w.print("[{d}], {d});", .{ padding_index, wrap_bits });
4357 } else {
4358 try f.writeCValueMember(w, local, .{ .identifier = "limbs" });
4359 try w.print("[{d}] = zig_bitCast_u128(zig_wrap_i128(zig_bitCast_i128(", .{
4360 padding_index,
4361 });
4362 try f.writeCValueMember(w, local, .{ .identifier = "limbs" });
4363 try w.print("[{d}]), {d}));", .{ padding_index, wrap_bits });
4364 try f.newline();
4365 }
4366 },
51604367 }
5161 if (need_bitcasts) try w.writeByte(')');
5162 try f.object.dg.renderBuiltinInfo(w, info_ty, .bits);
5163 if (need_bitcasts) try w.writeByte(')');
5164 try w.writeAll(");");
5165 try f.object.newline();
51664368 }
51674369
5168 try f.freeCValue(null, operand_lval);
51694370 return local;
51704371}
51714372
5172fn airTrap(f: *Function, w: *Writer) !void {
4373fn airTrap(f: *Function) !void {
51734374 // Not even allowed to call trap in a naked function.
5174 if (f.object.dg.is_naked_fn) return;
5175 try w.writeAll("zig_trap();\n");
4375 if (f.dg.is_naked_fn) return;
4376 try f.code.writer.writeAll("zig_trap();\n");
51764377}
51774378
51784379fn airBreakpoint(f: *Function) !CValue {
5179 const w = &f.object.code.writer;
4380 const w = &f.code.writer;
51804381 try w.writeAll("zig_breakpoint();");
5181 try f.object.newline();
4382 try f.newline();
51824383 return .none;
51834384}
51844385
51854386fn airRetAddr(f: *Function, inst: Air.Inst.Index) !CValue {
5186 const w = &f.object.code.writer;
4387 const w = &f.code.writer;
51874388 const local = try f.allocLocal(inst, .usize);
5188 try f.writeCValue(w, local, .Other);
4389 try f.writeCValue(w, local, .other);
51894390 try w.writeAll(" = (");
51904391 try f.renderType(w, .usize);
51914392 try w.writeAll(")zig_return_address();");
5192 try f.object.newline();
4393 try f.newline();
51934394 return local;
51944395}
51954396
51964397fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue {
5197 const w = &f.object.code.writer;
4398 const w = &f.code.writer;
51984399 const local = try f.allocLocal(inst, .usize);
5199 try f.writeCValue(w, local, .Other);
4400 try f.writeCValue(w, local, .other);
52004401 try w.writeAll(" = (");
52014402 try f.renderType(w, .usize);
52024403 try w.writeAll(")zig_frame_address();");
5203 try f.object.newline();
4404 try f.newline();
52044405 return local;
52054406}
52064407
5207fn airUnreach(o: *Object) !void {
4408fn airUnreach(f: *Function) !void {
52084409 // Not even allowed to call unreachable in a naked function.
5209 if (o.dg.is_naked_fn) return;
5210 try o.code.writer.writeAll("zig_unreachable();\n");
4410 if (f.dg.is_naked_fn) return;
4411 try f.code.writer.writeAll("zig_unreachable();\n");
52114412}
52124413
52134414fn airLoop(f: *Function, inst: Air.Inst.Index) !void {
52144415 const block = f.air.unwrapBlock(inst);
5215 const w = &f.object.code.writer;
4416 const w = &f.code.writer;
52164417
52174418 // `repeat` instructions matching this loop will branch to
52184419 // this label. Since we need a label for arbitrary `repeat`
52194420 // anyway, there's actually no need to use a "real" looping
52204421 // construct at all!
52214422 try w.print("zig_loop_{d}:", .{@intFromEnum(inst)});
5222 try f.object.newline();
4423 try f.newline();
52234424 try genBodyInner(f, block.body); // no need to restore state, we're noreturn
52244425}
52254426
......@@ -5230,15 +4431,15 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !void {
52304431 const then_body = cond_br.then_body;
52314432 const else_body = cond_br.else_body;
52324433 const liveness_condbr = f.liveness.getCondBr(inst);
5233 const w = &f.object.code.writer;
4434 const w = &f.code.writer;
52344435
52354436 try w.writeAll("if (");
5236 try f.writeCValue(w, cond, .Other);
4437 try f.writeCValue(w, cond, .other);
52374438 try w.writeAll(") ");
52384439
52394440 try genBodyResolveState(f, inst, liveness_condbr.then_deaths, then_body, false);
5240 try f.object.newline();
5241 if (else_body.len > 0) if (f.object.dg.expected_block) |_|
4441 try f.newline();
4442 if (else_body.len > 0) if (f.dg.expected_block) |_|
52424443 return f.fail("runtime code not allowed in naked function", .{});
52434444
52444445 // We don't need to use `genBodyResolveState` for the else block, because this instruction is
......@@ -5256,23 +4457,23 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !void {
52564457}
52574458
52584459fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void {
5259 const pt = f.object.dg.pt;
4460 const pt = f.dg.pt;
52604461 const zcu = pt.zcu;
5261 const gpa = f.object.dg.gpa;
4462 const gpa = f.dg.gpa;
52624463 const switch_br = f.air.unwrapSwitch(inst);
52634464 const init_condition = try f.resolveInst(switch_br.operand);
52644465 try reap(f, inst, &.{switch_br.operand});
52654466 const condition_ty = f.typeOf(switch_br.operand);
5266 const w = &f.object.code.writer;
4467 const w = &f.code.writer;
52674468
52684469 // For dispatches, we will create a local alloc to contain the condition value.
52694470 // This may not result in optimal codegen for switch loops, but it minimizes the
52704471 // amount of C code we generate, which is probably more desirable here (and is simpler).
52714472 const condition = if (is_dispatch_loop) cond: {
52724473 const new_local = try f.allocLocal(inst, condition_ty);
5273 try f.copyCValue(try f.ctypeFromType(condition_ty, .complete), new_local, init_condition);
4474 try f.copyCValue(new_local, init_condition);
52744475 try w.print("zig_switch_{d}_loop:", .{@intFromEnum(inst)});
5275 try f.object.newline();
4476 try f.newline();
52764477 try f.loop_switch_conds.put(gpa, inst, new_local.new_local);
52774478 break :cond new_local;
52784479 } else init_condition;
......@@ -5294,9 +4495,9 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
52944495 try f.renderType(w, lowered_condition_ty);
52954496 try w.writeByte(')');
52964497 }
5297 try f.writeCValue(w, condition, .Other);
4498 try f.writeCValue(w, condition, .other);
52984499 try w.writeAll(") {");
5299 f.object.indent();
4500 f.indent();
53004501
53014502 const liveness = try f.liveness.getSwitchBr(gpa, inst, switch_br.cases_len + 1);
53024503 defer gpa.free(liveness.deaths);
......@@ -5309,7 +4510,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
53094510 continue;
53104511 }
53114512 for (case.items) |item| {
5312 try f.object.newline();
4513 try f.newline();
53134514 try w.writeAll("case ");
53144515 const item_value = try f.air.value(item, pt);
53154516 // If `item_value` is a pointer with a known integer address, print the address
......@@ -5326,28 +4527,28 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
53264527 try f.renderType(w, .usize);
53274528 try w.writeByte(')');
53284529 }
5329 try f.object.dg.renderValue(w, (try f.air.value(item, pt)).?, .Other);
4530 try f.dg.renderValue(w, (try f.air.value(item, pt)).?, .other);
53304531 }
53314532 try w.writeByte(':');
53324533 }
53334534 try w.writeAll(" {");
5334 f.object.indent();
5335 try f.object.newline();
4535 f.indent();
4536 try f.newline();
53364537 if (is_dispatch_loop) {
53374538 try w.print("zig_switch_{d}_dispatch_{d}:;", .{ @intFromEnum(inst), case.idx });
5338 try f.object.newline();
4539 try f.newline();
53394540 }
53404541 try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true);
5341 try f.object.outdent();
4542 try f.outdent();
53424543 try w.writeByte('}');
5343 if (f.object.dg.expected_block) |_|
4544 if (f.dg.expected_block) |_|
53444545 return f.fail("runtime code not allowed in naked function", .{});
53454546
53464547 // The case body must be noreturn so we don't need to insert a break.
53474548 }
53484549
53494550 const else_body = it.elseBody();
5350 try f.object.newline();
4551 try f.newline();
53514552
53524553 try w.writeAll("default: ");
53534554 if (any_range_cases) {
......@@ -5360,33 +4561,33 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
53604561 try w.writeAll("if (");
53614562 for (case.items, 0..) |item, item_i| {
53624563 if (item_i != 0) try w.writeAll(" || ");
5363 try f.writeCValue(w, condition, .Other);
4564 try f.writeCValue(w, condition, .other);
53644565 try w.writeAll(" == ");
5365 try f.object.dg.renderValue(w, (try f.air.value(item, pt)).?, .Other);
4566 try f.dg.renderValue(w, (try f.air.value(item, pt)).?, .other);
53664567 }
53674568 for (case.ranges, 0..) |range, range_i| {
53684569 if (case.items.len != 0 or range_i != 0) try w.writeAll(" || ");
53694570 // "(x >= lower && x <= upper)"
53704571 try w.writeByte('(');
5371 try f.writeCValue(w, condition, .Other);
4572 try f.writeCValue(w, condition, .other);
53724573 try w.writeAll(" >= ");
5373 try f.object.dg.renderValue(w, (try f.air.value(range[0], pt)).?, .Other);
4574 try f.dg.renderValue(w, (try f.air.value(range[0], pt)).?, .other);
53744575 try w.writeAll(" && ");
5375 try f.writeCValue(w, condition, .Other);
4576 try f.writeCValue(w, condition, .other);
53764577 try w.writeAll(" <= ");
5377 try f.object.dg.renderValue(w, (try f.air.value(range[1], pt)).?, .Other);
4578 try f.dg.renderValue(w, (try f.air.value(range[1], pt)).?, .other);
53784579 try w.writeByte(')');
53794580 }
53804581 try w.writeAll(") {");
5381 f.object.indent();
5382 try f.object.newline();
4582 f.indent();
4583 try f.newline();
53834584 if (is_dispatch_loop) {
53844585 try w.print("zig_switch_{d}_dispatch_{d}: ", .{ @intFromEnum(inst), case.idx });
53854586 }
53864587 try genBodyResolveState(f, inst, liveness.deaths[case.idx], case.body, true);
5387 try f.object.outdent();
4588 try f.outdent();
53884589 try w.writeByte('}');
5389 if (f.object.dg.expected_block) |_|
4590 if (f.dg.expected_block) |_|
53904591 return f.fail("runtime code not allowed in naked function", .{});
53914592 }
53924593 }
......@@ -5400,16 +4601,16 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index, is_dispatch_loop: bool) !void
54004601 try die(f, inst, death.toRef());
54014602 }
54024603 try genBody(f, else_body);
5403 if (f.object.dg.expected_block) |_|
4604 if (f.dg.expected_block) |_|
54044605 return f.fail("runtime code not allowed in naked function", .{});
5405 } else try airUnreach(&f.object);
5406 try f.object.newline();
5407 try f.object.outdent();
4606 } else try airUnreach(f);
4607 try f.newline();
4608 try f.outdent();
54084609 try w.writeAll("}\n");
54094610}
54104611
54114612fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool {
5412 const dg = f.object.dg;
4613 const dg = f.dg;
54134614 const target = &dg.mod.resolved_target.result;
54144615 return switch (constraint[0]) {
54154616 '{' => true,
......@@ -5429,28 +4630,28 @@ fn asmInputNeedsLocal(f: *Function, constraint: []const u8, value: CValue) bool
54294630}
54304631
54314632fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
5432 const pt = f.object.dg.pt;
4633 const pt = f.dg.pt;
54334634 const zcu = pt.zcu;
54344635 const unwrapped_asm = f.air.unwrapAsm(inst);
54354636 const is_volatile = unwrapped_asm.is_volatile;
5436 const gpa = f.object.dg.gpa;
4637 const gpa = f.dg.gpa;
54374638 const outputs = unwrapped_asm.outputs;
54384639 const inputs = unwrapped_asm.inputs;
54394640
54404641 const result = result: {
5441 const w = &f.object.code.writer;
4642 const w = &f.code.writer;
54424643 const inst_ty = f.typeOfIndex(inst);
5443 const inst_local = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) local: {
4644 const inst_local = if (inst_ty.hasRuntimeBits(zcu)) local: {
54444645 const inst_local = try f.allocLocalValue(.{
5445 .ctype = try f.ctypeFromType(inst_ty, .complete),
5446 .alignas = CType.AlignAs.fromAbiAlignment(inst_ty.abiAlignment(zcu)),
4646 .type = inst_ty,
4647 .alignment = .none,
54474648 });
54484649 if (f.wantSafety()) {
5449 try f.writeCValue(w, inst_local, .Other);
4650 try f.writeCValue(w, inst_local, .other);
54504651 try w.writeAll(" = ");
5451 try f.writeCValue(w, .{ .undef = inst_ty }, .Other);
4652 try f.writeCValue(w, .{ .undef = inst_ty }, .other);
54524653 try w.writeByte(';');
5453 try f.object.newline();
4654 try f.newline();
54544655 }
54554656 break :local inst_local;
54564657 } else .none;
......@@ -5471,20 +4672,20 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
54714672 const output_ty = if (output.operand == .none) inst_ty else f.typeOf(output.operand).childType(zcu);
54724673 try w.writeAll("register ");
54734674 const output_local = try f.allocLocalValue(.{
5474 .ctype = try f.ctypeFromType(output_ty, .complete),
5475 .alignas = CType.AlignAs.fromAbiAlignment(output_ty.abiAlignment(zcu)),
4675 .type = output_ty,
4676 .alignment = .none,
54764677 });
54774678 try f.allocs.put(gpa, output_local.new_local, false);
5478 try f.object.dg.renderTypeAndName(w, output_ty, output_local, .{}, .none, .complete);
4679 try f.dg.renderTypeAndName(w, output_ty, output_local, .{}, .none);
54794680 try w.writeAll(" __asm(\"");
54804681 try w.writeAll(constraint["={".len .. constraint.len - "}".len]);
54814682 try w.writeAll("\")");
54824683 if (f.wantSafety()) {
54834684 try w.writeAll(" = ");
5484 try f.writeCValue(w, .{ .undef = output_ty }, .Other);
4685 try f.writeCValue(w, .{ .undef = output_ty }, .other);
54854686 }
54864687 try w.writeByte(';');
5487 try f.object.newline();
4688 try f.newline();
54884689 }
54894690 }
54904691
......@@ -5504,29 +4705,29 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
55044705 const input_ty = f.typeOf(input.operand);
55054706 if (is_reg) try w.writeAll("register ");
55064707 const input_local = try f.allocLocalValue(.{
5507 .ctype = try f.ctypeFromType(input_ty, .complete),
5508 .alignas = CType.AlignAs.fromAbiAlignment(input_ty.abiAlignment(zcu)),
4708 .type = input_ty,
4709 .alignment = .none,
55094710 });
55104711 try f.allocs.put(gpa, input_local.new_local, false);
55114712 // Do not render the declaration as `const` qualified if we're generating an
55124713 // explicit `register` local, as GCC will ignore the constraint completely.
5513 try f.object.dg.renderTypeAndName(w, input_ty, input_local, if (is_reg) .{} else Const, .none, .complete);
4714 try f.dg.renderTypeAndName(w, input_ty, input_local, .{ .@"const" = is_reg }, .none);
55144715 if (is_reg) {
55154716 try w.writeAll(" __asm(\"");
55164717 try w.writeAll(constraint["{".len .. constraint.len - "}".len]);
55174718 try w.writeAll("\")");
55184719 }
55194720 try w.writeAll(" = ");
5520 try f.writeCValue(w, input_val, .Other);
4721 try f.writeCValue(w, input_val, .other);
55214722 try w.writeByte(';');
5522 try f.object.newline();
4723 try f.newline();
55234724 }
55244725 }
55254726
55264727 {
55274728 const asm_source = unwrapped_asm.source;
55284729
5529 var stack = std.heap.stackFallback(256, f.object.dg.gpa);
4730 var stack = std.heap.stackFallback(256, f.dg.gpa);
55304731 const allocator = stack.get();
55314732 const fixed_asm_source = try allocator.alloc(u8, asm_source.len);
55324733 defer allocator.free(fixed_asm_source);
......@@ -5592,10 +4793,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
55924793 const is_reg = constraint[1] == '{';
55934794 try w.print("{f}(", .{fmtStringLiteral(if (is_reg) "=r" else constraint, null)});
55944795 if (is_reg) {
5595 try f.writeCValue(w, .{ .local = locals_index }, .Other);
4796 try f.writeCValue(w, .{ .local = locals_index }, .other);
55964797 locals_index += 1;
55974798 } else if (output.operand == .none) {
5598 try f.writeCValue(w, inst_local, .FunctionArgument);
4799 try f.writeCValue(w, inst_local, .other);
55994800 } else {
56004801 try f.writeCValueDeref(w, try f.resolveInst(output.operand));
56014802 }
......@@ -5619,57 +4820,54 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
56194820 const input_local_idx = locals_index;
56204821 locals_index += 1;
56214822 break :local .{ .local = input_local_idx };
5622 } else input_val, .Other);
4823 } else input_val, .other);
56234824 try w.writeByte(')');
56244825 }
56254826 try w.writeByte(':');
56264827 const ip = &zcu.intern_pool;
5627 const aggregate = ip.indexToKey(unwrapped_asm.clobbers).aggregate;
5628 const struct_type: Type = .fromInterned(aggregate.ty);
5629 switch (aggregate.storage) {
5630 .elems => |elems| for (elems, 0..) |elem, i| switch (elem) {
5631 .bool_true => {
5632 const field_name = struct_type.structFieldName(i, zcu).toSlice(ip).?;
5633 assert(field_name.len != 0);
5634
5635 const target = &f.object.dg.mod.resolved_target.result;
5636 var c_name_buf: [16]u8 = undefined;
5637 const name =
5638 if ((target.cpu.arch.isMIPS() or target.cpu.arch == .alpha) and field_name[0] == 'r') name: {
5639 // Convert "rN" to "$N"
5640 const c_name = (&c_name_buf)[0..field_name.len];
5641 @memcpy(c_name, field_name);
5642 c_name_buf[0] = '$';
5643 break :name c_name;
5644 } else if ((target.cpu.arch.isMIPS() and (mem.startsWith(u8, field_name, "fcc") or field_name[0] == 'w')) or
5645 ((target.cpu.arch.isMIPS() or target.cpu.arch == .alpha) and field_name[0] == 'f') or
5646 (target.cpu.arch == .kvx and !mem.eql(u8, field_name, "memory"))) name: {
5647 // "$" prefix for these registers
5648 c_name_buf[0] = '$';
5649 @memcpy((&c_name_buf)[1..][0..field_name.len], field_name);
5650 break :name (&c_name_buf)[0 .. 1 + field_name.len];
5651 } else if (target.cpu.arch.isSPARC() and
5652 (mem.eql(u8, field_name, "ccr") or mem.eql(u8, field_name, "icc") or mem.eql(u8, field_name, "xcc"))) name: {
5653 // C compilers just use `icc` to encompass all of these.
5654 break :name "icc";
5655 } else field_name;
5656
5657 try w.print(" {f}", .{fmtStringLiteral(name, null)});
5658 (try w.writableArray(1))[0] = ',';
5659 },
5660 .bool_false => continue,
5661 else => unreachable,
5662 },
5663 .repeated_elem => |elem| switch (elem) {
5664 .bool_true => @panic("TODO"),
5665 .bool_false => {},
5666 else => unreachable,
5667 },
5668 .bytes => @panic("TODO"),
4828 const clobbers_val: Value = .fromInterned(unwrapped_asm.clobbers);
4829 const clobbers_ty = clobbers_val.typeOf(zcu);
4830 var clobbers_bigint_buf: Value.BigIntSpace = undefined;
4831 const clobbers_bigint = clobbers_val.toBigInt(&clobbers_bigint_buf, zcu);
4832 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
4833 assert(clobbers_ty.fieldType(field_index, zcu).toIntern() == .bool_type);
4834 const limb_bits = @bitSizeOf(std.math.big.Limb);
4835 if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
4836 switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
4837 0 => continue, // field is false
4838 1 => {}, // field is true
4839 }
4840 const field_name = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;
4841 assert(field_name.len != 0);
4842
4843 const target = &f.dg.mod.resolved_target.result;
4844 var c_name_buf: [16]u8 = undefined;
4845 const name =
4846 if ((target.cpu.arch.isMIPS() or target.cpu.arch == .alpha) and field_name[0] == 'r') name: {
4847 // Convert "rN" to "$N"
4848 const c_name = (&c_name_buf)[0..field_name.len];
4849 @memcpy(c_name, field_name);
4850 c_name_buf[0] = '$';
4851 break :name c_name;
4852 } else if ((target.cpu.arch.isMIPS() and (mem.startsWith(u8, field_name, "fcc") or field_name[0] == 'w')) or
4853 ((target.cpu.arch.isMIPS() or target.cpu.arch == .alpha) and field_name[0] == 'f') or
4854 (target.cpu.arch == .kvx and !mem.eql(u8, field_name, "memory"))) name: {
4855 // "$" prefix for these registers
4856 c_name_buf[0] = '$';
4857 @memcpy((&c_name_buf)[1..][0..field_name.len], field_name);
4858 break :name (&c_name_buf)[0 .. 1 + field_name.len];
4859 } else if (target.cpu.arch.isSPARC() and
4860 (mem.eql(u8, field_name, "ccr") or mem.eql(u8, field_name, "icc") or mem.eql(u8, field_name, "xcc"))) name: {
4861 // C compilers just use `icc` to encompass all of these.
4862 break :name "icc";
4863 } else field_name;
4864
4865 try w.print(" {f}", .{fmtStringLiteral(name, null)});
4866 (try w.writableArray(1))[0] = ',';
56694867 }
56704868 w.undo(1); // erase the last comma
56714869 try w.writeAll(");");
5672 try f.object.newline();
4870 try f.newline();
56734871
56744872 locals_index = locals_begin;
56754873 it = unwrapped_asm.iterateOutputs();
......@@ -5683,10 +4881,10 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
56834881 else
56844882 try f.resolveInst(output.operand));
56854883 try w.writeAll(" = ");
5686 try f.writeCValue(w, .{ .local = locals_index }, .Other);
4884 try f.writeCValue(w, .{ .local = locals_index }, .other);
56874885 locals_index += 1;
56884886 try w.writeByte(';');
5689 try f.object.newline();
4887 try f.newline();
56904888 }
56914889 }
56924890
......@@ -5708,147 +4906,145 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
57084906fn airIsNull(
57094907 f: *Function,
57104908 inst: Air.Inst.Index,
5711 operator: std.math.CompareOperator,
4909 operator: enum { eq, neq },
57124910 is_ptr: bool,
57134911) !CValue {
5714 const pt = f.object.dg.pt;
4912 const pt = f.dg.pt;
57154913 const zcu = pt.zcu;
5716 const ctype_pool = &f.object.dg.ctype_pool;
57174914 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
57184915
5719 const w = &f.object.code.writer;
4916 const w = &f.code.writer;
57204917 const operand = try f.resolveInst(un_op);
57214918 try reap(f, inst, &.{un_op});
57224919
57234920 const local = try f.allocLocal(inst, .bool);
5724 const a = try Assignment.start(f, w, .bool);
5725 try f.writeCValue(w, local, .Other);
5726 try a.assign(f, w);
4921 try f.writeCValue(w, local, .other);
4922 try w.writeAll(" = ");
57274923
57284924 const operand_ty = f.typeOf(un_op);
57294925 const optional_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;
5730 const opt_ctype = try f.ctypeFromType(optional_ty, .complete);
5731 const rhs = switch (opt_ctype.info(ctype_pool)) {
5732 .basic, .pointer => rhs: {
5733 if (is_ptr)
5734 try f.writeCValueDeref(w, operand)
5735 else
5736 try f.writeCValue(w, operand, .Other);
5737 break :rhs if (opt_ctype.isBool())
5738 "true"
5739 else if (opt_ctype.isInteger())
5740 "0"
5741 else
5742 "NULL";
4926
4927 const pre: []const u8, const maybe_field: ?[]const u8, const post: []const u8 = switch (operator) {
4928 // zig fmt: off
4929 .eq => switch (CType.classifyOptional(optional_ty, zcu)) {
4930 .npv_payload => unreachable, // opv optional
4931 .error_set => .{ "", null, " == 0" },
4932 .ptr_like => .{ "", null, " == NULL" },
4933 .slice_like => .{ "", "ptr", " == NULL" },
4934 .opv_payload => .{ "", "is_null", "" },
4935 .@"struct" => .{ "", "is_null", "" },
57434936 },
5744 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
5745 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {
5746 .is_null, .payload => rhs: {
5747 if (is_ptr)
5748 try f.writeCValueDerefMember(w, operand, .{ .identifier = "is_null" })
5749 else
5750 try f.writeCValueMember(w, operand, .{ .identifier = "is_null" });
5751 break :rhs "true";
5752 },
5753 .ptr, .len => rhs: {
5754 if (is_ptr)
5755 try f.writeCValueDerefMember(w, operand, .{ .identifier = "ptr" })
5756 else
5757 try f.writeCValueMember(w, operand, .{ .identifier = "ptr" });
5758 break :rhs "NULL";
5759 },
5760 else => unreachable,
4937 .neq => switch (CType.classifyOptional(optional_ty, zcu)) {
4938 .npv_payload => unreachable, // opv optional
4939 .error_set => .{ "", null, " != 0" },
4940 .ptr_like => .{ "", null, " != NULL" },
4941 .slice_like => .{ "", "ptr", " != NULL" },
4942 .opv_payload => .{ "!", "is_null", "" },
4943 .@"struct" => .{ "!", "is_null", "" },
57614944 },
4945 // zig fmt: on
57624946 };
5763 try w.writeAll(compareOperatorC(operator));
5764 try w.writeAll(rhs);
5765 try a.end(f, w);
4947
4948 try w.writeAll(pre);
4949 if (maybe_field) |field| {
4950 if (is_ptr) {
4951 try f.writeCValueDerefMember(w, operand, .{ .identifier = field });
4952 } else {
4953 try f.writeCValueMember(w, operand, .{ .identifier = field });
4954 }
4955 } else {
4956 if (is_ptr) {
4957 try f.writeCValueDeref(w, operand);
4958 } else {
4959 try f.writeCValue(w, operand, .other);
4960 }
4961 }
4962 try w.writeAll(post);
4963
4964 try w.writeByte(';');
4965 try f.newline();
57664966 return local;
57674967}
57684968
57694969fn airOptionalPayload(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
5770 const pt = f.object.dg.pt;
4970 const pt = f.dg.pt;
57714971 const zcu = pt.zcu;
5772 const ctype_pool = &f.object.dg.ctype_pool;
57734972 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
57744973
57754974 const inst_ty = f.typeOfIndex(inst);
57764975 const operand_ty = f.typeOf(ty_op.operand);
57774976 const opt_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;
5778 const opt_ctype = try f.ctypeFromType(opt_ty, .complete);
5779 if (opt_ctype.isBool()) return if (is_ptr) .{ .undef = inst_ty } else .none;
57804977
57814978 const operand = try f.resolveInst(ty_op.operand);
5782 switch (opt_ctype.info(ctype_pool)) {
5783 .basic, .pointer => return f.moveCValue(inst, inst_ty, operand),
5784 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
5785 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {
5786 .is_null, .payload => {
5787 const w = &f.object.code.writer;
5788 const local = try f.allocLocal(inst, inst_ty);
5789 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
5790 try f.writeCValue(w, local, .Other);
5791 try a.assign(f, w);
5792 if (is_ptr) {
5793 try w.writeByte('&');
5794 try f.writeCValueDerefMember(w, operand, .{ .identifier = "payload" });
5795 } else try f.writeCValueMember(w, operand, .{ .identifier = "payload" });
5796 try a.end(f, w);
5797 return local;
5798 },
5799 .ptr, .len => return f.moveCValue(inst, inst_ty, operand),
5800 else => unreachable,
4979
4980 switch (CType.classifyOptional(opt_ty, zcu)) {
4981 .npv_payload => unreachable, // opv optional
4982
4983 .opv_payload => return if (is_ptr) .{ .undef = inst_ty } else .none,
4984
4985 .error_set,
4986 .ptr_like,
4987 .slice_like,
4988 => return f.moveCValue(inst, inst_ty, operand),
4989
4990 .@"struct" => {
4991 const w = &f.code.writer;
4992 const local = try f.allocLocal(inst, inst_ty);
4993 try f.writeCValue(w, local, .other);
4994 try w.writeAll(" = ");
4995 if (is_ptr) {
4996 try w.writeByte('&');
4997 try f.writeCValueDerefMember(w, operand, .{ .identifier = "payload" });
4998 } else try f.writeCValueMember(w, operand, .{ .identifier = "payload" });
4999 try w.writeByte(';');
5000 try f.newline();
5001 return local;
58015002 },
58025003 }
58035004}
58045005
58055006fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5806 const pt = f.object.dg.pt;
5007 const pt = f.dg.pt;
58075008 const zcu = pt.zcu;
58085009 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
5809 const w = &f.object.code.writer;
5010 const w = &f.code.writer;
58105011 const operand = try f.resolveInst(ty_op.operand);
58115012 try reap(f, inst, &.{ty_op.operand});
58125013 const operand_ty = f.typeOf(ty_op.operand);
5014 const opt_ty = operand_ty.childType(zcu);
58135015
58145016 const inst_ty = f.typeOfIndex(inst);
5815 const opt_ctype = try f.ctypeFromType(operand_ty.childType(zcu), .complete);
5816 switch (opt_ctype.info(&f.object.dg.ctype_pool)) {
5817 .basic => {
5818 const a = try Assignment.start(f, w, opt_ctype);
5819 try f.writeCValueDeref(w, operand);
5820 try a.assign(f, w);
5821 try f.object.dg.renderValue(w, Value.false, .Other);
5822 try a.end(f, w);
5823 return .none;
5824 },
5825 .pointer => {
5826 if (f.liveness.isUnused(inst)) return .none;
5827 const local = try f.allocLocal(inst, inst_ty);
5828 const a = try Assignment.start(f, w, opt_ctype);
5829 try f.writeCValue(w, local, .Other);
5830 try a.assign(f, w);
5831 try f.writeCValue(w, operand, .Other);
5832 try a.end(f, w);
5833 return local;
5017
5018 switch (CType.classifyOptional(opt_ty, zcu)) {
5019 .npv_payload => unreachable, // opv optional
5020
5021 .opv_payload => {
5022 try f.writeCValueDerefMember(w, operand, .{ .identifier = "is_null" });
5023 try w.writeAll(" = ");
5024 try f.dg.renderValue(w, .false, .other);
5025 try w.writeByte(';');
5026 try f.newline();
5027 return .{ .undef = inst_ty };
58345028 },
5835 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
5836 .aggregate => {
5837 {
5838 const a = try Assignment.start(f, w, opt_ctype);
5839 try f.writeCValueDerefMember(w, operand, .{ .identifier = "is_null" });
5840 try a.assign(f, w);
5841 try f.object.dg.renderValue(w, Value.false, .Other);
5842 try a.end(f, w);
5843 }
5029
5030 .error_set,
5031 .ptr_like,
5032 .slice_like,
5033 => return f.moveCValue(inst, inst_ty, operand),
5034
5035 .@"struct" => {
5036 try f.writeCValueDerefMember(w, operand, .{ .identifier = "is_null" });
5037 try w.writeAll(" = ");
5038 try f.dg.renderValue(w, .false, .other);
5039 try w.writeByte(';');
5040 try f.newline();
58445041 if (f.liveness.isUnused(inst)) return .none;
58455042 const local = try f.allocLocal(inst, inst_ty);
5846 const a = try Assignment.start(f, w, opt_ctype);
5847 try f.writeCValue(w, local, .Other);
5848 try a.assign(f, w);
5849 try w.writeByte('&');
5043 try f.writeCValue(w, local, .other);
5044 try w.writeAll(" = &");
58505045 try f.writeCValueDerefMember(w, operand, .{ .identifier = "payload" });
5851 try a.end(f, w);
5046 try w.writeByte(';');
5047 try f.newline();
58525048 return local;
58535049 },
58545050 }
......@@ -5870,12 +5066,12 @@ fn fieldLocation(
58705066 .struct_type => {
58715067 const loaded_struct = ip.loadStructType(container_ty.toIntern());
58725068 return switch (loaded_struct.layout) {
5873 .auto, .@"extern" => if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu))
5069 .auto, .@"extern" => if (!container_ty.hasRuntimeBits(zcu))
58745070 .begin
5875 else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu))
5876 .{ .byte_offset = loaded_struct.offsets.get(ip)[field_index] }
5071 else if (!field_ptr_ty.childType(zcu).hasRuntimeBits(zcu))
5072 .{ .byte_offset = loaded_struct.field_offsets.get(ip)[field_index] }
58775073 else
5878 .{ .field = .{ .identifier = loaded_struct.fieldName(ip, field_index).toSlice(ip) } },
5074 .{ .field = .{ .identifier = loaded_struct.field_names.get(ip)[field_index].toSlice(ip) } },
58795075 .@"packed" => if (field_ptr_ty.ptrInfo(zcu).packed_offset.host_size == 0)
58805076 .{ .byte_offset = @divExact(zcu.structPackedFieldBitOffset(loaded_struct, field_index) +
58815077 container_ptr_ty.ptrInfo(zcu).packed_offset.bit_offset, 8) }
......@@ -5883,27 +5079,29 @@ fn fieldLocation(
58835079 .begin,
58845080 };
58855081 },
5886 .tuple_type => return if (!container_ty.hasRuntimeBitsIgnoreComptime(zcu))
5082 .tuple_type => return if (!container_ty.hasRuntimeBits(zcu))
58875083 .begin
5888 else if (!field_ptr_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu))
5084 else if (!field_ptr_ty.childType(zcu).hasRuntimeBits(zcu))
58895085 .{ .byte_offset = container_ty.structFieldOffset(field_index, zcu) }
58905086 else
58915087 .{ .field = .{ .field = field_index } },
58925088 .union_type => {
58935089 const loaded_union = ip.loadUnionType(container_ty.toIntern());
5894 switch (loaded_union.flagsUnordered(ip).layout) {
5895 .auto, .@"extern" => {
5090 switch (loaded_union.layout) {
5091 .auto => {
58965092 const field_ty: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
5897 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu))
5898 return if (loaded_union.hasTag(ip) and !container_ty.unionHasAllZeroBitFieldTypes(zcu))
5899 .{ .field = .{ .identifier = "payload" } }
5900 else
5901 .begin;
5902 const field_name = loaded_union.loadTagType(ip).names.get(ip)[field_index];
5903 return .{ .field = if (loaded_union.hasTag(ip))
5904 .{ .payload_identifier = field_name.toSlice(ip) }
5905 else
5906 .{ .identifier = field_name.toSlice(ip) } };
5093 if (!field_ty.hasRuntimeBits(zcu)) {
5094 if (container_ty.unionHasAllZeroBitFieldTypes(zcu)) return .begin;
5095 return .{ .field = .{ .identifier = "payload" } };
5096 }
5097 const field_name = ip.loadEnumType(loaded_union.enum_tag_type).field_names.get(ip)[field_index];
5098 return .{ .field = .{ .payload_identifier = field_name.toSlice(ip) } };
5099 },
5100 .@"extern" => {
5101 const field_ty: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
5102 if (!field_ty.hasRuntimeBits(zcu)) return .begin;
5103 const field_name = ip.loadEnumType(loaded_union.enum_tag_type).field_names.get(ip)[field_index];
5104 return .{ .field = .{ .identifier = field_name.toSlice(ip) } };
59075105 },
59085106 .@"packed" => return .begin,
59095107 }
......@@ -5940,7 +5138,7 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue
59405138}
59415139
59425140fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
5943 const pt = f.object.dg.pt;
5141 const pt = f.dg.pt;
59445142 const zcu = pt.zcu;
59455143 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
59465144 const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
......@@ -5952,26 +5150,26 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
59525150 const field_ptr_val = try f.resolveInst(extra.field_ptr);
59535151 try reap(f, inst, &.{extra.field_ptr});
59545152
5955 const w = &f.object.code.writer;
5153 const w = &f.code.writer;
59565154 const local = try f.allocLocal(inst, container_ptr_ty);
5957 try f.writeCValue(w, local, .Other);
5155 try f.writeCValue(w, local, .other);
59585156 try w.writeAll(" = (");
59595157 try f.renderType(w, container_ptr_ty);
59605158 try w.writeByte(')');
59615159
59625160 switch (fieldLocation(container_ptr_ty, field_ptr_ty, extra.field_index, zcu)) {
5963 .begin => try f.writeCValue(w, field_ptr_val, .Other),
5161 .begin => try f.writeCValue(w, field_ptr_val, .other),
59645162 .field => |field| {
59655163 const u8_ptr_ty = try pt.adjustPtrTypeChild(field_ptr_ty, .u8);
59665164
59675165 try w.writeAll("((");
59685166 try f.renderType(w, u8_ptr_ty);
59695167 try w.writeByte(')');
5970 try f.writeCValue(w, field_ptr_val, .Other);
5168 try f.writeCValue(w, field_ptr_val, .other);
59715169 try w.writeAll(" - offsetof(");
59725170 try f.renderType(w, container_ty);
59735171 try w.writeAll(", ");
5974 try f.writeCValue(w, field, .Other);
5172 try f.writeCValue(w, field, .other);
59755173 try w.writeAll("))");
59765174 },
59775175 .byte_offset => |byte_offset| {
......@@ -5980,7 +5178,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
59805178 try w.writeAll("((");
59815179 try f.renderType(w, u8_ptr_ty);
59825180 try w.writeByte(')');
5983 try f.writeCValue(w, field_ptr_val, .Other);
5181 try f.writeCValue(w, field_ptr_val, .other);
59845182 try w.print(" - {f})", .{
59855183 try f.fmtIntLiteralDec(try pt.intValue(.usize, byte_offset)),
59865184 });
......@@ -5988,7 +5186,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue {
59885186 }
59895187
59905188 try w.writeByte(';');
5991 try f.object.newline();
5189 try f.newline();
59925190 return local;
59935191}
59945192
......@@ -5999,23 +5197,19 @@ fn fieldPtr(
59995197 container_ptr_val: CValue,
60005198 field_index: u32,
60015199) !CValue {
6002 const pt = f.object.dg.pt;
5200 const pt = f.dg.pt;
60035201 const zcu = pt.zcu;
6004 const container_ty = container_ptr_ty.childType(zcu);
60055202 const field_ptr_ty = f.typeOfIndex(inst);
60065203
6007 // Ensure complete type definition is visible before accessing fields.
6008 _ = try f.ctypeFromType(container_ty, .complete);
6009
6010 const w = &f.object.code.writer;
5204 const w = &f.code.writer;
60115205 const local = try f.allocLocal(inst, field_ptr_ty);
6012 try f.writeCValue(w, local, .Other);
5206 try f.writeCValue(w, local, .other);
60135207 try w.writeAll(" = (");
60145208 try f.renderType(w, field_ptr_ty);
60155209 try w.writeByte(')');
60165210
60175211 switch (fieldLocation(container_ptr_ty, field_ptr_ty, field_index, zcu)) {
6018 .begin => try f.writeCValue(w, container_ptr_val, .Other),
5212 .begin => try f.writeCValue(w, container_ptr_val, .other),
60195213 .field => |field| {
60205214 try w.writeByte('&');
60215215 try f.writeCValueDerefMember(w, container_ptr_val, field);
......@@ -6026,7 +5220,7 @@ fn fieldPtr(
60265220 try w.writeAll("((");
60275221 try f.renderType(w, u8_ptr_ty);
60285222 try w.writeByte(')');
6029 try f.writeCValue(w, container_ptr_val, .Other);
5223 try f.writeCValue(w, container_ptr_val, .other);
60305224 try w.print(" + {f})", .{
60315225 try f.fmtIntLiteralDec(try pt.intValue(.usize, byte_offset)),
60325226 });
......@@ -6034,61 +5228,51 @@ fn fieldPtr(
60345228 }
60355229
60365230 try w.writeByte(';');
6037 try f.object.newline();
5231 try f.newline();
60385232 return local;
60395233}
60405234
60415235fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
6042 const pt = f.object.dg.pt;
5236 const pt = f.dg.pt;
60435237 const zcu = pt.zcu;
60445238 const ip = &zcu.intern_pool;
60455239 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
60465240 const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;
60475241
60485242 const inst_ty = f.typeOfIndex(inst);
6049 if (!inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
6050 try reap(f, inst, &.{extra.struct_operand});
6051 return .none;
6052 }
5243 assert(inst_ty.hasRuntimeBits(zcu));
60535244
60545245 const struct_byval = try f.resolveInst(extra.struct_operand);
60555246 try reap(f, inst, &.{extra.struct_operand});
60565247 const struct_ty = f.typeOf(extra.struct_operand);
6057 const w = &f.object.code.writer;
6058
6059 // Ensure complete type definition is visible before accessing fields.
6060 _ = try f.ctypeFromType(struct_ty, .complete);
5248 const w = &f.code.writer;
60615249
60625250 assert(struct_ty.containerLayout(zcu) != .@"packed"); // `Air.Legalize.Feature.expand_packed_struct_field_val` handles this case
60635251 const field_name: CValue = switch (ip.indexToKey(struct_ty.toIntern())) {
60645252 .struct_type => .{ .identifier = struct_ty.structFieldName(extra.field_index, zcu).unwrap().?.toSlice(ip) },
60655253 .union_type => name: {
60665254 const union_type = ip.loadUnionType(struct_ty.toIntern());
6067 const enum_tag_ty: Type = .fromInterned(union_type.enum_tag_ty);
5255 const enum_tag_ty: Type = .fromInterned(union_type.enum_tag_type);
60685256 const field_name_str = enum_tag_ty.enumFieldName(extra.field_index, zcu).toSlice(ip);
6069 if (union_type.hasTag(ip)) {
6070 break :name .{ .payload_identifier = field_name_str };
6071 } else {
6072 break :name .{ .identifier = field_name_str };
6073 }
5257 break :name .{ .payload_identifier = field_name_str };
60745258 },
60755259 .tuple_type => .{ .field = extra.field_index },
60765260 else => unreachable,
60775261 };
60785262
60795263 const local = try f.allocLocal(inst, inst_ty);
6080 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
6081 try f.writeCValue(w, local, .Other);
6082 try a.assign(f, w);
5264 try f.writeCValue(w, local, .other);
5265 try w.writeAll(" = ");
60835266 try f.writeCValueMember(w, struct_byval, field_name);
6084 try a.end(f, w);
5267 try w.writeByte(';');
5268 try f.newline();
60855269 return local;
60865270}
60875271
60885272/// *(E!T) -> E
60895273/// Note that the result is never a pointer.
60905274fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
6091 const pt = f.object.dg.pt;
5275 const pt = f.dg.pt;
60925276 const zcu = pt.zcu;
60935277 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
60945278
......@@ -6098,37 +5282,23 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
60985282 try reap(f, inst, &.{ty_op.operand});
60995283
61005284 const operand_is_ptr = operand_ty.zigTypeTag(zcu) == .pointer;
6101 const error_union_ty = if (operand_is_ptr) operand_ty.childType(zcu) else operand_ty;
6102 const error_ty = error_union_ty.errorUnionSet(zcu);
6103 const payload_ty = error_union_ty.errorUnionPayload(zcu);
61045285 const local = try f.allocLocal(inst, inst_ty);
61055286
6106 if (!payload_ty.hasRuntimeBits(zcu) and operand == .local and operand.local == local.new_local) {
6107 // The store will be 'x = x'; elide it.
6108 return local;
6109 }
6110
6111 const w = &f.object.code.writer;
6112 try f.writeCValue(w, local, .Other);
5287 const w = &f.code.writer;
5288 try f.writeCValue(w, local, .other);
61135289 try w.writeAll(" = ");
61145290
6115 if (!payload_ty.hasRuntimeBits(zcu))
6116 try f.writeCValue(w, operand, .Other)
6117 else if (error_ty.errorSetIsEmpty(zcu))
6118 try w.print("{f}", .{
6119 try f.fmtIntLiteralDec(try pt.intValue(try pt.errorIntType(), 0)),
6120 })
6121 else if (operand_is_ptr)
5291 if (operand_is_ptr)
61225292 try f.writeCValueDerefMember(w, operand, .{ .identifier = "error" })
61235293 else
61245294 try f.writeCValueMember(w, operand, .{ .identifier = "error" });
61255295 try w.writeByte(';');
6126 try f.object.newline();
5296 try f.newline();
61275297 return local;
61285298}
61295299
61305300fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue {
6131 const pt = f.object.dg.pt;
5301 const pt = f.dg.pt;
61325302 const zcu = pt.zcu;
61335303 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
61345304
......@@ -6138,154 +5308,124 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
61385308 const operand_ty = f.typeOf(ty_op.operand);
61395309 const error_union_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;
61405310
6141 const w = &f.object.code.writer;
5311 const w = &f.code.writer;
61425312 if (!error_union_ty.errorUnionPayload(zcu).hasRuntimeBits(zcu)) {
6143 if (!is_ptr) return .none;
6144
5313 assert(is_ptr); // opv bug in sema
61455314 const local = try f.allocLocal(inst, inst_ty);
6146 try f.writeCValue(w, local, .Other);
5315 try f.writeCValue(w, local, .other);
61475316 try w.writeAll(" = (");
61485317 try f.renderType(w, inst_ty);
61495318 try w.writeByte(')');
6150 try f.writeCValue(w, operand, .Other);
5319 try f.writeCValue(w, operand, .other);
61515320 try w.writeByte(';');
6152 try f.object.newline();
5321 try f.newline();
61535322 return local;
61545323 }
61555324
61565325 const local = try f.allocLocal(inst, inst_ty);
6157 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
6158 try f.writeCValue(w, local, .Other);
6159 try a.assign(f, w);
5326 try f.writeCValue(w, local, .other);
5327 try w.writeAll(" = ");
61605328 if (is_ptr) {
61615329 try w.writeByte('&');
61625330 try f.writeCValueDerefMember(w, operand, .{ .identifier = "payload" });
61635331 } else try f.writeCValueMember(w, operand, .{ .identifier = "payload" });
6164 try a.end(f, w);
5332 try w.writeByte(';');
5333 try f.newline();
61655334 return local;
61665335}
61675336
61685337fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
6169 const ctype_pool = &f.object.dg.ctype_pool;
5338 const zcu = f.dg.pt.zcu;
61705339 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
61715340
61725341 const inst_ty = f.typeOfIndex(inst);
6173 const inst_ctype = try f.ctypeFromType(inst_ty, .complete);
6174 if (inst_ctype.isBool()) return .{ .constant = Value.true };
61755342
61765343 const operand = try f.resolveInst(ty_op.operand);
6177 switch (inst_ctype.info(ctype_pool)) {
6178 .basic, .pointer => return f.moveCValue(inst, inst_ty, operand),
6179 .aligned, .array, .vector, .fwd_decl, .function => unreachable,
6180 .aggregate => |aggregate| switch (aggregate.fields.at(0, ctype_pool).name.index) {
6181 .is_null, .payload => {
6182 const operand_ctype = try f.ctypeFromType(f.typeOf(ty_op.operand), .complete);
6183 const w = &f.object.code.writer;
6184 const local = try f.allocLocal(inst, inst_ty);
6185 {
6186 const a = try Assignment.start(f, w, .bool);
6187 try f.writeCValueMember(w, local, .{ .identifier = "is_null" });
6188 try a.assign(f, w);
6189 try w.writeAll("false");
6190 try a.end(f, w);
6191 }
6192 {
6193 const a = try Assignment.start(f, w, operand_ctype);
6194 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
6195 try a.assign(f, w);
6196 try f.writeCValue(w, operand, .Other);
6197 try a.end(f, w);
6198 }
6199 return local;
6200 },
6201 .ptr, .len => return f.moveCValue(inst, inst_ty, operand),
6202 else => unreachable,
5344
5345 switch (CType.classifyOptional(inst_ty, zcu)) {
5346 .npv_payload => unreachable, // opv optional
5347
5348 .opv_payload => unreachable, // opv bug in Sema
5349
5350 .error_set,
5351 .ptr_like,
5352 .slice_like,
5353 => return f.moveCValue(inst, inst_ty, operand),
5354
5355 .@"struct" => {
5356 const w = &f.code.writer;
5357 const local = try f.allocLocal(inst, inst_ty);
5358
5359 try f.writeCValueMember(w, local, .{ .identifier = "is_null" });
5360 try w.writeAll(" = false;");
5361 try f.newline();
5362
5363 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
5364 try w.writeAll(" = ");
5365 try f.writeCValue(w, operand, .other);
5366 try w.writeByte(';');
5367 try f.newline();
5368
5369 return local;
62035370 },
62045371 }
62055372}
62065373
62075374fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
6208 const pt = f.object.dg.pt;
5375 const pt = f.dg.pt;
62095376 const zcu = pt.zcu;
62105377 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
62115378
62125379 const inst_ty = f.typeOfIndex(inst);
62135380 const payload_ty = inst_ty.errorUnionPayload(zcu);
6214 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(zcu);
6215 const err_ty = inst_ty.errorUnionSet(zcu);
62165381 const err = try f.resolveInst(ty_op.operand);
62175382 try reap(f, inst, &.{ty_op.operand});
62185383
6219 const w = &f.object.code.writer;
5384 const w = &f.code.writer;
62205385 const local = try f.allocLocal(inst, inst_ty);
62215386
6222 if (repr_is_err and err == .local and err.local == local.new_local) {
6223 // The store will be 'x = x'; elide it.
6224 return local;
6225 }
6226
6227 if (!repr_is_err) {
6228 const a = try Assignment.start(f, w, try f.ctypeFromType(payload_ty, .complete));
5387 if (payload_ty.hasRuntimeBits(zcu)) {
62295388 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
6230 try a.assign(f, w);
6231 try f.object.dg.renderUndefValue(w, payload_ty, .Other);
6232 try a.end(f, w);
6233 }
6234 {
6235 const a = try Assignment.start(f, w, try f.ctypeFromType(err_ty, .complete));
6236 if (repr_is_err)
6237 try f.writeCValue(w, local, .Other)
6238 else
6239 try f.writeCValueMember(w, local, .{ .identifier = "error" });
6240 try a.assign(f, w);
6241 try f.writeCValue(w, err, .Other);
6242 try a.end(f, w);
5389 try w.writeAll(" = ");
5390 try f.dg.renderUndefValue(w, payload_ty, .other);
5391 try w.writeByte(';');
5392 try f.newline();
62435393 }
5394
5395 try f.writeCValueMember(w, local, .{ .identifier = "error" });
5396 try w.writeAll(" = ");
5397 try f.writeCValue(w, err, .other);
5398 try w.writeByte(';');
5399 try f.newline();
5400
62445401 return local;
62455402}
62465403
62475404fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
6248 const pt = f.object.dg.pt;
6249 const zcu = pt.zcu;
6250 const w = &f.object.code.writer;
5405 const pt = f.dg.pt;
5406 const w = &f.code.writer;
62515407 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
62525408 const inst_ty = f.typeOfIndex(inst);
62535409 const operand = try f.resolveInst(ty_op.operand);
6254 const operand_ty = f.typeOf(ty_op.operand);
6255 const error_union_ty = operand_ty.childType(zcu);
62565410
6257 const payload_ty = error_union_ty.errorUnionPayload(zcu);
62585411 const err_int_ty = try pt.errorIntType();
62595412 const no_err = try pt.intValue(err_int_ty, 0);
62605413 try reap(f, inst, &.{ty_op.operand});
62615414
62625415 // First, set the non-error value.
6263 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
6264 const a = try Assignment.start(f, w, try f.ctypeFromType(operand_ty, .complete));
6265 try f.writeCValueDeref(w, operand);
6266 try a.assign(f, w);
6267 try w.print("{f}", .{try f.fmtIntLiteralDec(no_err)});
6268 try a.end(f, w);
6269 return .none;
6270 }
6271 {
6272 const a = try Assignment.start(f, w, try f.ctypeFromType(err_int_ty, .complete));
6273 try f.writeCValueDerefMember(w, operand, .{ .identifier = "error" });
6274 try a.assign(f, w);
6275 try w.print("{f}", .{try f.fmtIntLiteralDec(no_err)});
6276 try a.end(f, w);
6277 }
5416 try f.writeCValueDerefMember(w, operand, .{ .identifier = "error" });
5417 try w.print(" = {f};", .{try f.fmtIntLiteralDec(no_err)});
5418 try f.newline();
62785419
62795420 // Then return the payload pointer (only if it is used)
62805421 if (f.liveness.isUnused(inst)) return .none;
62815422
62825423 const local = try f.allocLocal(inst, inst_ty);
6283 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
6284 try f.writeCValue(w, local, .Other);
6285 try a.assign(f, w);
6286 try w.writeByte('&');
5424 try f.writeCValue(w, local, .other);
5425 try w.writeAll(" = &");
62875426 try f.writeCValueDerefMember(w, operand, .{ .identifier = "payload" });
6288 try a.end(f, w);
5427 try w.writeByte(';');
5428 try f.newline();
62895429 return local;
62905430}
62915431
......@@ -6305,131 +5445,96 @@ fn airSaveErrReturnTraceIndex(f: *Function, inst: Air.Inst.Index) !CValue {
63055445}
63065446
63075447fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
6308 const pt = f.object.dg.pt;
5448 const pt = f.dg.pt;
63095449 const zcu = pt.zcu;
63105450 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
63115451
63125452 const inst_ty = f.typeOfIndex(inst);
63135453 const payload_ty = inst_ty.errorUnionPayload(zcu);
63145454 const payload = try f.resolveInst(ty_op.operand);
6315 const repr_is_err = !payload_ty.hasRuntimeBitsIgnoreComptime(zcu);
6316 const err_ty = inst_ty.errorUnionSet(zcu);
5455 assert(payload_ty.hasRuntimeBits(zcu));
63175456 try reap(f, inst, &.{ty_op.operand});
63185457
6319 const w = &f.object.code.writer;
5458 const w = &f.code.writer;
63205459 const local = try f.allocLocal(inst, inst_ty);
6321 if (!repr_is_err) {
6322 const a = try Assignment.start(f, w, try f.ctypeFromType(payload_ty, .complete));
6323 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
6324 try a.assign(f, w);
6325 try f.writeCValue(w, payload, .Other);
6326 try a.end(f, w);
6327 }
6328 {
6329 const a = try Assignment.start(f, w, try f.ctypeFromType(err_ty, .complete));
6330 if (repr_is_err)
6331 try f.writeCValue(w, local, .Other)
6332 else
6333 try f.writeCValueMember(w, local, .{ .identifier = "error" });
6334 try a.assign(f, w);
6335 try f.object.dg.renderValue(w, try pt.intValue(try pt.errorIntType(), 0), .Other);
6336 try a.end(f, w);
6337 }
5460
5461 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
5462 try w.writeAll(" = ");
5463 try f.writeCValue(w, payload, .other);
5464 try w.writeByte(';');
5465 try f.newline();
5466
5467 try f.writeCValueMember(w, local, .{ .identifier = "error" });
5468 try w.writeAll(" = ");
5469 try f.dg.renderValue(w, try pt.intValue(try pt.errorIntType(), 0), .other);
5470 try w.writeByte(';');
5471 try f.newline();
5472
63385473 return local;
63395474}
63405475
63415476fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const u8) !CValue {
6342 const pt = f.object.dg.pt;
6343 const zcu = pt.zcu;
5477 const pt = f.dg.pt;
63445478 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
63455479
6346 const w = &f.object.code.writer;
5480 const w = &f.code.writer;
63475481 const operand = try f.resolveInst(un_op);
63485482 try reap(f, inst, &.{un_op});
6349 const operand_ty = f.typeOf(un_op);
63505483 const local = try f.allocLocal(inst, .bool);
6351 const err_union_ty = if (is_ptr) operand_ty.childType(zcu) else operand_ty;
6352 const payload_ty = err_union_ty.errorUnionPayload(zcu);
6353 const error_ty = err_union_ty.errorUnionSet(zcu);
63545484
6355 const a = try Assignment.start(f, w, .bool);
6356 try f.writeCValue(w, local, .Other);
6357 try a.assign(f, w);
5485 try f.writeCValue(w, local, .other);
5486 try w.writeAll(" = ");
63585487 const err_int_ty = try pt.errorIntType();
6359 if (!error_ty.errorSetIsEmpty(zcu))
6360 if (payload_ty.hasRuntimeBits(zcu))
6361 if (is_ptr)
6362 try f.writeCValueDerefMember(w, operand, .{ .identifier = "error" })
6363 else
6364 try f.writeCValueMember(w, operand, .{ .identifier = "error" })
6365 else
6366 try f.writeCValue(w, operand, .Other)
5488 if (is_ptr)
5489 try f.writeCValueDerefMember(w, operand, .{ .identifier = "error" })
63675490 else
6368 try f.object.dg.renderValue(w, try pt.intValue(err_int_ty, 0), .Other);
6369 try w.writeByte(' ');
6370 try w.writeAll(operator);
6371 try w.writeByte(' ');
6372 try f.object.dg.renderValue(w, try pt.intValue(err_int_ty, 0), .Other);
6373 try a.end(f, w);
5491 try f.writeCValueMember(w, operand, .{ .identifier = "error" });
5492 try w.print(" {s} ", .{operator});
5493 try f.dg.renderValue(w, try pt.intValue(err_int_ty, 0), .other);
5494 try w.writeByte(';');
5495 try f.newline();
63745496 return local;
63755497}
63765498
63775499fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
6378 const pt = f.object.dg.pt;
5500 const pt = f.dg.pt;
63795501 const zcu = pt.zcu;
6380 const ctype_pool = &f.object.dg.ctype_pool;
63815502 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
63825503
63835504 const operand = try f.resolveInst(ty_op.operand);
63845505 try reap(f, inst, &.{ty_op.operand});
63855506 const inst_ty = f.typeOfIndex(inst);
6386 const ptr_ty = inst_ty.slicePtrFieldType(zcu);
6387 const w = &f.object.code.writer;
5507 const w = &f.code.writer;
63885508 const local = try f.allocLocal(inst, inst_ty);
63895509 const operand_ty = f.typeOf(ty_op.operand);
63905510 const array_ty = operand_ty.childType(zcu);
63915511
6392 {
6393 const a = try Assignment.start(f, w, try f.ctypeFromType(ptr_ty, .complete));
6394 try f.writeCValueMember(w, local, .{ .identifier = "ptr" });
6395 try a.assign(f, w);
6396 if (operand == .undef) {
6397 try f.writeCValue(w, .{ .undef = inst_ty.slicePtrFieldType(zcu) }, .Other);
6398 } else {
6399 const ptr_ctype = try f.ctypeFromType(ptr_ty, .complete);
6400 const ptr_child_ctype = ptr_ctype.info(ctype_pool).pointer.elem_ctype;
6401 const elem_ty = array_ty.childType(zcu);
6402 const elem_ctype = try f.ctypeFromType(elem_ty, .complete);
6403 if (!ptr_child_ctype.eql(elem_ctype)) {
6404 try w.writeByte('(');
6405 try f.renderCType(w, ptr_ctype);
6406 try w.writeByte(')');
6407 }
6408 const operand_ctype = try f.ctypeFromType(operand_ty, .complete);
6409 const operand_child_ctype = operand_ctype.info(ctype_pool).pointer.elem_ctype;
6410 if (operand_child_ctype.info(ctype_pool) == .array) {
6411 try w.writeByte('&');
6412 try f.writeCValueDeref(w, operand);
6413 try w.print("[{f}]", .{try f.fmtIntLiteralDec(.zero_usize)});
6414 } else try f.writeCValue(w, operand, .Other);
6415 }
6416 try a.end(f, w);
6417 }
6418 {
6419 const a = try Assignment.start(f, w, .usize);
6420 try f.writeCValueMember(w, local, .{ .identifier = "len" });
6421 try a.assign(f, w);
6422 try w.print("{f}", .{
6423 try f.fmtIntLiteralDec(try pt.intValue(.usize, array_ty.arrayLen(zcu))),
6424 });
6425 try a.end(f, w);
6426 }
5512 // We have a `*[n]T`, which was turned into to a pointer to `struct { T array[n]; }`.
5513 // Ideally we would want to use 'operand->array' to convert to a `T *` (we get a `T []`
5514 // which decays to a pointer), but if the element type is zero-bit or the array length is
5515 // zero, there will not be an `array` member (the array type lowers to `void`). We cannot
5516 // check the type layout here because it may not be resolved, so in this instance, we must
5517 // use a pointer cast.
5518 try f.writeCValueMember(w, local, .{ .identifier = "ptr" });
5519 try w.writeAll(" = (");
5520 try f.dg.renderType(w, inst_ty.slicePtrFieldType(zcu));
5521 try w.writeByte(')');
5522 try f.writeCValue(w, operand, .other);
5523 try w.writeByte(';');
5524 try f.newline();
5525
5526 try f.writeCValueMember(w, local, .{ .identifier = "len" });
5527 try w.print(" = {f}", .{
5528 try f.fmtIntLiteralDec(try pt.intValue(.usize, array_ty.arrayLen(zcu))),
5529 });
5530 try w.writeByte(';');
5531 try f.newline();
64275532
64285533 return local;
64295534}
64305535
64315536fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
6432 const pt = f.object.dg.pt;
5537 const pt = f.dg.pt;
64335538 const zcu = pt.zcu;
64345539 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
64355540
......@@ -6439,7 +5544,7 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
64395544 try reap(f, inst, &.{ty_op.operand});
64405545 const operand_ty = f.typeOf(ty_op.operand);
64415546 const scalar_ty = operand_ty.scalarType(zcu);
6442 const target = &f.object.dg.mod.resolved_target.result;
5547 const target = &f.dg.mod.resolved_target.result;
64435548 const operation = if (inst_scalar_ty.isRuntimeFloat() and scalar_ty.isRuntimeFloat())
64445549 if (inst_scalar_ty.floatBits(target) < scalar_ty.floatBits(target)) "trunc" else "extend"
64455550 else if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat())
......@@ -6449,16 +5554,15 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
64495554 else
64505555 unreachable;
64515556
6452 const w = &f.object.code.writer;
5557 const w = &f.code.writer;
64535558 const local = try f.allocLocal(inst, inst_ty);
64545559 const v = try Vectorize.start(f, inst, w, operand_ty);
6455 const a = try Assignment.start(f, w, try f.ctypeFromType(scalar_ty, .complete));
6456 try f.writeCValue(w, local, .Other);
5560 try f.writeCValue(w, local, .other);
64575561 try v.elem(f, w);
6458 try a.assign(f, w);
5562 try w.writeAll(" = ");
64595563 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {
64605564 try w.writeAll("zig_wrap_");
6461 try f.object.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty);
5565 try f.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty);
64625566 try w.writeByte('(');
64635567 }
64645568 try w.writeAll("zig_");
......@@ -6466,14 +5570,15 @@ fn airFloatCast(f: *Function, inst: Air.Inst.Index) !CValue {
64665570 try w.writeAll(compilerRtAbbrev(scalar_ty, zcu, target));
64675571 try w.writeAll(compilerRtAbbrev(inst_scalar_ty, zcu, target));
64685572 try w.writeByte('(');
6469 try f.writeCValue(w, operand, .FunctionArgument);
5573 try f.writeCValue(w, operand, .other);
64705574 try v.elem(f, w);
64715575 try w.writeByte(')');
64725576 if (inst_scalar_ty.isInt(zcu) and scalar_ty.isRuntimeFloat()) {
6473 try f.object.dg.renderBuiltinInfo(w, inst_scalar_ty, .bits);
5577 try f.dg.renderBuiltinInfo(w, inst_scalar_ty, .bits);
64745578 try w.writeByte(')');
64755579 }
6476 try a.end(f, w);
5580 try w.writeByte(';');
5581 try f.newline();
64775582 try v.end(f, inst, w);
64785583
64795584 return local;
......@@ -6486,7 +5591,7 @@ fn airUnBuiltinCall(
64865591 operation: []const u8,
64875592 info: BuiltinInfo,
64885593) !CValue {
6489 const pt = f.object.dg.pt;
5594 const pt = f.dg.pt;
64905595 const zcu = pt.zcu;
64915596
64925597 const operand = try f.resolveInst(operand_ref);
......@@ -6496,30 +5601,32 @@ fn airUnBuiltinCall(
64965601 const operand_ty = f.typeOf(operand_ref);
64975602 const scalar_ty = operand_ty.scalarType(zcu);
64985603
6499 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
6500 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;
5604 const ref_ret = lowersToBigInt(inst_scalar_ty, zcu);
5605 const ref_arg = lowersToBigInt(scalar_ty, zcu);
65015606
6502 const w = &f.object.code.writer;
5607 const w = &f.code.writer;
65035608 const local = try f.allocLocal(inst, inst_ty);
65045609 const v = try Vectorize.start(f, inst, w, operand_ty);
65055610 if (!ref_ret) {
6506 try f.writeCValue(w, local, .Other);
5611 try f.writeCValue(w, local, .other);
65075612 try v.elem(f, w);
65085613 try w.writeAll(" = ");
65095614 }
65105615 try w.print("zig_{s}_", .{operation});
6511 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
5616 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
65125617 try w.writeByte('(');
65135618 if (ref_ret) {
6514 try f.writeCValue(w, local, .FunctionArgument);
5619 try w.writeByte('&');
5620 try f.writeCValue(w, local, .other);
65155621 try v.elem(f, w);
65165622 try w.writeAll(", ");
65175623 }
6518 try f.writeCValue(w, operand, .FunctionArgument);
5624 if (ref_arg) try w.writeByte('&');
5625 try f.writeCValue(w, operand, .other);
65195626 try v.elem(f, w);
6520 try f.object.dg.renderBuiltinInfo(w, scalar_ty, info);
5627 try f.dg.renderBuiltinInfo(w, scalar_ty, info);
65215628 try w.writeAll(");");
6522 try f.object.newline();
5629 try f.newline();
65235630 try v.end(f, inst, w);
65245631
65255632 return local;
......@@ -6531,13 +5638,12 @@ fn airBinBuiltinCall(
65315638 operation: []const u8,
65325639 info: BuiltinInfo,
65335640) !CValue {
6534 const pt = f.object.dg.pt;
5641 const pt = f.dg.pt;
65355642 const zcu = pt.zcu;
65365643 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
65375644
65385645 const operand_ty = f.typeOf(bin_op.lhs);
6539 const operand_ctype = try f.ctypeFromType(operand_ty, .complete);
6540 const is_big = operand_ctype.info(&f.object.dg.ctype_pool) == .array;
5646 const is_big = lowersToBigInt(operand_ty, zcu);
65415647
65425648 const lhs = try f.resolveInst(bin_op.lhs);
65435649 const rhs = try f.resolveInst(bin_op.rhs);
......@@ -6547,32 +5653,35 @@ fn airBinBuiltinCall(
65475653 const inst_scalar_ty = inst_ty.scalarType(zcu);
65485654 const scalar_ty = operand_ty.scalarType(zcu);
65495655
6550 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
6551 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;
5656 const ref_ret = lowersToBigInt(inst_scalar_ty, zcu);
5657 const ref_arg = lowersToBigInt(scalar_ty, zcu);
65525658
6553 const w = &f.object.code.writer;
5659 const w = &f.code.writer;
65545660 const local = try f.allocLocal(inst, inst_ty);
65555661 if (is_big) try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
65565662 const v = try Vectorize.start(f, inst, w, operand_ty);
65575663 if (!ref_ret) {
6558 try f.writeCValue(w, local, .Other);
5664 try f.writeCValue(w, local, .other);
65595665 try v.elem(f, w);
65605666 try w.writeAll(" = ");
65615667 }
65625668 try w.print("zig_{s}_", .{operation});
6563 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
5669 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
65645670 try w.writeByte('(');
65655671 if (ref_ret) {
6566 try f.writeCValue(w, local, .FunctionArgument);
5672 try w.writeByte('&');
5673 try f.writeCValue(w, local, .other);
65675674 try v.elem(f, w);
65685675 try w.writeAll(", ");
65695676 }
6570 try f.writeCValue(w, lhs, .FunctionArgument);
5677 if (ref_arg) try w.writeByte('&');
5678 try f.writeCValue(w, lhs, .other);
65715679 try v.elem(f, w);
65725680 try w.writeAll(", ");
6573 try f.writeCValue(w, rhs, .FunctionArgument);
5681 if (ref_arg) try w.writeByte('&');
5682 try f.writeCValue(w, rhs, .other);
65745683 if (f.typeOf(bin_op.rhs).isVector(zcu)) try v.elem(f, w);
6575 try f.object.dg.renderBuiltinInfo(w, scalar_ty, info);
5684 try f.dg.renderBuiltinInfo(w, scalar_ty, info);
65765685 try w.writeAll(");\n");
65775686 try v.end(f, inst, w);
65785687
......@@ -6587,7 +5696,7 @@ fn airCmpBuiltinCall(
65875696 operation: enum { cmp, operator },
65885697 info: BuiltinInfo,
65895698) !CValue {
6590 const pt = f.object.dg.pt;
5699 const pt = f.dg.pt;
65915700 const zcu = pt.zcu;
65925701 const lhs = try f.resolveInst(data.lhs);
65935702 const rhs = try f.resolveInst(data.rhs);
......@@ -6598,14 +5707,14 @@ fn airCmpBuiltinCall(
65985707 const operand_ty = f.typeOf(data.lhs);
65995708 const scalar_ty = operand_ty.scalarType(zcu);
66005709
6601 const inst_scalar_ctype = try f.ctypeFromType(inst_scalar_ty, .complete);
6602 const ref_ret = inst_scalar_ctype.info(&f.object.dg.ctype_pool) == .array;
5710 const ref_ret = lowersToBigInt(inst_scalar_ty, zcu);
5711 const ref_arg = lowersToBigInt(scalar_ty, zcu);
66035712
6604 const w = &f.object.code.writer;
5713 const w = &f.code.writer;
66055714 const local = try f.allocLocal(inst, inst_ty);
66065715 const v = try Vectorize.start(f, inst, w, operand_ty);
66075716 if (!ref_ret) {
6608 try f.writeCValue(w, local, .Other);
5717 try f.writeCValue(w, local, .other);
66095718 try v.elem(f, w);
66105719 try w.writeAll(" = ");
66115720 }
......@@ -6613,33 +5722,36 @@ fn airCmpBuiltinCall(
66135722 else => @tagName(operation),
66145723 .operator => compareOperatorAbbrev(operator),
66155724 }});
6616 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
5725 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
66175726 try w.writeByte('(');
66185727 if (ref_ret) {
6619 try f.writeCValue(w, local, .FunctionArgument);
5728 try w.writeByte('&');
5729 try f.writeCValue(w, local, .other);
66205730 try v.elem(f, w);
66215731 try w.writeAll(", ");
66225732 }
6623 try f.writeCValue(w, lhs, .FunctionArgument);
5733 if (ref_arg) try w.writeByte('&');
5734 try f.writeCValue(w, lhs, .other);
66245735 try v.elem(f, w);
66255736 try w.writeAll(", ");
6626 try f.writeCValue(w, rhs, .FunctionArgument);
5737 if (ref_arg) try w.writeByte('&');
5738 try f.writeCValue(w, rhs, .other);
66275739 try v.elem(f, w);
6628 try f.object.dg.renderBuiltinInfo(w, scalar_ty, info);
5740 try f.dg.renderBuiltinInfo(w, scalar_ty, info);
66295741 try w.writeByte(')');
66305742 if (!ref_ret) try w.print("{s}{f}", .{
66315743 compareOperatorC(operator),
66325744 try f.fmtIntLiteralDec(try pt.intValue(.i32, 0)),
66335745 });
66345746 try w.writeByte(';');
6635 try f.object.newline();
5747 try f.newline();
66365748 try v.end(f, inst, w);
66375749
66385750 return local;
66395751}
66405752
66415753fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue {
6642 const pt = f.object.dg.pt;
5754 const pt = f.dg.pt;
66435755 const zcu = pt.zcu;
66445756 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
66455757 const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
......@@ -6649,9 +5761,8 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
66495761 const new_value = try f.resolveInst(extra.new_value);
66505762 const ptr_ty = f.typeOf(extra.ptr);
66515763 const ty = ptr_ty.childType(zcu);
6652 const ctype = try f.ctypeFromType(ty, .complete);
66535764
6654 const w = &f.object.code.writer;
5765 const w = &f.code.writer;
66555766 const new_value_mat = try Materialize.start(f, inst, ty, new_value);
66565767 try reap(f, inst, &.{ extra.ptr, extra.expected_value, extra.new_value });
66575768
......@@ -6662,13 +5773,11 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
66625773
66635774 const local = try f.allocLocal(inst, inst_ty);
66645775 if (inst_ty.isPtrLikeOptional(zcu)) {
6665 {
6666 const a = try Assignment.start(f, w, ctype);
6667 try f.writeCValue(w, local, .Other);
6668 try a.assign(f, w);
6669 try f.writeCValue(w, expected_value, .Other);
6670 try a.end(f, w);
6671 }
5776 try f.writeCValue(w, local, .other);
5777 try w.writeAll(" = ");
5778 try f.writeCValue(w, expected_value, .other);
5779 try w.writeByte(';');
5780 try f.newline();
66725781
66735782 try w.writeAll("if (");
66745783 try w.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
......@@ -6676,9 +5785,9 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
66765785 try w.writeByte(')');
66775786 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");
66785787 try w.writeAll(" *)");
6679 try f.writeCValue(w, ptr, .Other);
5788 try f.writeCValue(w, ptr, .other);
66805789 try w.writeAll(", ");
6681 try f.writeCValue(w, local, .FunctionArgument);
5790 try f.writeCValue(w, local, .other);
66825791 try w.writeAll(", ");
66835792 try new_value_mat.mat(f, w);
66845793 try w.writeAll(", ");
......@@ -6686,56 +5795,49 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
66865795 try w.writeAll(", ");
66875796 try writeMemoryOrder(w, extra.failureOrder());
66885797 try w.writeAll(", ");
6689 try f.object.dg.renderTypeForBuiltinFnName(w, ty);
5798 try f.dg.renderTypeForBuiltinFnName(w, ty);
66905799 try w.writeAll(", ");
66915800 try f.renderType(w, repr_ty);
66925801 try w.writeByte(')');
66935802 try w.writeAll(") {");
6694 f.object.indent();
6695 try f.object.newline();
6696 {
6697 const a = try Assignment.start(f, w, ctype);
6698 try f.writeCValue(w, local, .Other);
6699 try a.assign(f, w);
6700 try w.writeAll("NULL");
6701 try a.end(f, w);
6702 }
6703 try f.object.outdent();
5803 f.indent();
5804 try f.newline();
5805
5806 try f.writeCValue(w, local, .other);
5807 try w.writeAll(" = NULL;");
5808 try f.newline();
5809
5810 try f.outdent();
67045811 try w.writeByte('}');
6705 try f.object.newline();
5812 try f.newline();
67065813 } else {
6707 {
6708 const a = try Assignment.start(f, w, ctype);
6709 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
6710 try a.assign(f, w);
6711 try f.writeCValue(w, expected_value, .Other);
6712 try a.end(f, w);
6713 }
6714 {
6715 const a = try Assignment.start(f, w, .bool);
6716 try f.writeCValueMember(w, local, .{ .identifier = "is_null" });
6717 try a.assign(f, w);
6718 try w.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
6719 try f.renderType(w, ty);
6720 try w.writeByte(')');
6721 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");
6722 try w.writeAll(" *)");
6723 try f.writeCValue(w, ptr, .Other);
6724 try w.writeAll(", ");
6725 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
6726 try w.writeAll(", ");
6727 try new_value_mat.mat(f, w);
6728 try w.writeAll(", ");
6729 try writeMemoryOrder(w, extra.successOrder());
6730 try w.writeAll(", ");
6731 try writeMemoryOrder(w, extra.failureOrder());
6732 try w.writeAll(", ");
6733 try f.object.dg.renderTypeForBuiltinFnName(w, ty);
6734 try w.writeAll(", ");
6735 try f.renderType(w, repr_ty);
6736 try w.writeByte(')');
6737 try a.end(f, w);
6738 }
5814 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
5815 try w.writeAll(" = ");
5816 try f.writeCValue(w, expected_value, .other);
5817 try w.writeByte(';');
5818 try f.newline();
5819
5820 try f.writeCValueMember(w, local, .{ .identifier = "is_null" });
5821 try w.print(" = zig_cmpxchg_{s}((zig_atomic(", .{flavor});
5822 try f.renderType(w, ty);
5823 try w.writeByte(')');
5824 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");
5825 try w.writeAll(" *)");
5826 try f.writeCValue(w, ptr, .other);
5827 try w.writeAll(", ");
5828 try f.writeCValueMember(w, local, .{ .identifier = "payload" });
5829 try w.writeAll(", ");
5830 try new_value_mat.mat(f, w);
5831 try w.writeAll(", ");
5832 try writeMemoryOrder(w, extra.successOrder());
5833 try w.writeAll(", ");
5834 try writeMemoryOrder(w, extra.failureOrder());
5835 try w.writeAll(", ");
5836 try f.dg.renderTypeForBuiltinFnName(w, ty);
5837 try w.writeAll(", ");
5838 try f.renderType(w, repr_ty);
5839 try w.writeAll(");");
5840 try f.newline();
67395841 }
67405842 try new_value_mat.end(f, inst);
67415843
......@@ -6748,7 +5850,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
67485850}
67495851
67505852fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6751 const pt = f.object.dg.pt;
5853 const pt = f.dg.pt;
67525854 const zcu = pt.zcu;
67535855 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
67545856 const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data;
......@@ -6758,7 +5860,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
67585860 const ptr = try f.resolveInst(pl_op.operand);
67595861 const operand = try f.resolveInst(extra.operand);
67605862
6761 const w = &f.object.code.writer;
5863 const w = &f.code.writer;
67625864 const operand_mat = try Materialize.start(f, inst, ty, operand);
67635865 try reap(f, inst, &.{ pl_op.operand, extra.operand });
67645866
......@@ -6771,7 +5873,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
67715873 try w.print("zig_atomicrmw_{s}", .{toAtomicRmwSuffix(extra.op())});
67725874 if (is_float) try w.writeAll("_float") else if (is_128) try w.writeAll("_int128");
67735875 try w.writeByte('(');
6774 try f.writeCValue(w, local, .Other);
5876 try f.writeCValue(w, local, .other);
67755877 try w.writeAll(", (");
67765878 const use_atomic = switch (extra.op()) {
67775879 else => true,
......@@ -6783,17 +5885,17 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
67835885 if (use_atomic) try w.writeByte(')');
67845886 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");
67855887 try w.writeAll(" *)");
6786 try f.writeCValue(w, ptr, .Other);
5888 try f.writeCValue(w, ptr, .other);
67875889 try w.writeAll(", ");
67885890 try operand_mat.mat(f, w);
67895891 try w.writeAll(", ");
67905892 try writeMemoryOrder(w, extra.ordering());
67915893 try w.writeAll(", ");
6792 try f.object.dg.renderTypeForBuiltinFnName(w, ty);
5894 try f.dg.renderTypeForBuiltinFnName(w, ty);
67935895 try w.writeAll(", ");
67945896 try f.renderType(w, repr_ty);
67955897 try w.writeAll(");");
6796 try f.object.newline();
5898 try f.newline();
67975899 try operand_mat.end(f, inst);
67985900
67995901 if (f.liveness.isUnused(inst)) {
......@@ -6805,7 +5907,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
68055907}
68065908
68075909fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
6808 const pt = f.object.dg.pt;
5910 const pt = f.dg.pt;
68095911 const zcu = pt.zcu;
68105912 const atomic_load = f.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
68115913 const ptr = try f.resolveInst(atomic_load.ptr);
......@@ -6819,31 +5921,31 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
68195921 ty;
68205922
68215923 const inst_ty = f.typeOfIndex(inst);
6822 const w = &f.object.code.writer;
5924 const w = &f.code.writer;
68235925 const local = try f.allocLocal(inst, inst_ty);
68245926
68255927 try w.writeAll("zig_atomic_load(");
6826 try f.writeCValue(w, local, .Other);
5928 try f.writeCValue(w, local, .other);
68275929 try w.writeAll(", (zig_atomic(");
68285930 try f.renderType(w, ty);
68295931 try w.writeByte(')');
68305932 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");
68315933 try w.writeAll(" *)");
6832 try f.writeCValue(w, ptr, .Other);
5934 try f.writeCValue(w, ptr, .other);
68335935 try w.writeAll(", ");
68345936 try writeMemoryOrder(w, atomic_load.order);
68355937 try w.writeAll(", ");
6836 try f.object.dg.renderTypeForBuiltinFnName(w, ty);
5938 try f.dg.renderTypeForBuiltinFnName(w, ty);
68375939 try w.writeAll(", ");
68385940 try f.renderType(w, repr_ty);
68395941 try w.writeAll(");");
6840 try f.object.newline();
5942 try f.newline();
68415943
68425944 return local;
68435945}
68445946
68455947fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue {
6846 const pt = f.object.dg.pt;
5948 const pt = f.dg.pt;
68475949 const zcu = pt.zcu;
68485950 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
68495951 const ptr_ty = f.typeOf(bin_op.lhs);
......@@ -6851,7 +5953,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
68515953 const ptr = try f.resolveInst(bin_op.lhs);
68525954 const element = try f.resolveInst(bin_op.rhs);
68535955
6854 const w = &f.object.code.writer;
5956 const w = &f.code.writer;
68555957 const element_mat = try Materialize.start(f, inst, ty, element);
68565958 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
68575959
......@@ -6865,32 +5967,22 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
68655967 try w.writeByte(')');
68665968 if (ptr_ty.isVolatilePtr(zcu)) try w.writeAll(" volatile");
68675969 try w.writeAll(" *)");
6868 try f.writeCValue(w, ptr, .Other);
5970 try f.writeCValue(w, ptr, .other);
68695971 try w.writeAll(", ");
68705972 try element_mat.mat(f, w);
68715973 try w.print(", {s}, ", .{order});
6872 try f.object.dg.renderTypeForBuiltinFnName(w, ty);
5974 try f.dg.renderTypeForBuiltinFnName(w, ty);
68735975 try w.writeAll(", ");
68745976 try f.renderType(w, repr_ty);
68755977 try w.writeAll(");");
6876 try f.object.newline();
5978 try f.newline();
68775979 try element_mat.end(f, inst);
68785980
68795981 return .none;
68805982}
68815983
6882fn writeSliceOrPtr(f: *Function, w: *Writer, ptr: CValue, ptr_ty: Type) !void {
6883 const pt = f.object.dg.pt;
6884 const zcu = pt.zcu;
6885 if (ptr_ty.isSlice(zcu)) {
6886 try f.writeCValueMember(w, ptr, .{ .identifier = "ptr" });
6887 } else {
6888 try f.writeCValue(w, ptr, .FunctionArgument);
6889 }
6890}
6891
68925984fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
6893 const pt = f.object.dg.pt;
5985 const pt = f.dg.pt;
68945986 const zcu = pt.zcu;
68955987 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
68965988 const dest_ty = f.typeOf(bin_op.lhs);
......@@ -6899,7 +5991,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
68995991 const elem_ty = f.typeOf(bin_op.rhs);
69005992 const elem_abi_size = elem_ty.abiSize(zcu);
69015993 const val_is_undef = if (try f.air.value(bin_op.rhs, pt)) |val| val.isUndef(zcu) else false;
6902 const w = &f.object.code.writer;
5994 const w = &f.code.writer;
69035995
69045996 if (val_is_undef) {
69055997 if (!safety) {
......@@ -6913,153 +6005,128 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue {
69136005 try f.writeCValueMember(w, dest_slice, .{ .identifier = "ptr" });
69146006 try w.writeAll(", 0xaa, ");
69156007 try f.writeCValueMember(w, dest_slice, .{ .identifier = "len" });
6916 if (elem_abi_size > 1) {
6917 try w.print(" * {d}", .{elem_abi_size});
6918 }
6919 try w.writeAll(");");
6920 try f.object.newline();
69216008 },
69226009 .one => {
6923 const array_ty = dest_ty.childType(zcu);
6924 const len = array_ty.arrayLen(zcu) * elem_abi_size;
6925
6926 try f.writeCValue(w, dest_slice, .FunctionArgument);
6927 try w.print(", 0xaa, {d});", .{len});
6928 try f.object.newline();
6010 try f.writeCValue(w, dest_slice, .other);
6011 try w.print(", 0xaa, {d}", .{dest_ty.childType(zcu).arrayLen(zcu)});
69296012 },
69306013 .many, .c => unreachable,
69316014 }
6015 if (elem_abi_size > 0) try w.print(" * {d}", .{elem_abi_size});
6016 try w.writeAll(");");
6017 try f.newline();
69326018 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
69336019 return .none;
69346020 }
69356021
6936 if (elem_abi_size > 1 or dest_ty.isVolatilePtr(zcu)) {
6937 // For the assignment in this loop, the array pointer needs to get
6938 // casted to a regular pointer, otherwise an error like this occurs:
6939 // error: array type 'uint32_t[20]' (aka 'unsigned int[20]') is not assignable
6940 const elem_ptr_ty = try pt.ptrType(.{
6941 .child = elem_ty.toIntern(),
6942 .flags = .{
6943 .size = .c,
6944 },
6945 });
6946
6947 const index = try f.allocLocal(inst, .usize);
6948
6949 try w.writeAll("for (");
6950 try f.writeCValue(w, index, .Other);
6951 try w.writeAll(" = ");
6952 try f.object.dg.renderValue(w, .zero_usize, .Other);
6953 try w.writeAll("; ");
6954 try f.writeCValue(w, index, .Other);
6955 try w.writeAll(" != ");
6022 if (elem_abi_size == 1 and !dest_ty.isVolatilePtr(zcu)) {
6023 const bitcasted = try bitcast(f, .u8, value, elem_ty);
6024 try w.writeAll("memset(");
69566025 switch (dest_ty.ptrSize(zcu)) {
69576026 .slice => {
6027 try f.writeCValueMember(w, dest_slice, .{ .identifier = "ptr" });
6028 try w.writeAll(", ");
6029 try f.writeCValue(w, bitcasted, .other);
6030 try w.writeAll(", ");
69586031 try f.writeCValueMember(w, dest_slice, .{ .identifier = "len" });
69596032 },
69606033 .one => {
6961 const array_ty = dest_ty.childType(zcu);
6962 try w.print("{d}", .{array_ty.arrayLen(zcu)});
6034 try f.writeCValue(w, dest_slice, .other);
6035 try w.writeAll(", ");
6036 try f.writeCValue(w, bitcasted, .other);
6037 try w.print(", {d}", .{dest_ty.childType(zcu).arrayLen(zcu)});
69636038 },
69646039 .many, .c => unreachable,
69656040 }
6966 try w.writeAll("; ++");
6967 try f.writeCValue(w, index, .Other);
6968 try w.writeAll(") ");
6969
6970 const a = try Assignment.start(f, w, try f.ctypeFromType(elem_ty, .complete));
6971 try w.writeAll("((");
6972 try f.renderType(w, elem_ptr_ty);
6973 try w.writeByte(')');
6974 try writeSliceOrPtr(f, w, dest_slice, dest_ty);
6975 try w.writeAll(")[");
6976 try f.writeCValue(w, index, .Other);
6977 try w.writeByte(']');
6978 try a.assign(f, w);
6979 try f.writeCValue(w, value, .Other);
6980 try a.end(f, w);
6981
6041 try w.writeAll(");");
6042 try f.newline();
6043 try f.freeCValue(inst, bitcasted);
69826044 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
6983 try freeLocal(f, inst, index.new_local, null);
6984
69856045 return .none;
69866046 }
69876047
6988 const bitcasted = try bitcast(f, .u8, value, elem_ty);
6048 // Fallback path: use a `for` loop.
69896049
6990 try w.writeAll("memset(");
6050 const index = try f.allocLocal(inst, .usize);
6051
6052 try w.writeAll("for (");
6053 try f.writeCValue(w, index, .other);
6054 try w.writeAll(" = ");
6055 try f.dg.renderValue(w, .zero_usize, .other);
6056 try w.writeAll("; ");
6057 try f.writeCValue(w, index, .other);
6058 try w.writeAll(" != ");
69916059 switch (dest_ty.ptrSize(zcu)) {
6992 .slice => {
6993 try f.writeCValueMember(w, dest_slice, .{ .identifier = "ptr" });
6994 try w.writeAll(", ");
6995 try f.writeCValue(w, bitcasted, .FunctionArgument);
6996 try w.writeAll(", ");
6997 try f.writeCValueMember(w, dest_slice, .{ .identifier = "len" });
6998 try w.writeAll(");");
6999 try f.object.newline();
7000 },
7001 .one => {
7002 const array_ty = dest_ty.childType(zcu);
7003 const len = array_ty.arrayLen(zcu) * elem_abi_size;
6060 .slice => try f.writeCValueMember(w, dest_slice, .{ .identifier = "len" }),
6061 .one => try w.print("{d}", .{dest_ty.childType(zcu).arrayLen(zcu)}),
6062 .many, .c => unreachable,
6063 }
6064 try w.writeAll("; ++");
6065 try f.writeCValue(w, index, .other);
6066 try w.writeAll(") ");
70046067
7005 try f.writeCValue(w, dest_slice, .FunctionArgument);
7006 try w.writeAll(", ");
7007 try f.writeCValue(w, bitcasted, .FunctionArgument);
7008 try w.print(", {d});", .{len});
7009 try f.object.newline();
7010 },
6068 switch (dest_ty.ptrSize(zcu)) {
6069 .slice => try f.writeCValueMember(w, dest_slice, .{ .identifier = "ptr" }),
6070 .one => try f.writeCValueDerefMember(w, dest_slice, .{ .identifier = "array" }),
70116071 .many, .c => unreachable,
70126072 }
7013 try f.freeCValue(inst, bitcasted);
6073 try w.writeByte('[');
6074 try f.writeCValue(w, index, .other);
6075 try w.writeAll("] = ");
6076 try f.writeCValue(w, value, .other);
6077 try w.writeByte(';');
6078 try f.newline();
6079
70146080 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
6081 try freeLocal(f, inst, index.new_local, null);
6082
70156083 return .none;
70166084}
70176085
70186086fn airMemcpy(f: *Function, inst: Air.Inst.Index, function_paren: []const u8) !CValue {
7019 const pt = f.object.dg.pt;
6087 const pt = f.dg.pt;
70206088 const zcu = pt.zcu;
70216089 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
70226090 const dest_ptr = try f.resolveInst(bin_op.lhs);
70236091 const src_ptr = try f.resolveInst(bin_op.rhs);
70246092 const dest_ty = f.typeOf(bin_op.lhs);
70256093 const src_ty = f.typeOf(bin_op.rhs);
7026 const w = &f.object.code.writer;
6094 const w = &f.code.writer;
70276095
70286096 if (dest_ty.ptrSize(zcu) != .one) {
70296097 try w.writeAll("if (");
7030 try writeArrayLen(f, dest_ptr, dest_ty);
6098 try f.writeCValueMember(w, dest_ptr, .{ .identifier = "len" });
70316099 try w.writeAll(" != 0) ");
70326100 }
70336101 try w.writeAll(function_paren);
7034 try writeSliceOrPtr(f, w, dest_ptr, dest_ty);
6102 switch (dest_ty.ptrSize(zcu)) {
6103 .slice => try f.writeCValueMember(w, dest_ptr, .{ .identifier = "ptr" }),
6104 .one => try f.writeCValueDerefMember(w, dest_ptr, .{ .identifier = "array" }),
6105 .many, .c => unreachable,
6106 }
70356107 try w.writeAll(", ");
7036 try writeSliceOrPtr(f, w, src_ptr, src_ty);
6108 switch (src_ty.ptrSize(zcu)) {
6109 .slice => try f.writeCValueMember(w, src_ptr, .{ .identifier = "ptr" }),
6110 .one => try f.writeCValueDerefMember(w, src_ptr, .{ .identifier = "array" }),
6111 .many, .c => try f.writeCValue(w, src_ptr, .other),
6112 }
70376113 try w.writeAll(", ");
7038 try writeArrayLen(f, dest_ptr, dest_ty);
6114 switch (dest_ty.ptrSize(zcu)) {
6115 .slice => try f.writeCValueMember(w, dest_ptr, .{ .identifier = "len" }),
6116 .one => try w.print("{d}", .{dest_ty.childType(zcu).arrayLen(zcu)}),
6117 .many, .c => unreachable,
6118 }
70396119 try w.writeAll(" * sizeof(");
7040 try f.renderType(w, dest_ty.elemType2(zcu));
6120 try f.renderType(w, dest_ty.indexableElem(zcu));
70416121 try w.writeAll("));");
7042 try f.object.newline();
6122 try f.newline();
70436123
70446124 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
70456125 return .none;
70466126}
70476127
7048fn writeArrayLen(f: *Function, dest_ptr: CValue, dest_ty: Type) !void {
7049 const pt = f.object.dg.pt;
7050 const zcu = pt.zcu;
7051 const w = &f.object.code.writer;
7052 switch (dest_ty.ptrSize(zcu)) {
7053 .one => try w.print("{f}", .{
7054 try f.fmtIntLiteralDec(try pt.intValue(.usize, dest_ty.childType(zcu).arrayLen(zcu))),
7055 }),
7056 .many, .c => unreachable,
7057 .slice => try f.writeCValueMember(w, dest_ptr, .{ .identifier = "len" }),
7058 }
7059}
7060
70616128fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
7062 const pt = f.object.dg.pt;
6129 const pt = f.dg.pt;
70636130 const zcu = pt.zcu;
70646131 const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
70656132 const union_ptr = try f.resolveInst(bin_op.lhs);
......@@ -7069,19 +6136,18 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
70696136 const union_ty = f.typeOf(bin_op.lhs).childType(zcu);
70706137 const layout = union_ty.unionGetLayout(zcu);
70716138 if (layout.tag_size == 0) return .none;
7072 const tag_ty = union_ty.unionTagTypeSafety(zcu).?;
70736139
7074 const w = &f.object.code.writer;
7075 const a = try Assignment.start(f, w, try f.ctypeFromType(tag_ty, .complete));
6140 const w = &f.code.writer;
70766141 try f.writeCValueDerefMember(w, union_ptr, .{ .identifier = "tag" });
7077 try a.assign(f, w);
7078 try f.writeCValue(w, new_tag, .Other);
7079 try a.end(f, w);
6142 try w.writeAll(" = ");
6143 try f.writeCValue(w, new_tag, .other);
6144 try w.writeByte(';');
6145 try f.newline();
70806146 return .none;
70816147}
70826148
70836149fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
7084 const pt = f.object.dg.pt;
6150 const pt = f.dg.pt;
70856151 const zcu = pt.zcu;
70866152 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
70876153
......@@ -7093,17 +6159,20 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue {
70936159 if (layout.tag_size == 0) return .none;
70946160
70956161 const inst_ty = f.typeOfIndex(inst);
7096 const w = &f.object.code.writer;
6162 const w = &f.code.writer;
70976163 const local = try f.allocLocal(inst, inst_ty);
7098 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_ty, .complete));
7099 try f.writeCValue(w, local, .Other);
7100 try a.assign(f, w);
6164 try f.writeCValue(w, local, .other);
6165 try w.writeAll(" = ");
71016166 try f.writeCValueMember(w, operand, .{ .identifier = "tag" });
7102 try a.end(f, w);
6167 try w.writeByte(';');
6168 try f.newline();
71036169 return local;
71046170}
71056171
71066172fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
6173 const zcu = f.dg.pt.zcu;
6174 const ip = &zcu.intern_pool;
6175 const gpa = zcu.comp.gpa;
71076176 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
71086177
71096178 const inst_ty = f.typeOfIndex(inst);
......@@ -7111,15 +6180,17 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
71116180 const operand = try f.resolveInst(un_op);
71126181 try reap(f, inst, &.{un_op});
71136182
7114 const w = &f.object.code.writer;
6183 const w = &f.code.writer;
71156184 const local = try f.allocLocal(inst, inst_ty);
7116 try f.writeCValue(w, local, .Other);
7117 try w.print(" = {s}(", .{
7118 try f.getLazyFnName(.{ .tag_name = enum_ty.toIntern() }),
6185 try f.writeCValue(w, local, .other);
6186 try f.need_tag_name_funcs.put(gpa, enum_ty.toIntern(), {});
6187 try w.print(" = zig_tagName_{f}__{d}(", .{
6188 fmtIdentUnsolo(enum_ty.containerTypeName(ip).toSlice(ip)),
6189 @intFromEnum(enum_ty.toIntern()),
71196190 });
7120 try f.writeCValue(w, operand, .Other);
6191 try f.writeCValue(w, operand, .other);
71216192 try w.writeAll(");");
7122 try f.object.newline();
6193 try f.newline();
71236194
71246195 return local;
71256196}
......@@ -7127,40 +6198,37 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue {
71276198fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
71286199 const un_op = f.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
71296200
7130 const w = &f.object.code.writer;
6201 const w = &f.code.writer;
71316202 const inst_ty = f.typeOfIndex(inst);
71326203 const operand = try f.resolveInst(un_op);
71336204 try reap(f, inst, &.{un_op});
71346205 const local = try f.allocLocal(inst, inst_ty);
7135 try f.writeCValue(w, local, .Other);
6206 try f.writeCValue(w, local, .other);
71366207
71376208 try w.writeAll(" = zig_errorName[");
7138 try f.writeCValue(w, operand, .Other);
6209 try f.writeCValue(w, operand, .other);
71396210 try w.writeAll(" - 1];");
7140 try f.object.newline();
6211 try f.newline();
71416212 return local;
71426213}
71436214
71446215fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue {
7145 const pt = f.object.dg.pt;
7146 const zcu = pt.zcu;
71476216 const ty_op = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
71486217
71496218 const operand = try f.resolveInst(ty_op.operand);
71506219 try reap(f, inst, &.{ty_op.operand});
71516220
71526221 const inst_ty = f.typeOfIndex(inst);
7153 const inst_scalar_ty = inst_ty.scalarType(zcu);
71546222
7155 const w = &f.object.code.writer;
6223 const w = &f.code.writer;
71566224 const local = try f.allocLocal(inst, inst_ty);
71576225 const v = try Vectorize.start(f, inst, w, inst_ty);
7158 const a = try Assignment.start(f, w, try f.ctypeFromType(inst_scalar_ty, .complete));
7159 try f.writeCValue(w, local, .Other);
6226 try f.writeCValue(w, local, .other);
71606227 try v.elem(f, w);
7161 try a.assign(f, w);
7162 try f.writeCValue(w, operand, .Other);
7163 try a.end(f, w);
6228 try w.writeAll(" = ");
6229 try f.writeCValue(w, operand, .other);
6230 try w.writeByte(';');
6231 try f.newline();
71646232 try v.end(f, inst, w);
71656233
71666234 return local;
......@@ -7177,29 +6245,29 @@ fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue {
71776245
71786246 const inst_ty = f.typeOfIndex(inst);
71796247
7180 const w = &f.object.code.writer;
6248 const w = &f.code.writer;
71816249 const local = try f.allocLocal(inst, inst_ty);
71826250 const v = try Vectorize.start(f, inst, w, inst_ty);
7183 try f.writeCValue(w, local, .Other);
6251 try f.writeCValue(w, local, .other);
71846252 try v.elem(f, w);
71856253 try w.writeAll(" = ");
7186 try f.writeCValue(w, pred, .Other);
6254 try f.writeCValue(w, pred, .other);
71876255 try v.elem(f, w);
71886256 try w.writeAll(" ? ");
7189 try f.writeCValue(w, lhs, .Other);
6257 try f.writeCValue(w, lhs, .other);
71906258 try v.elem(f, w);
71916259 try w.writeAll(" : ");
7192 try f.writeCValue(w, rhs, .Other);
6260 try f.writeCValue(w, rhs, .other);
71936261 try v.elem(f, w);
71946262 try w.writeByte(';');
7195 try f.object.newline();
6263 try f.newline();
71966264 try v.end(f, inst, w);
71976265
71986266 return local;
71996267}
72006268
72016269fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {
7202 const pt = f.object.dg.pt;
6270 const pt = f.dg.pt;
72036271 const zcu = pt.zcu;
72046272
72056273 const unwrapped = f.air.unwrapShuffleOne(zcu, inst);
......@@ -7207,22 +6275,22 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {
72076275 const operand = try f.resolveInst(unwrapped.operand);
72086276 const inst_ty = unwrapped.result_ty;
72096277
7210 const w = &f.object.code.writer;
6278 const w = &f.code.writer;
72116279 const local = try f.allocLocal(inst, inst_ty);
72126280 try reap(f, inst, &.{unwrapped.operand}); // local cannot alias operand
72136281 for (mask, 0..) |mask_elem, out_idx| {
7214 try f.writeCValue(w, local, .Other);
6282 try f.writeCValueMember(w, local, .{ .identifier = "array" });
72156283 try w.writeByte('[');
7216 try f.object.dg.renderValue(w, try pt.intValue(.usize, out_idx), .Other);
6284 try f.dg.renderValue(w, try pt.intValue(.usize, out_idx), .other);
72176285 try w.writeAll("] = ");
72186286 switch (mask_elem.unwrap()) {
72196287 .elem => |src_idx| {
7220 try f.writeCValue(w, operand, .Other);
6288 try f.writeCValueMember(w, operand, .{ .identifier = "array" });
72216289 try w.writeByte('[');
7222 try f.object.dg.renderValue(w, try pt.intValue(.usize, src_idx), .Other);
6290 try f.dg.renderValue(w, try pt.intValue(.usize, src_idx), .other);
72236291 try w.writeByte(']');
72246292 },
7225 .value => |val| try f.object.dg.renderValue(w, .fromInterned(val), .Other),
6293 .value => |val| try f.dg.renderValue(w, .fromInterned(val), .other),
72266294 }
72276295 try w.writeAll(";\n");
72286296 }
......@@ -7231,7 +6299,7 @@ fn airShuffleOne(f: *Function, inst: Air.Inst.Index) !CValue {
72316299}
72326300
72336301fn airShuffleTwo(f: *Function, inst: Air.Inst.Index) !CValue {
7234 const pt = f.object.dg.pt;
6302 const pt = f.dg.pt;
72356303 const zcu = pt.zcu;
72366304
72376305 const unwrapped = f.air.unwrapShuffleTwo(zcu, inst);
......@@ -7241,38 +6309,38 @@ fn airShuffleTwo(f: *Function, inst: Air.Inst.Index) !CValue {
72416309 const inst_ty = unwrapped.result_ty;
72426310 const elem_ty = inst_ty.childType(zcu);
72436311
7244 const w = &f.object.code.writer;
6312 const w = &f.code.writer;
72456313 const local = try f.allocLocal(inst, inst_ty);
72466314 try reap(f, inst, &.{ unwrapped.operand_a, unwrapped.operand_b }); // local cannot alias operands
72476315 for (mask, 0..) |mask_elem, out_idx| {
7248 try f.writeCValue(w, local, .Other);
6316 try f.writeCValueMember(w, local, .{ .identifier = "array" });
72496317 try w.writeByte('[');
7250 try f.object.dg.renderValue(w, try pt.intValue(.usize, out_idx), .Other);
6318 try f.dg.renderValue(w, try pt.intValue(.usize, out_idx), .other);
72516319 try w.writeAll("] = ");
72526320 switch (mask_elem.unwrap()) {
72536321 .a_elem => |src_idx| {
7254 try f.writeCValue(w, operand_a, .Other);
6322 try f.writeCValueMember(w, operand_a, .{ .identifier = "array" });
72556323 try w.writeByte('[');
7256 try f.object.dg.renderValue(w, try pt.intValue(.usize, src_idx), .Other);
6324 try f.dg.renderValue(w, try pt.intValue(.usize, src_idx), .other);
72576325 try w.writeByte(']');
72586326 },
72596327 .b_elem => |src_idx| {
7260 try f.writeCValue(w, operand_b, .Other);
6328 try f.writeCValueMember(w, operand_b, .{ .identifier = "array" });
72616329 try w.writeByte('[');
7262 try f.object.dg.renderValue(w, try pt.intValue(.usize, src_idx), .Other);
6330 try f.dg.renderValue(w, try pt.intValue(.usize, src_idx), .other);
72636331 try w.writeByte(']');
72646332 },
7265 .undef => try f.object.dg.renderUndefValue(w, elem_ty, .Other),
6333 .undef => try f.dg.renderUndefValue(w, elem_ty, .other),
72666334 }
72676335 try w.writeByte(';');
7268 try f.object.newline();
6336 try f.newline();
72696337 }
72706338
72716339 return local;
72726340}
72736341
72746342fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
7275 const pt = f.object.dg.pt;
6343 const pt = f.dg.pt;
72766344 const zcu = pt.zcu;
72776345 const reduce = f.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
72786346
......@@ -7280,7 +6348,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
72806348 const operand = try f.resolveInst(reduce.operand);
72816349 try reap(f, inst, &.{reduce.operand});
72826350 const operand_ty = f.typeOf(reduce.operand);
7283 const w = &f.object.code.writer;
6351 const w = &f.code.writer;
72846352
72856353 const use_operator = scalar_ty.bitSize(zcu) <= 64;
72866354 const op: union(enum) {
......@@ -7327,10 +6395,10 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
73276395 // }
73286396
73296397 const accum = try f.allocLocal(inst, scalar_ty);
7330 try f.writeCValue(w, accum, .Other);
6398 try f.writeCValue(w, accum, .other);
73316399 try w.writeAll(" = ");
73326400
7333 try f.object.dg.renderValue(w, switch (reduce.operation) {
6401 try f.dg.renderValue(w, switch (reduce.operation) {
73346402 .Or, .Xor => switch (scalar_ty.zigTypeTag(zcu)) {
73356403 .bool => Value.false,
73366404 .int => try pt.intValue(scalar_ty, 0),
......@@ -7366,58 +6434,58 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
73666434 .float => try pt.floatValue(scalar_ty, std.math.nan(f128)),
73676435 else => unreachable,
73686436 },
7369 }, .Other);
6437 }, .other);
73706438 try w.writeByte(';');
7371 try f.object.newline();
6439 try f.newline();
73726440
73736441 const v = try Vectorize.start(f, inst, w, operand_ty);
7374 try f.writeCValue(w, accum, .Other);
6442 try f.writeCValue(w, accum, .other);
73756443 switch (op) {
73766444 .builtin => |func| {
73776445 try w.print(" = zig_{s}_", .{func.operation});
7378 try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty);
6446 try f.dg.renderTypeForBuiltinFnName(w, scalar_ty);
73796447 try w.writeByte('(');
7380 try f.writeCValue(w, accum, .FunctionArgument);
6448 try f.writeCValue(w, accum, .other);
73816449 try w.writeAll(", ");
7382 try f.writeCValue(w, operand, .Other);
6450 try f.writeCValue(w, operand, .other);
73836451 try v.elem(f, w);
7384 try f.object.dg.renderBuiltinInfo(w, scalar_ty, func.info);
6452 try f.dg.renderBuiltinInfo(w, scalar_ty, func.info);
73856453 try w.writeByte(')');
73866454 },
73876455 .infix => |ass| {
73886456 try w.writeAll(ass);
7389 try f.writeCValue(w, operand, .Other);
6457 try f.writeCValue(w, operand, .other);
73906458 try v.elem(f, w);
73916459 },
73926460 .ternary => |cmp| {
73936461 try w.writeAll(" = ");
7394 try f.writeCValue(w, accum, .Other);
6462 try f.writeCValue(w, accum, .other);
73956463 try w.writeAll(cmp);
7396 try f.writeCValue(w, operand, .Other);
6464 try f.writeCValue(w, operand, .other);
73976465 try v.elem(f, w);
73986466 try w.writeAll(" ? ");
7399 try f.writeCValue(w, accum, .Other);
6467 try f.writeCValue(w, accum, .other);
74006468 try w.writeAll(" : ");
7401 try f.writeCValue(w, operand, .Other);
6469 try f.writeCValue(w, operand, .other);
74026470 try v.elem(f, w);
74036471 },
74046472 }
74056473 try w.writeByte(';');
7406 try f.object.newline();
6474 try f.newline();
74076475 try v.end(f, inst, w);
74086476
74096477 return accum;
74106478}
74116479
74126480fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
7413 const pt = f.object.dg.pt;
6481 const pt = f.dg.pt;
74146482 const zcu = pt.zcu;
74156483 const ip = &zcu.intern_pool;
74166484 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
74176485 const inst_ty = f.typeOfIndex(inst);
74186486 const len: usize = @intCast(inst_ty.arrayLen(zcu));
74196487 const elements: []const Air.Inst.Ref = @ptrCast(f.air.extra.items[ty_pl.payload..][0..len]);
7420 const gpa = f.object.dg.gpa;
6488 const gpa = f.dg.gpa;
74216489 const resolved_elements = try gpa.alloc(CValue, elements.len);
74226490 defer gpa.free(resolved_elements);
74236491 for (resolved_elements, elements) |*resolved_element, element| {
......@@ -7430,28 +6498,23 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
74306498 }
74316499 }
74326500
7433 const w = &f.object.code.writer;
6501 const w = &f.code.writer;
74346502 const local = try f.allocLocal(inst, inst_ty);
74356503 switch (ip.indexToKey(inst_ty.toIntern())) {
74366504 inline .array_type, .vector_type => |info, tag| {
7437 const a: Assignment = .{
7438 .ctype = try f.ctypeFromType(.fromInterned(info.child), .complete),
7439 };
74406505 for (resolved_elements, 0..) |element, i| {
7441 try a.restart(f, w);
7442 try f.writeCValue(w, local, .Other);
7443 try w.print("[{d}]", .{i});
7444 try a.assign(f, w);
7445 try f.writeCValue(w, element, .Other);
7446 try a.end(f, w);
6506 try f.writeCValueMember(w, local, .{ .identifier = "array" });
6507 try w.print("[{d}] = ", .{i});
6508 try f.writeCValue(w, element, .other);
6509 try w.writeByte(';');
6510 try f.newline();
74476511 }
74486512 if (tag == .array_type and info.sentinel != .none) {
7449 try a.restart(f, w);
7450 try f.writeCValue(w, local, .Other);
7451 try w.print("[{d}]", .{info.len});
7452 try a.assign(f, w);
7453 try f.object.dg.renderValue(w, Value.fromInterned(info.sentinel), .Other);
7454 try a.end(f, w);
6513 try f.writeCValueMember(w, local, .{ .identifier = "array" });
6514 try w.print("[{d}] = ", .{info.len});
6515 try f.dg.renderValue(w, Value.fromInterned(info.sentinel), .other);
6516 try w.writeByte(';');
6517 try f.newline();
74556518 }
74566519 },
74576520 .struct_type => {
......@@ -7461,13 +6524,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
74616524 var field_it = loaded_struct.iterateRuntimeOrder(ip);
74626525 while (field_it.next()) |field_index| {
74636526 const field_ty: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
7464 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
6527 if (!field_ty.hasRuntimeBits(zcu)) continue;
74656528
7466 const a = try Assignment.start(f, w, try f.ctypeFromType(field_ty, .complete));
7467 try f.writeCValueMember(w, local, .{ .identifier = loaded_struct.fieldName(ip, field_index).toSlice(ip) });
7468 try a.assign(f, w);
7469 try f.writeCValue(w, resolved_elements[field_index], .Other);
7470 try a.end(f, w);
6529 try f.writeCValueMember(w, local, .{ .identifier = loaded_struct.field_names.get(ip)[field_index].toSlice(ip) });
6530 try w.writeAll(" = ");
6531 try f.writeCValue(w, resolved_elements[field_index], .other);
6532 try w.writeByte(';');
6533 try f.newline();
74716534 }
74726535 },
74736536 .@"packed" => unreachable, // `Air.Legalize.Feature.expand_packed_struct_init` handles this case
......@@ -7476,13 +6539,13 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
74766539 .tuple_type => |tuple_info| for (0..tuple_info.types.len) |field_index| {
74776540 if (tuple_info.values.get(ip)[field_index] != .none) continue;
74786541 const field_ty: Type = .fromInterned(tuple_info.types.get(ip)[field_index]);
7479 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
6542 if (!field_ty.hasRuntimeBits(zcu)) continue;
74806543
7481 const a = try Assignment.start(f, w, try f.ctypeFromType(field_ty, .complete));
74826544 try f.writeCValueMember(w, local, .{ .field = field_index });
7483 try a.assign(f, w);
7484 try f.writeCValue(w, resolved_elements[field_index], .Other);
7485 try a.end(f, w);
6545 try w.writeAll(" = ");
6546 try f.writeCValue(w, resolved_elements[field_index], .other);
6547 try w.writeByte(';');
6548 try f.newline();
74866549 },
74876550 else => unreachable,
74886551 }
......@@ -7491,49 +6554,52 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
74916554}
74926555
74936556fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
7494 const pt = f.object.dg.pt;
6557 const pt = f.dg.pt;
74956558 const zcu = pt.zcu;
74966559 const ip = &zcu.intern_pool;
74976560 const ty_pl = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
74986561 const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;
6562 const field_index = extra.field_index;
74996563
75006564 const union_ty = f.typeOfIndex(inst);
75016565 const loaded_union = ip.loadUnionType(union_ty.toIntern());
7502 const field_name = loaded_union.loadTagType(ip).names.get(ip)[extra.field_index];
7503 const payload_ty = f.typeOf(extra.init);
6566 const loaded_enum = ip.loadEnumType(loaded_union.enum_tag_type);
6567
75046568 const payload = try f.resolveInst(extra.init);
75056569 try reap(f, inst, &.{extra.init});
75066570
7507 const w = &f.object.code.writer;
7508 if (loaded_union.flagsUnordered(ip).layout == .@"packed") return f.moveCValue(inst, union_ty, payload);
6571 const w = &f.code.writer;
6572 if (loaded_union.layout == .@"packed") return f.moveCValue(inst, union_ty, payload);
75096573
75106574 const local = try f.allocLocal(inst, union_ty);
75116575
7512 const field: CValue = if (union_ty.unionTagTypeSafety(zcu)) |tag_ty| field: {
7513 const layout = union_ty.unionGetLayout(zcu);
7514 if (layout.tag_size != 0) {
7515 const field_index = tag_ty.enumFieldIndex(field_name, zcu).?;
7516 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);
7517
7518 const a = try Assignment.start(f, w, try f.ctypeFromType(tag_ty, .complete));
7519 try f.writeCValueMember(w, local, .{ .identifier = "tag" });
7520 try a.assign(f, w);
7521 try w.print("{f}", .{try f.fmtIntLiteralDec(try tag_val.intFromEnum(tag_ty, pt))});
7522 try a.end(f, w);
6576 if (loaded_union.has_runtime_tag) {
6577 try f.writeCValueMember(w, local, .{ .identifier = "tag" });
6578 if (loaded_enum.field_values.len == 0) {
6579 // auto-numbered
6580 try w.print(" = {d};", .{field_index});
6581 } else {
6582 const tag_int_val: Value = .fromInterned(loaded_enum.field_values.get(ip)[field_index]);
6583 try w.print(" = {f};", .{try f.fmtIntLiteralDec(tag_int_val)});
75236584 }
7524 break :field .{ .payload_identifier = field_name.toSlice(ip) };
7525 } else .{ .identifier = field_name.toSlice(ip) };
7526
7527 const a = try Assignment.start(f, w, try f.ctypeFromType(payload_ty, .complete));
7528 try f.writeCValueMember(w, local, field);
7529 try a.assign(f, w);
7530 try f.writeCValue(w, payload, .Other);
7531 try a.end(f, w);
6585 try f.newline();
6586 }
6587
6588 const field_name_slice = loaded_enum.field_names.get(ip)[field_index].toSlice(ip);
6589 switch (loaded_union.layout) {
6590 .auto => try f.writeCValueMember(w, local, .{ .payload_identifier = field_name_slice }),
6591 .@"extern" => try f.writeCValueMember(w, local, .{ .identifier = field_name_slice }),
6592 .@"packed" => unreachable,
6593 }
6594 try w.writeAll(" = ");
6595 try f.writeCValue(w, payload, .other);
6596 try w.writeByte(';');
6597 try f.newline();
75326598 return local;
75336599}
75346600
75356601fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
7536 const pt = f.object.dg.pt;
6602 const pt = f.dg.pt;
75376603 const zcu = pt.zcu;
75386604 const prefetch = f.air.instructions.items(.data)[@intFromEnum(inst)].prefetch;
75396605
......@@ -7541,16 +6607,16 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
75416607 const ptr = try f.resolveInst(prefetch.ptr);
75426608 try reap(f, inst, &.{prefetch.ptr});
75436609
7544 const w = &f.object.code.writer;
6610 const w = &f.code.writer;
75456611 switch (prefetch.cache) {
75466612 .data => {
75476613 try w.writeAll("zig_prefetch(");
75486614 if (ptr_ty.isSlice(zcu))
75496615 try f.writeCValueMember(w, ptr, .{ .identifier = "ptr" })
75506616 else
7551 try f.writeCValue(w, ptr, .FunctionArgument);
6617 try f.writeCValue(w, ptr, .other);
75526618 try w.print(", {d}, {d});", .{ @intFromEnum(prefetch.rw), prefetch.locality });
7553 try f.object.newline();
6619 try f.newline();
75546620 },
75556621 // The available prefetch intrinsics do not accept a cache argument; only
75566622 // address, rw, and locality.
......@@ -7563,14 +6629,14 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue {
75636629fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {
75646630 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
75656631
7566 const w = &f.object.code.writer;
6632 const w = &f.code.writer;
75676633 const inst_ty = f.typeOfIndex(inst);
75686634 const local = try f.allocLocal(inst, inst_ty);
7569 try f.writeCValue(w, local, .Other);
6635 try f.writeCValue(w, local, .other);
75706636
75716637 try w.writeAll(" = ");
75726638 try w.print("zig_wasm_memory_size({d});", .{pl_op.payload});
7573 try f.object.newline();
6639 try f.newline();
75746640
75756641 return local;
75766642}
......@@ -7578,23 +6644,23 @@ fn airWasmMemorySize(f: *Function, inst: Air.Inst.Index) !CValue {
75786644fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue {
75796645 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
75806646
7581 const w = &f.object.code.writer;
6647 const w = &f.code.writer;
75826648 const inst_ty = f.typeOfIndex(inst);
75836649 const operand = try f.resolveInst(pl_op.operand);
75846650 try reap(f, inst, &.{pl_op.operand});
75856651 const local = try f.allocLocal(inst, inst_ty);
7586 try f.writeCValue(w, local, .Other);
6652 try f.writeCValue(w, local, .other);
75876653
75886654 try w.writeAll(" = ");
75896655 try w.print("zig_wasm_memory_grow({d}, ", .{pl_op.payload});
7590 try f.writeCValue(w, operand, .FunctionArgument);
6656 try f.writeCValue(w, operand, .other);
75916657 try w.writeAll(");");
7592 try f.object.newline();
6658 try f.newline();
75936659 return local;
75946660}
75956661
75966662fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
7597 const pt = f.object.dg.pt;
6663 const pt = f.dg.pt;
75986664 const zcu = pt.zcu;
75996665 const pl_op = f.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
76006666 const bin_op = f.air.extraData(Air.Bin, pl_op.payload).data;
......@@ -7607,24 +6673,24 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
76076673 const inst_ty = f.typeOfIndex(inst);
76086674 const inst_scalar_ty = inst_ty.scalarType(zcu);
76096675
7610 const w = &f.object.code.writer;
6676 const w = &f.code.writer;
76116677 const local = try f.allocLocal(inst, inst_ty);
76126678 const v = try Vectorize.start(f, inst, w, inst_ty);
7613 try f.writeCValue(w, local, .Other);
6679 try f.writeCValue(w, local, .other);
76146680 try v.elem(f, w);
76156681 try w.writeAll(" = zig_fma_");
7616 try f.object.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty);
6682 try f.dg.renderTypeForBuiltinFnName(w, inst_scalar_ty);
76176683 try w.writeByte('(');
7618 try f.writeCValue(w, mulend1, .FunctionArgument);
6684 try f.writeCValue(w, mulend1, .other);
76196685 try v.elem(f, w);
76206686 try w.writeAll(", ");
7621 try f.writeCValue(w, mulend2, .FunctionArgument);
6687 try f.writeCValue(w, mulend2, .other);
76226688 try v.elem(f, w);
76236689 try w.writeAll(", ");
7624 try f.writeCValue(w, addend, .FunctionArgument);
6690 try f.writeCValue(w, addend, .other);
76256691 try v.elem(f, w);
76266692 try w.writeAll(");");
7627 try f.object.newline();
6693 try f.newline();
76286694 try v.end(f, inst, w);
76296695
76306696 return local;
......@@ -7632,34 +6698,33 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue {
76326698
76336699fn airRuntimeNavPtr(f: *Function, inst: Air.Inst.Index) !CValue {
76346700 const ty_nav = f.air.instructions.items(.data)[@intFromEnum(inst)].ty_nav;
7635 const w = &f.object.code.writer;
6701 const w = &f.code.writer;
76366702 const local = try f.allocLocal(inst, .fromInterned(ty_nav.ty));
7637 try f.writeCValue(w, local, .Other);
6703 try f.writeCValue(w, local, .other);
76386704 try w.writeAll(" = ");
7639 try f.object.dg.renderNav(w, ty_nav.nav, .Other);
6705 try f.dg.renderNav(w, ty_nav.nav, .other);
76406706 try w.writeByte(';');
7641 try f.object.newline();
6707 try f.newline();
76426708 return local;
76436709}
76446710
76456711fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
7646 const pt = f.object.dg.pt;
6712 const pt = f.dg.pt;
76476713 const zcu = pt.zcu;
76486714 const inst_ty = f.typeOfIndex(inst);
7649 const function_ty = zcu.navValue(f.object.dg.pass.nav).typeOf(zcu);
7650 const function_info = (try f.ctypeFromType(function_ty, .complete)).info(&f.object.dg.ctype_pool).function;
7651 assert(function_info.varargs);
76526715
7653 const w = &f.object.code.writer;
6716 assert(Value.fromInterned(f.func_index).typeOf(zcu).fnIsVarArgs(zcu));
6717
6718 const w = &f.code.writer;
76546719 const local = try f.allocLocal(inst, inst_ty);
76556720 try w.writeAll("va_start(*(va_list *)&");
7656 try f.writeCValue(w, local, .Other);
7657 if (function_info.param_ctypes.len > 0) {
6721 try f.writeCValue(w, local, .other);
6722 if (f.next_arg_index > 0) {
76586723 try w.writeAll(", ");
7659 try f.writeCValue(w, .{ .arg = function_info.param_ctypes.len - 1 }, .FunctionArgument);
6724 try f.writeCValue(w, .{ .arg = f.next_arg_index - 1 }, .other);
76606725 }
76616726 try w.writeAll(");");
7662 try f.object.newline();
6727 try f.newline();
76636728 return local;
76646729}
76656730
......@@ -7670,15 +6735,15 @@ fn airCVaArg(f: *Function, inst: Air.Inst.Index) !CValue {
76706735 const va_list = try f.resolveInst(ty_op.operand);
76716736 try reap(f, inst, &.{ty_op.operand});
76726737
7673 const w = &f.object.code.writer;
6738 const w = &f.code.writer;
76746739 const local = try f.allocLocal(inst, inst_ty);
7675 try f.writeCValue(w, local, .Other);
6740 try f.writeCValue(w, local, .other);
76766741 try w.writeAll(" = va_arg(*(va_list *)");
7677 try f.writeCValue(w, va_list, .Other);
6742 try f.writeCValue(w, va_list, .other);
76786743 try w.writeAll(", ");
76796744 try f.renderType(w, ty_op.ty.toType());
76806745 try w.writeAll(");");
7681 try f.object.newline();
6746 try f.newline();
76826747 return local;
76836748}
76846749
......@@ -7688,11 +6753,11 @@ fn airCVaEnd(f: *Function, inst: Air.Inst.Index) !CValue {
76886753 const va_list = try f.resolveInst(un_op);
76896754 try reap(f, inst, &.{un_op});
76906755
7691 const w = &f.object.code.writer;
6756 const w = &f.code.writer;
76926757 try w.writeAll("va_end(*(va_list *)");
7693 try f.writeCValue(w, va_list, .Other);
6758 try f.writeCValue(w, va_list, .other);
76946759 try w.writeAll(");");
7695 try f.object.newline();
6760 try f.newline();
76966761 return .none;
76976762}
76986763
......@@ -7703,14 +6768,14 @@ fn airCVaCopy(f: *Function, inst: Air.Inst.Index) !CValue {
77036768 const va_list = try f.resolveInst(ty_op.operand);
77046769 try reap(f, inst, &.{ty_op.operand});
77056770
7706 const w = &f.object.code.writer;
6771 const w = &f.code.writer;
77076772 const local = try f.allocLocal(inst, inst_ty);
77086773 try w.writeAll("va_copy(*(va_list *)&");
7709 try f.writeCValue(w, local, .Other);
6774 try f.writeCValue(w, local, .other);
77106775 try w.writeAll(", *(va_list *)");
7711 try f.writeCValue(w, va_list, .Other);
6776 try f.writeCValue(w, va_list, .other);
77126777 try w.writeAll(");");
7713 try f.object.newline();
6778 try f.newline();
77146779 return local;
77156780}
77166781
......@@ -8027,103 +7092,193 @@ fn undefPattern(comptime IntType: type) IntType {
80277092
80287093const FormatIntLiteralContext = struct {
80297094 dg: *DeclGen,
8030 int_info: InternPool.Key.IntType,
8031 kind: CType.Kind,
8032 ctype: CType,
7095 loc: ValueRenderLocation,
80337096 val: Value,
7097 cty: CType,
80347098 base: u8,
80357099 case: std.fmt.Case,
80367100};
80377101fn formatIntLiteral(data: FormatIntLiteralContext, w: *Writer) Writer.Error!void {
8038 const pt = data.dg.pt;
8039 const zcu = pt.zcu;
8040 const target = &data.dg.mod.resolved_target.result;
8041 const ctype_pool = &data.dg.ctype_pool;
8042
8043 const ExpectedContents = struct {
8044 const base = 10;
8045 const bits = 128;
8046 const limbs_count = BigInt.calcTwosCompLimbCount(bits);
8047
8048 undef_limbs: [limbs_count]BigIntLimb,
8049 wrap_limbs: [limbs_count]BigIntLimb,
8050 to_string_buf: [bits]u8,
8051 to_string_limbs: [BigInt.calcToStringLimbsBufferLen(limbs_count, base)]BigIntLimb,
8052 };
8053 var stack align(@alignOf(ExpectedContents)) =
8054 std.heap.stackFallback(@sizeOf(ExpectedContents), data.dg.gpa);
8055 const allocator = stack.get();
8056
8057 var undef_limbs: []BigIntLimb = &.{};
8058 defer allocator.free(undef_limbs);
8059
8060 var int_buf: Value.BigIntSpace = undefined;
8061 const int = if (data.val.isUndef(zcu)) blk: {
8062 undef_limbs = allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(data.int_info.bits)) catch return error.WriteFailed;
8063 @memset(undef_limbs, undefPattern(BigIntLimb));
8064
8065 var undef_int = BigInt.Mutable{
8066 .limbs = undef_limbs,
8067 .len = undef_limbs.len,
8068 .positive = true,
8069 };
8070 undef_int.truncate(undef_int.toConst(), data.int_info.signedness, data.int_info.bits);
8071 break :blk undef_int.toConst();
8072 } else data.val.toBigInt(&int_buf, zcu);
8073 assert(int.fitsInTwosComp(data.int_info.signedness, data.int_info.bits));
8074
8075 const c_bits: usize = @intCast(data.ctype.byteSize(ctype_pool, data.dg.mod) * 8);
8076 var one_limbs: [BigInt.calcLimbLen(1)]BigIntLimb = undefined;
8077 const one = BigInt.Mutable.init(&one_limbs, 1).toConst();
8078
8079 var wrap = BigInt.Mutable{
8080 .limbs = allocator.alloc(BigIntLimb, BigInt.calcTwosCompLimbCount(c_bits)) catch return error.WriteFailed,
8081 .len = undefined,
8082 .positive = undefined,
8083 };
8084 defer allocator.free(wrap.limbs);
8085
8086 const c_limb_info: struct {
8087 ctype: CType,
8088 count: usize,
8089 endian: std.builtin.Endian,
8090 homogeneous: bool,
8091 } = switch (data.ctype.info(ctype_pool)) {
8092 .basic => |basic_info| switch (basic_info) {
8093 else => .{
8094 .ctype = .void,
8095 .count = 1,
8096 .endian = .little,
8097 .homogeneous = true,
7102 const dg = data.dg;
7103 const zcu = dg.pt.zcu;
7104 const target = &dg.mod.resolved_target.result;
7105
7106 const val = data.val;
7107 const ty = val.typeOf(zcu);
7108
7109 assert(!val.isUndef(zcu));
7110
7111 var space: Value.BigIntSpace = undefined;
7112 const val_bigint = val.toBigInt(&space, zcu);
7113
7114 switch (CType.classifyInt(ty, zcu)) {
7115 .void => unreachable, // opv
7116 .small => |int_cty| return FormatInt128.format(.{
7117 .target = zcu.getTarget(),
7118 .int_cty = int_cty,
7119 .val = val_bigint,
7120 .is_global = data.loc == .static_initializer,
7121 .base = data.base,
7122 .case = data.case,
7123 }, w),
7124 .big => |big| {
7125 if (!data.loc.isInitializer()) {
7126 // Use `CType.fmtTypeName` directly to avoid the possibility of `error.OutOfMemory`.
7127 try w.print("({f})", .{data.cty.fmtTypeName(zcu)});
7128 }
7129
7130 try w.writeAll("{{");
7131
7132 var limb_buf: [std.math.big.int.calcTwosCompLimbCount(65535)]std.math.big.Limb = undefined;
7133 for (0..big.limbs_len) |limb_index| {
7134 if (limb_index != 0) try w.writeAll(", ");
7135 const limb_bit_offset: u16 = switch (target.cpu.arch.endian()) {
7136 .little => @intCast(limb_index * big.limb_size.bits()),
7137 .big => @intCast((big.limbs_len - limb_index - 1) * big.limb_size.bits()),
7138 };
7139 var limb_bigint: std.math.big.int.Mutable = .{
7140 .limbs = &limb_buf,
7141 .len = undefined,
7142 .positive = undefined,
7143 };
7144 limb_bigint.shiftRight(val_bigint, limb_bit_offset);
7145 limb_bigint.truncate(limb_bigint.toConst(), .unsigned, big.limb_size.bits());
7146 try FormatInt128.format(.{
7147 .target = zcu.getTarget(),
7148 .int_cty = big.limb_size.unsigned(),
7149 .val = limb_bigint.toConst(),
7150 .is_global = data.loc == .static_initializer,
7151 .base = data.base,
7152 .case = data.case,
7153 }, w);
7154 }
7155
7156 try w.writeAll("}}");
7157 },
7158 }
7159}
7160const FormatInt128 = struct {
7161 target: *const std.Target,
7162 int_cty: CType.Int,
7163 val: std.math.big.int.Const,
7164 is_global: bool,
7165 base: u8,
7166 case: std.fmt.Case,
7167 pub fn format(data: FormatInt128, w: *Writer) Writer.Error!void {
7168 const target = data.target;
7169
7170 const val = data.val;
7171 const is_global = data.is_global;
7172 const base = data.base;
7173 const case = data.case;
7174
7175 switch (data.int_cty) {
7176 .uint8_t,
7177 .uint16_t,
7178 .uint32_t,
7179 .uint64_t,
7180 .@"unsigned short",
7181 .@"unsigned int",
7182 .@"unsigned long",
7183 .@"unsigned long long",
7184 .uintptr_t,
7185 => |t| try w.print("{f}", .{
7186 fmtUnsignedIntLiteralSmall(target, t, val.toInt(u64) catch unreachable, is_global, base, case),
7187 }),
7188
7189 .int8_t,
7190 .int16_t,
7191 .int32_t,
7192 .int64_t,
7193 .char,
7194 .@"signed short",
7195 .@"signed int",
7196 .@"signed long",
7197 .@"signed long long",
7198 .intptr_t,
7199 => |t| try w.print("{f}", .{
7200 fmtSignedIntLiteralSmall(target, t, val.toInt(i64) catch unreachable, is_global, base, case),
7201 }),
7202
7203 .zig_u128 => {
7204 const raw = val.toInt(u128) catch unreachable;
7205 const lo: u64 = @truncate(raw);
7206 const hi: u64 = @intCast(raw >> 64);
7207 const macro_name: []const u8 = if (is_global) "zig_init_u128" else "zig_make_u128";
7208 try w.print("{s}({f}, {f})", .{
7209 macro_name,
7210 fmtUnsignedIntLiteralSmall(target, .uint64_t, hi, is_global, base, case),
7211 fmtUnsignedIntLiteralSmall(target, .uint64_t, lo, is_global, base, case),
7212 });
80987213 },
8099 .zig_u128, .zig_i128 => .{
8100 .ctype = .u64,
8101 .count = 2,
8102 .endian = .big,
8103 .homogeneous = false,
7214
7215 .zig_i128 => {
7216 const raw = val.toInt(i128) catch unreachable;
7217 const lo: u64 = @truncate(@as(u128, @bitCast(raw)));
7218 const hi: i64 = @intCast(raw >> 64);
7219 const macro_name: []const u8 = if (is_global) "zig_init_i128" else "zig_make_i128";
7220 try w.print("{s}({f}, {f})", .{
7221 macro_name,
7222 fmtSignedIntLiteralSmall(target, .int64_t, hi, is_global, base, case),
7223 fmtUnsignedIntLiteralSmall(target, .uint64_t, lo, is_global, base, case),
7224 });
81047225 },
8105 },
8106 .array => |array_info| .{
8107 .ctype = array_info.elem_ctype,
8108 .count = @intCast(array_info.len),
8109 .endian = target.cpu.arch.endian(),
8110 .homogeneous = true,
8111 },
8112 else => unreachable,
7226 }
7227 }
7228};
7229fn fmtUnsignedIntLiteralSmall(
7230 target: *const std.Target,
7231 int_cty: CType.Int,
7232 val: u64,
7233 is_global: bool,
7234 base: u8,
7235 case: std.fmt.Case,
7236) FormatUnsignedIntLiteralSmall {
7237 return .{
7238 .target = target,
7239 .int_cty = int_cty,
7240 .val = val,
7241 .is_global = is_global,
7242 .base = base,
7243 .case = case,
81137244 };
8114 if (c_limb_info.count == 1) {
8115 if (wrap.addWrap(int, one, data.int_info.signedness, c_bits) or
8116 data.int_info.signedness == .signed and wrap.subWrap(int, one, data.int_info.signedness, c_bits))
8117 return w.print("{s}_{s}", .{
8118 data.ctype.getStandardDefineAbbrev() orelse return w.print("zig_{s}Int_{c}{d}", .{
8119 if (int.positive) "max" else "min", signAbbrev(data.int_info.signedness), c_bits,
8120 }),
8121 if (int.positive) "MAX" else "MIN",
8122 });
8123
8124 if (!int.positive) try w.writeByte('-');
8125 try data.ctype.renderLiteralPrefix(w, data.kind, ctype_pool);
7245}
7246fn fmtSignedIntLiteralSmall(
7247 target: *const std.Target,
7248 int_cty: CType.Int,
7249 val: i64,
7250 is_global: bool,
7251 base: u8,
7252 case: std.fmt.Case,
7253) FormatSignedIntLiteralSmall {
7254 return .{
7255 .target = target,
7256 .int_cty = int_cty,
7257 .val = val,
7258 .is_global = is_global,
7259 .base = base,
7260 .case = case,
7261 };
7262}
81267263
7264const FormatSignedIntLiteralSmall = struct {
7265 target: *const std.Target,
7266 int_cty: CType.Int,
7267 val: i64,
7268 is_global: bool,
7269 base: u8,
7270 case: std.fmt.Case,
7271 pub fn format(data: FormatSignedIntLiteralSmall, w: *Writer) Writer.Error!void {
7272 const bits = data.int_cty.bits(data.target);
7273 const max_int: i64 = @bitCast((@as(u64, 1) << @intCast(bits - 1)) - 1);
7274 const min_int: i64 = @bitCast(@as(u64, 1) << @intCast(bits - 1));
7275 if (data.val == max_int) {
7276 return w.print("{s}_MAX", .{minMaxMacroPrefix(data.int_cty)});
7277 } else if (data.val == min_int) {
7278 return w.print("{s}_MIN", .{minMaxMacroPrefix(data.int_cty)});
7279 }
7280 if (data.val < 0) try w.writeByte('-');
7281 try w.writeAll(intLiteralPrefix(data.int_cty, data.is_global));
81277282 switch (data.base) {
81287283 2 => try w.writeAll("0b"),
81297284 8 => try w.writeByte('0'),
......@@ -8131,68 +7286,131 @@ fn formatIntLiteral(data: FormatIntLiteralContext, w: *Writer) Writer.Error!void
81317286 16 => try w.writeAll("0x"),
81327287 else => unreachable,
81337288 }
8134 const string = int.abs().toStringAlloc(allocator, data.base, data.case) catch
8135 return error.WriteFailed;
8136 defer allocator.free(string);
8137 try w.writeAll(string);
8138 } else {
8139 try data.ctype.renderLiteralPrefix(w, data.kind, ctype_pool);
8140 wrap.truncate(int, .unsigned, c_bits);
8141 @memset(wrap.limbs[wrap.len..], 0);
8142 wrap.len = wrap.limbs.len;
8143 const limbs_per_c_limb = @divExact(wrap.len, c_limb_info.count);
8144
8145 var c_limb_int_info: std.builtin.Type.Int = .{
8146 .signedness = undefined,
8147 .bits = @intCast(@divExact(c_bits, c_limb_info.count)),
8148 };
8149 var c_limb_ctype: CType = undefined;
8150
8151 var limb_offset: usize = 0;
8152 const most_significant_limb_i = wrap.len - limbs_per_c_limb;
8153 while (limb_offset < wrap.len) : (limb_offset += limbs_per_c_limb) {
8154 const limb_i = switch (c_limb_info.endian) {
8155 .little => limb_offset,
8156 .big => most_significant_limb_i - limb_offset,
8157 };
8158 var c_limb_mut = BigInt.Mutable{
8159 .limbs = wrap.limbs[limb_i..][0..limbs_per_c_limb],
8160 .len = undefined,
8161 .positive = true,
8162 };
8163 c_limb_mut.normalize(limbs_per_c_limb);
8164
8165 if (limb_i == most_significant_limb_i and
8166 !c_limb_info.homogeneous and data.int_info.signedness == .signed)
8167 {
8168 // most significant limb is actually signed
8169 c_limb_int_info.signedness = .signed;
8170 c_limb_ctype = c_limb_info.ctype.toSigned();
8171
8172 c_limb_mut.truncate(
8173 c_limb_mut.toConst(),
8174 .signed,
8175 data.int_info.bits - limb_i * @bitSizeOf(BigIntLimb),
8176 );
8177 } else {
8178 c_limb_int_info.signedness = .unsigned;
8179 c_limb_ctype = c_limb_info.ctype;
8180 }
8181
8182 if (limb_offset > 0) try w.writeAll(", ");
8183 try formatIntLiteral(.{
8184 .dg = data.dg,
8185 .int_info = c_limb_int_info,
8186 .kind = data.kind,
8187 .ctype = c_limb_ctype,
8188 .val = pt.intValue_big(.comptime_int, c_limb_mut.toConst()) catch
8189 return error.WriteFailed,
8190 .base = data.base,
8191 .case = data.case,
8192 }, w);
7289 // This `@abs` is safe thanks to the `min_int` case above.
7290 try w.printInt(@abs(data.val), data.base, data.case, .{});
7291 try w.writeAll(intLiteralSuffix(data.int_cty));
7292 }
7293};
7294const FormatUnsignedIntLiteralSmall = struct {
7295 target: *const std.Target,
7296 int_cty: CType.Int,
7297 val: u64,
7298 is_global: bool,
7299 base: u8,
7300 case: std.fmt.Case,
7301 pub fn format(data: FormatUnsignedIntLiteralSmall, w: *Writer) Writer.Error!void {
7302 const bits = data.int_cty.bits(data.target);
7303 const max_int: u64 = @as(u64, std.math.maxInt(u64)) >> @intCast(64 - bits);
7304 if (data.val == max_int) {
7305 return w.print("{s}_MAX", .{minMaxMacroPrefix(data.int_cty)});
7306 }
7307 try w.writeAll(intLiteralPrefix(data.int_cty, data.is_global));
7308 switch (data.base) {
7309 2 => try w.writeAll("0b"),
7310 8 => try w.writeByte('0'),
7311 10 => {},
7312 16 => try w.writeAll("0x"),
7313 else => unreachable,
81937314 }
7315 try w.printInt(data.val, data.base, data.case, .{});
7316 try w.writeAll(intLiteralSuffix(data.int_cty));
81947317 }
8195 try data.ctype.renderLiteralSuffix(w, ctype_pool);
7318};
7319fn minMaxMacroPrefix(int_cty: CType.Int) []const u8 {
7320 return switch (int_cty) {
7321 // zig fmt: off
7322 .char => "CHAR",
7323
7324 .@"unsigned short" => "USHRT",
7325 .@"unsigned int" => "UINT",
7326 .@"unsigned long" => "ULONG",
7327 .@"unsigned long long" => "ULLONG",
7328
7329 .@"signed short" => "SHRT",
7330 .@"signed int" => "INT",
7331 .@"signed long" => "LONG",
7332 .@"signed long long" => "LLONG",
7333
7334 .uint8_t => "UINT8",
7335 .uint16_t => "UINT16",
7336 .uint32_t => "UINT32",
7337 .uint64_t => "UINT64",
7338 .zig_u128 => unreachable,
7339
7340 .int8_t => "INT8",
7341 .int16_t => "INT16",
7342 .int32_t => "INT32",
7343 .int64_t => "INT64",
7344 .zig_i128 => unreachable,
7345
7346 .uintptr_t => "UINTPTR",
7347 .intptr_t => "INTPTR",
7348 // zig fmt: on
7349 };
7350}
7351fn intLiteralPrefix(cty: CType.Int, is_global: bool) []const u8 {
7352 return switch (cty) {
7353 // zig fmt: off
7354 .char => if (is_global) "" else "(char)",
7355
7356 .@"unsigned short" => if (is_global) "" else "(unsigned short)",
7357 .@"unsigned int" => "",
7358 .@"unsigned long" => "",
7359 .@"unsigned long long" => "",
7360
7361 .@"signed short" => if (is_global) "" else "(signed short)",
7362 .@"signed int" => "",
7363 .@"signed long" => "",
7364 .@"signed long long" => "",
7365
7366 .uint8_t => "UINT8_C(",
7367 .uint16_t => "UINT16_C(",
7368 .uint32_t => "UINT32_C(",
7369 .uint64_t => "UINT64_C(",
7370 .zig_u128 => unreachable,
7371
7372 .int8_t => "INT8_C(",
7373 .int16_t => "INT16_C(",
7374 .int32_t => "INT32_C(",
7375 .int64_t => "INT64_C(",
7376 .zig_i128 => unreachable,
7377
7378 .uintptr_t => if (is_global) "" else "(uintptr_t)",
7379 .intptr_t => if (is_global) "" else "(intptr_t)",
7380 // zig fmt: on
7381 };
7382}
7383fn intLiteralSuffix(cty: CType.Int) []const u8 {
7384 return switch (cty) {
7385 // zig fmt: off
7386 .char => "",
7387
7388 .@"unsigned short" => "u",
7389 .@"unsigned int" => "u",
7390 .@"unsigned long" => "ul",
7391 .@"unsigned long long" => "ull",
7392
7393 .@"signed short" => "",
7394 .@"signed int" => "",
7395 .@"signed long" => "l",
7396 .@"signed long long" => "ll",
7397
7398 .uint8_t => ")",
7399 .uint16_t => ")",
7400 .uint32_t => ")",
7401 .uint64_t => ")",
7402 .zig_u128 => unreachable,
7403
7404 .int8_t => ")",
7405 .int16_t => ")",
7406 .int32_t => ")",
7407 .int64_t => ")",
7408 .zig_i128 => unreachable,
7409
7410 .uintptr_t => "ul",
7411 .intptr_t => "",
7412 // zig fmt: on
7413 };
81967414}
81977415
81987416const Materialize = struct {
......@@ -8207,7 +7425,7 @@ const Materialize = struct {
82077425 }
82087426
82097427 pub fn mat(self: Materialize, f: *Function, w: *Writer) !void {
8210 try f.writeCValue(w, self.local, .Other);
7428 try f.writeCValue(w, self.local, .other);
82117429 }
82127430
82137431 pub fn end(self: Materialize, f: *Function, inst: Air.Inst.Index) !void {
......@@ -8215,95 +7433,52 @@ const Materialize = struct {
82157433 }
82167434};
82177435
8218const Assignment = struct {
8219 ctype: CType,
8220
8221 pub fn start(f: *Function, w: *Writer, ctype: CType) !Assignment {
8222 const self: Assignment = .{ .ctype = ctype };
8223 try self.restart(f, w);
8224 return self;
8225 }
8226
8227 pub fn restart(self: Assignment, f: *Function, w: *Writer) !void {
8228 switch (self.strategy(f)) {
8229 .assign => {},
8230 .memcpy => try w.writeAll("memcpy("),
8231 }
8232 }
8233
8234 pub fn assign(self: Assignment, f: *Function, w: *Writer) !void {
8235 switch (self.strategy(f)) {
8236 .assign => try w.writeAll(" = "),
8237 .memcpy => try w.writeAll(", "),
8238 }
8239 }
8240
8241 pub fn end(self: Assignment, f: *Function, w: *Writer) !void {
8242 switch (self.strategy(f)) {
8243 .assign => {},
8244 .memcpy => {
8245 try w.writeAll(", sizeof(");
8246 try f.renderCType(w, self.ctype);
8247 try w.writeAll("))");
8248 },
8249 }
8250 try w.writeByte(';');
8251 try f.object.newline();
8252 }
8253
8254 fn strategy(self: Assignment, f: *Function) enum { assign, memcpy } {
8255 return switch (self.ctype.info(&f.object.dg.ctype_pool)) {
8256 else => .assign,
8257 .array, .vector => .memcpy,
8258 };
8259 }
8260};
8261
82627436const Vectorize = struct {
82637437 index: CValue = .none,
82647438
82657439 pub fn start(f: *Function, inst: Air.Inst.Index, w: *Writer, ty: Type) !Vectorize {
8266 const pt = f.object.dg.pt;
7440 const pt = f.dg.pt;
82677441 const zcu = pt.zcu;
8268 return if (ty.zigTypeTag(zcu) == .vector) index: {
8269 const local = try f.allocLocal(inst, .usize);
8270
8271 try w.writeAll("for (");
8272 try f.writeCValue(w, local, .Other);
8273 try w.print(" = {f}; ", .{try f.fmtIntLiteralDec(.zero_usize)});
8274 try f.writeCValue(w, local, .Other);
8275 try w.print(" < {f}; ", .{try f.fmtIntLiteralDec(try pt.intValue(.usize, ty.vectorLen(zcu)))});
8276 try f.writeCValue(w, local, .Other);
8277 try w.print(" += {f}) {{\n", .{try f.fmtIntLiteralDec(.one_usize)});
8278 f.object.indent();
8279 try f.object.newline();
8280
8281 break :index .{ .index = local };
8282 } else .{};
7442 switch (ty.zigTypeTag(zcu)) {
7443 else => return .{ .index = .none },
7444 .vector => {
7445 const local = try f.allocLocal(inst, .usize);
7446 try w.writeAll("for (");
7447 try f.writeCValue(w, local, .other);
7448 try w.print(" = {f}; ", .{try f.fmtIntLiteralDec(.zero_usize)});
7449 try f.writeCValue(w, local, .other);
7450 try w.print(" < {f}; ", .{try f.fmtIntLiteralDec(try pt.intValue(.usize, ty.vectorLen(zcu)))});
7451 try f.writeCValue(w, local, .other);
7452 try w.print(" += {f}) {{", .{try f.fmtIntLiteralDec(.one_usize)});
7453 f.indent();
7454 try f.newline();
7455 return .{ .index = local };
7456 },
7457 }
82837458 }
82847459
82857460 pub fn elem(self: Vectorize, f: *Function, w: *Writer) !void {
82867461 if (self.index != .none) {
8287 try w.writeByte('[');
8288 try f.writeCValue(w, self.index, .Other);
7462 try w.writeAll(".array[");
7463 try f.writeCValue(w, self.index, .other);
82897464 try w.writeByte(']');
82907465 }
82917466 }
82927467
82937468 pub fn end(self: Vectorize, f: *Function, inst: Air.Inst.Index, w: *Writer) !void {
82947469 if (self.index != .none) {
8295 try f.object.outdent();
7470 try f.outdent();
82967471 try w.writeByte('}');
8297 try f.object.newline();
7472 try f.newline();
82987473 try freeLocal(f, inst, self.index.new_local, null);
82997474 }
83007475 }
83017476};
83027477
8303fn lowersToArray(ty: Type, zcu: *Zcu) bool {
7478fn lowersToBigInt(ty: Type, zcu: *const Zcu) bool {
83047479 return switch (ty.zigTypeTag(zcu)) {
8305 .array, .vector => return true,
8306 else => return ty.isAbiInt(zcu) and toCIntBits(@as(u32, @intCast(ty.bitSize(zcu)))) == null,
7480 .int, .@"enum", .@"struct", .@"union" => CType.classifyInt(ty, zcu) == .big,
7481 else => false,
83077482 };
83087483}
83097484
......@@ -8329,8 +7504,8 @@ fn die(f: *Function, inst: Air.Inst.Index, ref: Air.Inst.Ref) !void {
83297504}
83307505
83317506fn freeLocal(f: *Function, inst: ?Air.Inst.Index, local_index: LocalIndex, ref_inst: ?Air.Inst.Index) !void {
8332 const gpa = f.object.dg.gpa;
8333 const local = &f.locals.items[local_index];
7507 const gpa = f.dg.gpa;
7508 const local = f.locals.items[local_index];
83347509 if (inst) |i| {
83357510 if (ref_inst) |operand| {
83367511 log.debug("%{d}: freeing t{d} (operand %{d})", .{ @intFromEnum(i), local_index, operand });
......@@ -8344,7 +7519,7 @@ fn freeLocal(f: *Function, inst: ?Air.Inst.Index, local_index: LocalIndex, ref_i
83447519 log.debug("freeing t{d}", .{local_index});
83457520 }
83467521 }
8347 const gop = try f.free_locals_map.getOrPut(gpa, local.getType());
7522 const gop = try f.free_locals_map.getOrPut(gpa, local);
83487523 if (!gop.found_existing) gop.value_ptr.* = .{};
83497524 if (std.debug.runtime_safety) {
83507525 // If this trips, an unfreeable allocation was attempted to be freed.
......@@ -8401,3 +7576,28 @@ fn deinitFreeLocalsMap(gpa: Allocator, map: *LocalsMap) void {
84017576 }
84027577 map.deinit(gpa);
84037578}
7579
7580fn renderErrorName(w: *Writer, err_name: []const u8) Writer.Error!void {
7581 try w.print("zig_error_{f}", .{fmtIdentUnsolo(err_name)});
7582}
7583
7584fn renderNavName(w: *Writer, nav_index: InternPool.Nav.Index, ip: *const InternPool) !void {
7585 const nav = ip.getNav(nav_index);
7586 if (nav.getExtern(ip)) |@"extern"| {
7587 try w.print("{f}", .{
7588 fmtIdentSolo(ip.getNav(@"extern".owner_nav).name.toSlice(ip)),
7589 });
7590 } else {
7591 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),
7592 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.
7593 const fqn_slice = ip.getNav(nav_index).fqn.toSlice(ip);
7594 try w.print("{f}__{d}", .{
7595 fmtIdentUnsolo(fqn_slice[0..@min(fqn_slice.len, 100)]),
7596 @intFromEnum(nav_index),
7597 });
7598 }
7599}
7600
7601fn renderUavName(w: *Writer, uav: Value) !void {
7602 try w.print("__anon_{d}", .{@intFromEnum(uav.toIntern())});
7603}
src/codegen/c/Type.zig deleted-3472
......@@ -1,3472 +0,0 @@
1index: CType.Index,
2
3pub const @"void": CType = .{ .index = .void };
4pub const @"bool": CType = .{ .index = .bool };
5pub const @"i8": CType = .{ .index = .int8_t };
6pub const @"u8": CType = .{ .index = .uint8_t };
7pub const @"i16": CType = .{ .index = .int16_t };
8pub const @"u16": CType = .{ .index = .uint16_t };
9pub const @"i32": CType = .{ .index = .int32_t };
10pub const @"u32": CType = .{ .index = .uint32_t };
11pub const @"i64": CType = .{ .index = .int64_t };
12pub const @"u64": CType = .{ .index = .uint64_t };
13pub const @"i128": CType = .{ .index = .zig_i128 };
14pub const @"u128": CType = .{ .index = .zig_u128 };
15pub const @"isize": CType = .{ .index = .intptr_t };
16pub const @"usize": CType = .{ .index = .uintptr_t };
17pub const @"f16": CType = .{ .index = .zig_f16 };
18pub const @"f32": CType = .{ .index = .zig_f32 };
19pub const @"f64": CType = .{ .index = .zig_f64 };
20pub const @"f80": CType = .{ .index = .zig_f80 };
21pub const @"f128": CType = .{ .index = .zig_f128 };
22
23pub fn fromPoolIndex(pool_index: usize) CType {
24 return .{ .index = @enumFromInt(CType.Index.first_pool_index + pool_index) };
25}
26
27pub fn toPoolIndex(ctype: CType) ?u32 {
28 const pool_index, const is_null =
29 @subWithOverflow(@intFromEnum(ctype.index), CType.Index.first_pool_index);
30 return switch (is_null) {
31 0 => pool_index,
32 1 => null,
33 };
34}
35
36pub fn eql(lhs: CType, rhs: CType) bool {
37 return lhs.index == rhs.index;
38}
39
40pub fn isBool(ctype: CType) bool {
41 return switch (ctype.index) {
42 ._Bool, .bool => true,
43 else => false,
44 };
45}
46
47pub fn isInteger(ctype: CType) bool {
48 return switch (ctype.index) {
49 .char,
50 .@"signed char",
51 .short,
52 .int,
53 .long,
54 .@"long long",
55 .@"unsigned char",
56 .@"unsigned short",
57 .@"unsigned int",
58 .@"unsigned long",
59 .@"unsigned long long",
60 .size_t,
61 .ptrdiff_t,
62 .uint8_t,
63 .int8_t,
64 .uint16_t,
65 .int16_t,
66 .uint32_t,
67 .int32_t,
68 .uint64_t,
69 .int64_t,
70 .uintptr_t,
71 .intptr_t,
72 .zig_u128,
73 .zig_i128,
74 => true,
75 else => false,
76 };
77}
78
79pub fn signedness(ctype: CType, mod: *Module) std.builtin.Signedness {
80 return switch (ctype.index) {
81 .char => mod.resolved_target.result.cCharSignedness(),
82 .@"signed char",
83 .short,
84 .int,
85 .long,
86 .@"long long",
87 .ptrdiff_t,
88 .int8_t,
89 .int16_t,
90 .int32_t,
91 .int64_t,
92 .intptr_t,
93 .zig_i128,
94 => .signed,
95 .@"unsigned char",
96 .@"unsigned short",
97 .@"unsigned int",
98 .@"unsigned long",
99 .@"unsigned long long",
100 .size_t,
101 .uint8_t,
102 .uint16_t,
103 .uint32_t,
104 .uint64_t,
105 .uintptr_t,
106 .zig_u128,
107 => .unsigned,
108 else => unreachable,
109 };
110}
111
112pub fn isFloat(ctype: CType) bool {
113 return switch (ctype.index) {
114 .float,
115 .double,
116 .@"long double",
117 .zig_f16,
118 .zig_f32,
119 .zig_f64,
120 .zig_f80,
121 .zig_f128,
122 .zig_c_longdouble,
123 => true,
124 else => false,
125 };
126}
127
128pub fn toSigned(ctype: CType) CType {
129 return switch (ctype.index) {
130 .char, .@"signed char", .@"unsigned char" => .{ .index = .@"signed char" },
131 .short, .@"unsigned short" => .{ .index = .short },
132 .int, .@"unsigned int" => .{ .index = .int },
133 .long, .@"unsigned long" => .{ .index = .long },
134 .@"long long", .@"unsigned long long" => .{ .index = .@"long long" },
135 .size_t, .ptrdiff_t => .{ .index = .ptrdiff_t },
136 .uint8_t, .int8_t => .{ .index = .int8_t },
137 .uint16_t, .int16_t => .{ .index = .int16_t },
138 .uint32_t, .int32_t => .{ .index = .int32_t },
139 .uint64_t, .int64_t => .{ .index = .int64_t },
140 .uintptr_t, .intptr_t => .{ .index = .intptr_t },
141 .zig_u128, .zig_i128 => .{ .index = .zig_i128 },
142 .float,
143 .double,
144 .@"long double",
145 .zig_f16,
146 .zig_f32,
147 .zig_f80,
148 .zig_f128,
149 .zig_c_longdouble,
150 => ctype,
151 else => unreachable,
152 };
153}
154
155pub fn toUnsigned(ctype: CType) CType {
156 return switch (ctype.index) {
157 .char, .@"signed char", .@"unsigned char" => .{ .index = .@"unsigned char" },
158 .short, .@"unsigned short" => .{ .index = .@"unsigned short" },
159 .int, .@"unsigned int" => .{ .index = .@"unsigned int" },
160 .long, .@"unsigned long" => .{ .index = .@"unsigned long" },
161 .@"long long", .@"unsigned long long" => .{ .index = .@"unsigned long long" },
162 .size_t, .ptrdiff_t => .{ .index = .size_t },
163 .uint8_t, .int8_t => .{ .index = .uint8_t },
164 .uint16_t, .int16_t => .{ .index = .uint16_t },
165 .uint32_t, .int32_t => .{ .index = .uint32_t },
166 .uint64_t, .int64_t => .{ .index = .uint64_t },
167 .uintptr_t, .intptr_t => .{ .index = .uintptr_t },
168 .zig_u128, .zig_i128 => .{ .index = .zig_u128 },
169 else => unreachable,
170 };
171}
172
173pub fn toSignedness(ctype: CType, s: std.builtin.Signedness) CType {
174 return switch (s) {
175 .unsigned => ctype.toUnsigned(),
176 .signed => ctype.toSigned(),
177 };
178}
179
180pub fn isAnyChar(ctype: CType) bool {
181 return switch (ctype.index) {
182 else => false,
183 .char, .@"signed char", .@"unsigned char", .uint8_t, .int8_t => true,
184 };
185}
186
187pub fn isString(ctype: CType, pool: *const Pool) bool {
188 return info: switch (ctype.info(pool)) {
189 .basic, .fwd_decl, .aggregate, .function => false,
190 .pointer => |pointer_info| pointer_info.elem_ctype.isAnyChar(),
191 .aligned => |aligned_info| continue :info aligned_info.ctype.info(pool),
192 .array, .vector => |sequence_info| sequence_info.elem_type.isAnyChar(),
193 };
194}
195
196pub fn isNonString(ctype: CType, pool: *const Pool) bool {
197 var allow_pointer = true;
198 return info: switch (ctype.info(pool)) {
199 .basic, .fwd_decl, .aggregate, .function => false,
200 .pointer => |pointer_info| allow_pointer and pointer_info.nonstring,
201 .aligned => |aligned_info| continue :info aligned_info.ctype.info(pool),
202 .array, .vector => |sequence_info| sequence_info.nonstring or {
203 allow_pointer = false;
204 continue :info sequence_info.elem_ctype.info(pool);
205 },
206 };
207}
208
209pub fn getStandardDefineAbbrev(ctype: CType) ?[]const u8 {
210 return switch (ctype.index) {
211 .char => "CHAR",
212 .@"signed char" => "SCHAR",
213 .short => "SHRT",
214 .int => "INT",
215 .long => "LONG",
216 .@"long long" => "LLONG",
217 .@"unsigned char" => "UCHAR",
218 .@"unsigned short" => "USHRT",
219 .@"unsigned int" => "UINT",
220 .@"unsigned long" => "ULONG",
221 .@"unsigned long long" => "ULLONG",
222 .float => "FLT",
223 .double => "DBL",
224 .@"long double" => "LDBL",
225 .size_t => "SIZE",
226 .ptrdiff_t => "PTRDIFF",
227 .uint8_t => "UINT8",
228 .int8_t => "INT8",
229 .uint16_t => "UINT16",
230 .int16_t => "INT16",
231 .uint32_t => "UINT32",
232 .int32_t => "INT32",
233 .uint64_t => "UINT64",
234 .int64_t => "INT64",
235 .uintptr_t => "UINTPTR",
236 .intptr_t => "INTPTR",
237 else => null,
238 };
239}
240
241pub fn renderLiteralPrefix(ctype: CType, w: *Writer, kind: Kind, pool: *const Pool) Writer.Error!void {
242 switch (ctype.info(pool)) {
243 .basic => |basic_info| switch (basic_info) {
244 .void => unreachable,
245 ._Bool,
246 .char,
247 .@"signed char",
248 .short,
249 .@"unsigned short",
250 .bool,
251 .size_t,
252 .ptrdiff_t,
253 .uintptr_t,
254 .intptr_t,
255 => switch (kind) {
256 else => try w.print("({s})", .{@tagName(basic_info)}),
257 .global => {},
258 },
259 .int,
260 .long,
261 .@"long long",
262 .@"unsigned char",
263 .@"unsigned int",
264 .@"unsigned long",
265 .@"unsigned long long",
266 .float,
267 .double,
268 .@"long double",
269 => {},
270 .uint8_t,
271 .int8_t,
272 .uint16_t,
273 .int16_t,
274 .uint32_t,
275 .int32_t,
276 .uint64_t,
277 .int64_t,
278 => try w.print("{s}_C(", .{ctype.getStandardDefineAbbrev().?}),
279 .zig_u128,
280 .zig_i128,
281 .zig_f16,
282 .zig_f32,
283 .zig_f64,
284 .zig_f80,
285 .zig_f128,
286 .zig_c_longdouble,
287 => try w.print("zig_{s}_{s}(", .{
288 switch (kind) {
289 else => "make",
290 .global => "init",
291 },
292 @tagName(basic_info)["zig_".len..],
293 }),
294 .va_list => unreachable,
295 _ => unreachable,
296 },
297 .array, .vector => try w.writeByte('{'),
298 else => unreachable,
299 }
300}
301
302pub fn renderLiteralSuffix(ctype: CType, w: *Writer, pool: *const Pool) Writer.Error!void {
303 switch (ctype.info(pool)) {
304 .basic => |basic_info| switch (basic_info) {
305 .void => unreachable,
306 ._Bool => {},
307 .char,
308 .@"signed char",
309 .short,
310 .int,
311 => {},
312 .long => try w.writeByte('l'),
313 .@"long long" => try w.writeAll("ll"),
314 .@"unsigned char",
315 .@"unsigned short",
316 .@"unsigned int",
317 => try w.writeByte('u'),
318 .@"unsigned long",
319 .size_t,
320 .uintptr_t,
321 => try w.writeAll("ul"),
322 .@"unsigned long long" => try w.writeAll("ull"),
323 .float => try w.writeByte('f'),
324 .double => {},
325 .@"long double" => try w.writeByte('l'),
326 .bool,
327 .ptrdiff_t,
328 .intptr_t,
329 => {},
330 .uint8_t,
331 .int8_t,
332 .uint16_t,
333 .int16_t,
334 .uint32_t,
335 .int32_t,
336 .uint64_t,
337 .int64_t,
338 .zig_u128,
339 .zig_i128,
340 .zig_f16,
341 .zig_f32,
342 .zig_f64,
343 .zig_f80,
344 .zig_f128,
345 .zig_c_longdouble,
346 => try w.writeByte(')'),
347 .va_list => unreachable,
348 _ => unreachable,
349 },
350 .array, .vector => try w.writeByte('}'),
351 else => unreachable,
352 }
353}
354
355pub fn floatActiveBits(ctype: CType, mod: *Module) u16 {
356 const target = &mod.resolved_target.result;
357 return switch (ctype.index) {
358 .float => target.cTypeBitSize(.float),
359 .double => target.cTypeBitSize(.double),
360 .@"long double", .zig_c_longdouble => target.cTypeBitSize(.longdouble),
361 .zig_f16 => 16,
362 .zig_f32 => 32,
363 .zig_f64 => 64,
364 .zig_f80 => 80,
365 .zig_f128 => 128,
366 else => unreachable,
367 };
368}
369
370pub fn byteSize(ctype: CType, pool: *const Pool, mod: *Module) u64 {
371 const target = &mod.resolved_target.result;
372 return switch (ctype.info(pool)) {
373 .basic => |basic_info| switch (basic_info) {
374 .void => 0,
375 .char, .@"signed char", ._Bool, .@"unsigned char", .bool, .uint8_t, .int8_t => 1,
376 .short => target.cTypeByteSize(.short),
377 .int => target.cTypeByteSize(.int),
378 .long => target.cTypeByteSize(.long),
379 .@"long long" => target.cTypeByteSize(.longlong),
380 .@"unsigned short" => target.cTypeByteSize(.ushort),
381 .@"unsigned int" => target.cTypeByteSize(.uint),
382 .@"unsigned long" => target.cTypeByteSize(.ulong),
383 .@"unsigned long long" => target.cTypeByteSize(.ulonglong),
384 .float => target.cTypeByteSize(.float),
385 .double => target.cTypeByteSize(.double),
386 .@"long double" => target.cTypeByteSize(.longdouble),
387 .size_t,
388 .ptrdiff_t,
389 .uintptr_t,
390 .intptr_t,
391 => @divExact(target.ptrBitWidth(), 8),
392 .uint16_t, .int16_t, .zig_f16 => 2,
393 .uint32_t, .int32_t, .zig_f32 => 4,
394 .uint64_t, .int64_t, .zig_f64 => 8,
395 .zig_u128, .zig_i128, .zig_f128 => 16,
396 .zig_f80 => if (target.cTypeBitSize(.longdouble) == 80)
397 target.cTypeByteSize(.longdouble)
398 else
399 16,
400 .zig_c_longdouble => target.cTypeByteSize(.longdouble),
401 .va_list => unreachable,
402 _ => unreachable,
403 },
404 .pointer => @divExact(target.ptrBitWidth(), 8),
405 .array, .vector => |sequence_info| sequence_info.elem_ctype.byteSize(pool, mod) * sequence_info.len,
406 else => unreachable,
407 };
408}
409
410pub fn info(ctype: CType, pool: *const Pool) Info {
411 const pool_index = ctype.toPoolIndex() orelse return .{ .basic = ctype.index };
412 const item = pool.items.get(pool_index);
413 switch (item.tag) {
414 .basic => unreachable,
415 .pointer => return .{ .pointer = .{
416 .elem_ctype = .{ .index = @enumFromInt(item.data) },
417 } },
418 .pointer_const => return .{ .pointer = .{
419 .elem_ctype = .{ .index = @enumFromInt(item.data) },
420 .@"const" = true,
421 } },
422 .pointer_volatile => return .{ .pointer = .{
423 .elem_ctype = .{ .index = @enumFromInt(item.data) },
424 .@"volatile" = true,
425 } },
426 .pointer_const_volatile => return .{ .pointer = .{
427 .elem_ctype = .{ .index = @enumFromInt(item.data) },
428 .@"const" = true,
429 .@"volatile" = true,
430 } },
431 .aligned => {
432 const extra = pool.getExtra(Pool.Aligned, item.data);
433 return .{ .aligned = .{
434 .ctype = .{ .index = extra.ctype },
435 .alignas = extra.flags.alignas,
436 } };
437 },
438 .array_small => {
439 const extra = pool.getExtra(Pool.SequenceSmall, item.data);
440 return .{ .array = .{
441 .elem_ctype = .{ .index = extra.elem_ctype },
442 .len = extra.len,
443 } };
444 },
445 .array_large => {
446 const extra = pool.getExtra(Pool.SequenceLarge, item.data);
447 return .{ .array = .{
448 .elem_ctype = .{ .index = extra.elem_ctype },
449 .len = extra.len(),
450 } };
451 },
452 .vector => {
453 const extra = pool.getExtra(Pool.SequenceSmall, item.data);
454 return .{ .vector = .{
455 .elem_ctype = .{ .index = extra.elem_ctype },
456 .len = extra.len,
457 } };
458 },
459 .nonstring => {
460 var child_info = info(.{ .index = @enumFromInt(item.data) }, pool);
461 switch (child_info) {
462 else => unreachable,
463 .pointer => |*pointer_info| pointer_info.nonstring = true,
464 .array, .vector => |*sequence_info| sequence_info.nonstring = true,
465 }
466 return child_info;
467 },
468 .fwd_decl_struct_anon => {
469 const extra_trail = pool.getExtraTrail(Pool.FwdDeclAnon, item.data);
470 return .{ .fwd_decl = .{
471 .tag = .@"struct",
472 .name = .{ .anon = .{
473 .extra_index = extra_trail.trail.extra_index,
474 .len = extra_trail.extra.fields_len,
475 } },
476 } };
477 },
478 .fwd_decl_union_anon => {
479 const extra_trail = pool.getExtraTrail(Pool.FwdDeclAnon, item.data);
480 return .{ .fwd_decl = .{
481 .tag = .@"union",
482 .name = .{ .anon = .{
483 .extra_index = extra_trail.trail.extra_index,
484 .len = extra_trail.extra.fields_len,
485 } },
486 } };
487 },
488 .fwd_decl_struct => return .{ .fwd_decl = .{
489 .tag = .@"struct",
490 .name = .{ .index = @enumFromInt(item.data) },
491 } },
492 .fwd_decl_union => return .{ .fwd_decl = .{
493 .tag = .@"union",
494 .name = .{ .index = @enumFromInt(item.data) },
495 } },
496 .aggregate_struct_anon => {
497 const extra_trail = pool.getExtraTrail(Pool.AggregateAnon, item.data);
498 return .{ .aggregate = .{
499 .tag = .@"struct",
500 .name = .{ .anon = .{
501 .index = extra_trail.extra.index,
502 .id = extra_trail.extra.id,
503 } },
504 .fields = .{
505 .extra_index = extra_trail.trail.extra_index,
506 .len = extra_trail.extra.fields_len,
507 },
508 } };
509 },
510 .aggregate_union_anon => {
511 const extra_trail = pool.getExtraTrail(Pool.AggregateAnon, item.data);
512 return .{ .aggregate = .{
513 .tag = .@"union",
514 .name = .{ .anon = .{
515 .index = extra_trail.extra.index,
516 .id = extra_trail.extra.id,
517 } },
518 .fields = .{
519 .extra_index = extra_trail.trail.extra_index,
520 .len = extra_trail.extra.fields_len,
521 },
522 } };
523 },
524 .aggregate_struct_packed_anon => {
525 const extra_trail = pool.getExtraTrail(Pool.AggregateAnon, item.data);
526 return .{ .aggregate = .{
527 .tag = .@"struct",
528 .@"packed" = true,
529 .name = .{ .anon = .{
530 .index = extra_trail.extra.index,
531 .id = extra_trail.extra.id,
532 } },
533 .fields = .{
534 .extra_index = extra_trail.trail.extra_index,
535 .len = extra_trail.extra.fields_len,
536 },
537 } };
538 },
539 .aggregate_union_packed_anon => {
540 const extra_trail = pool.getExtraTrail(Pool.AggregateAnon, item.data);
541 return .{ .aggregate = .{
542 .tag = .@"union",
543 .@"packed" = true,
544 .name = .{ .anon = .{
545 .index = extra_trail.extra.index,
546 .id = extra_trail.extra.id,
547 } },
548 .fields = .{
549 .extra_index = extra_trail.trail.extra_index,
550 .len = extra_trail.extra.fields_len,
551 },
552 } };
553 },
554 .aggregate_struct => {
555 const extra_trail = pool.getExtraTrail(Pool.Aggregate, item.data);
556 return .{ .aggregate = .{
557 .tag = .@"struct",
558 .name = .{ .fwd_decl = .{ .index = extra_trail.extra.fwd_decl } },
559 .fields = .{
560 .extra_index = extra_trail.trail.extra_index,
561 .len = extra_trail.extra.fields_len,
562 },
563 } };
564 },
565 .aggregate_union => {
566 const extra_trail = pool.getExtraTrail(Pool.Aggregate, item.data);
567 return .{ .aggregate = .{
568 .tag = .@"union",
569 .name = .{ .fwd_decl = .{ .index = extra_trail.extra.fwd_decl } },
570 .fields = .{
571 .extra_index = extra_trail.trail.extra_index,
572 .len = extra_trail.extra.fields_len,
573 },
574 } };
575 },
576 .aggregate_struct_packed => {
577 const extra_trail = pool.getExtraTrail(Pool.Aggregate, item.data);
578 return .{ .aggregate = .{
579 .tag = .@"struct",
580 .@"packed" = true,
581 .name = .{ .fwd_decl = .{ .index = extra_trail.extra.fwd_decl } },
582 .fields = .{
583 .extra_index = extra_trail.trail.extra_index,
584 .len = extra_trail.extra.fields_len,
585 },
586 } };
587 },
588 .aggregate_union_packed => {
589 const extra_trail = pool.getExtraTrail(Pool.Aggregate, item.data);
590 return .{ .aggregate = .{
591 .tag = .@"union",
592 .@"packed" = true,
593 .name = .{ .fwd_decl = .{ .index = extra_trail.extra.fwd_decl } },
594 .fields = .{
595 .extra_index = extra_trail.trail.extra_index,
596 .len = extra_trail.extra.fields_len,
597 },
598 } };
599 },
600 .function => {
601 const extra_trail = pool.getExtraTrail(Pool.Function, item.data);
602 return .{ .function = .{
603 .return_ctype = .{ .index = extra_trail.extra.return_ctype },
604 .param_ctypes = .{
605 .extra_index = extra_trail.trail.extra_index,
606 .len = extra_trail.extra.param_ctypes_len,
607 },
608 .varargs = false,
609 } };
610 },
611 .function_varargs => {
612 const extra_trail = pool.getExtraTrail(Pool.Function, item.data);
613 return .{ .function = .{
614 .return_ctype = .{ .index = extra_trail.extra.return_ctype },
615 .param_ctypes = .{
616 .extra_index = extra_trail.trail.extra_index,
617 .len = extra_trail.extra.param_ctypes_len,
618 },
619 .varargs = true,
620 } };
621 },
622 }
623}
624
625pub fn hash(ctype: CType, pool: *const Pool) Pool.Map.Hash {
626 return if (ctype.toPoolIndex()) |pool_index|
627 pool.map.entries.items(.hash)[pool_index]
628 else
629 CType.Index.basic_hashes[@intFromEnum(ctype.index)];
630}
631
632fn toForward(ctype: CType, pool: *Pool, allocator: std.mem.Allocator) !CType {
633 return switch (ctype.info(pool)) {
634 .basic, .pointer, .fwd_decl => ctype,
635 .aligned => |aligned_info| pool.getAligned(allocator, .{
636 .ctype = try aligned_info.ctype.toForward(pool, allocator),
637 .alignas = aligned_info.alignas,
638 }),
639 .array => |array_info| pool.getArray(allocator, .{
640 .elem_ctype = try array_info.elem_ctype.toForward(pool, allocator),
641 .len = array_info.len,
642 .nonstring = array_info.nonstring,
643 }),
644 .vector => |vector_info| pool.getVector(allocator, .{
645 .elem_ctype = try vector_info.elem_ctype.toForward(pool, allocator),
646 .len = vector_info.len,
647 .nonstring = vector_info.nonstring,
648 }),
649 .aggregate => |aggregate_info| switch (aggregate_info.name) {
650 .anon => ctype,
651 .fwd_decl => |fwd_decl| fwd_decl,
652 },
653 .function => unreachable,
654 };
655}
656
657const Index = enum(u32) {
658 void,
659
660 // C basic types
661 char,
662
663 @"signed char",
664 short,
665 int,
666 long,
667 @"long long",
668
669 _Bool,
670 @"unsigned char",
671 @"unsigned short",
672 @"unsigned int",
673 @"unsigned long",
674 @"unsigned long long",
675
676 float,
677 double,
678 @"long double",
679
680 // C header types
681 // - stdbool.h
682 bool,
683 // - stddef.h
684 size_t,
685 ptrdiff_t,
686 // - stdint.h
687 uint8_t,
688 int8_t,
689 uint16_t,
690 int16_t,
691 uint32_t,
692 int32_t,
693 uint64_t,
694 int64_t,
695 uintptr_t,
696 intptr_t,
697 // - stdarg.h
698 va_list,
699
700 // zig.h types
701 zig_u128,
702 zig_i128,
703 zig_f16,
704 zig_f32,
705 zig_f64,
706 zig_f80,
707 zig_f128,
708 zig_c_longdouble,
709
710 _,
711
712 const first_pool_index: u32 = @typeInfo(CType.Index).@"enum".fields.len;
713 const basic_hashes = init: {
714 @setEvalBranchQuota(1_600);
715 var basic_hashes_init: [first_pool_index]Pool.Map.Hash = undefined;
716 for (&basic_hashes_init, 0..) |*basic_hash, index| {
717 const ctype_index: CType.Index = @enumFromInt(index);
718 var hasher = Pool.Hasher.init;
719 hasher.update(@intFromEnum(ctype_index));
720 basic_hash.* = hasher.final(.basic);
721 }
722 break :init basic_hashes_init;
723 };
724};
725
726const Slice = struct {
727 extra_index: Pool.ExtraIndex,
728 len: u32,
729
730 pub fn at(slice: CType.Slice, index: usize, pool: *const Pool) CType {
731 var extra: Pool.ExtraTrail = .{ .extra_index = slice.extra_index };
732 return .{ .index = extra.next(slice.len, CType.Index, pool)[index] };
733 }
734};
735
736pub const Kind = enum {
737 forward,
738 forward_parameter,
739 complete,
740 global,
741 parameter,
742
743 pub fn isForward(kind: Kind) bool {
744 return switch (kind) {
745 .forward, .forward_parameter => true,
746 .complete, .global, .parameter => false,
747 };
748 }
749
750 pub fn isParameter(kind: Kind) bool {
751 return switch (kind) {
752 .forward_parameter, .parameter => true,
753 .forward, .complete, .global => false,
754 };
755 }
756
757 pub fn asParameter(kind: Kind) Kind {
758 return switch (kind) {
759 .forward, .forward_parameter => .forward_parameter,
760 .complete, .parameter, .global => .parameter,
761 };
762 }
763
764 pub fn noParameter(kind: Kind) Kind {
765 return switch (kind) {
766 .forward, .forward_parameter => .forward,
767 .complete, .parameter => .complete,
768 .global => .global,
769 };
770 }
771
772 pub fn asComplete(kind: Kind) Kind {
773 return switch (kind) {
774 .forward, .complete => .complete,
775 .forward_parameter, .parameter => .parameter,
776 .global => .global,
777 };
778 }
779};
780
781pub const Info = union(enum) {
782 basic: CType.Index,
783 pointer: Pointer,
784 aligned: Aligned,
785 array: Sequence,
786 vector: Sequence,
787 fwd_decl: FwdDecl,
788 aggregate: Aggregate,
789 function: Function,
790
791 const Tag = @typeInfo(Info).@"union".tag_type.?;
792
793 pub const Pointer = struct {
794 elem_ctype: CType,
795 @"const": bool = false,
796 @"volatile": bool = false,
797 nonstring: bool = false,
798
799 fn tag(pointer_info: Pointer) Pool.Tag {
800 return @enumFromInt(@intFromEnum(Pool.Tag.pointer) +
801 @as(u2, @bitCast(packed struct(u2) {
802 @"const": bool,
803 @"volatile": bool,
804 }{
805 .@"const" = pointer_info.@"const",
806 .@"volatile" = pointer_info.@"volatile",
807 })));
808 }
809 };
810
811 pub const Aligned = struct {
812 ctype: CType,
813 alignas: AlignAs,
814 };
815
816 pub const Sequence = struct {
817 elem_ctype: CType,
818 len: u64,
819 nonstring: bool = false,
820 };
821
822 pub const AggregateTag = enum { @"enum", @"struct", @"union" };
823
824 pub const Field = struct {
825 name: Pool.String,
826 ctype: CType,
827 alignas: AlignAs,
828
829 pub const Slice = struct {
830 extra_index: Pool.ExtraIndex,
831 len: u32,
832
833 pub fn at(slice: Field.Slice, index: usize, pool: *const Pool) Field {
834 assert(index < slice.len);
835 const extra = pool.getExtra(Pool.Field, @intCast(slice.extra_index +
836 index * @typeInfo(Pool.Field).@"struct".fields.len));
837 return .{
838 .name = .{ .index = extra.name },
839 .ctype = .{ .index = extra.ctype },
840 .alignas = extra.flags.alignas,
841 };
842 }
843
844 fn eqlAdapted(
845 lhs_slice: Field.Slice,
846 lhs_pool: *const Pool,
847 rhs_slice: Field.Slice,
848 rhs_pool: *const Pool,
849 pool_adapter: anytype,
850 ) bool {
851 if (lhs_slice.len != rhs_slice.len) return false;
852 for (0..lhs_slice.len) |index| {
853 if (!lhs_slice.at(index, lhs_pool).eqlAdapted(
854 lhs_pool,
855 rhs_slice.at(index, rhs_pool),
856 rhs_pool,
857 pool_adapter,
858 )) return false;
859 }
860 return true;
861 }
862 };
863
864 fn eqlAdapted(
865 lhs_field: Field,
866 lhs_pool: *const Pool,
867 rhs_field: Field,
868 rhs_pool: *const Pool,
869 pool_adapter: anytype,
870 ) bool {
871 if (!std.meta.eql(lhs_field.alignas, rhs_field.alignas)) return false;
872 if (!pool_adapter.eql(lhs_field.ctype, rhs_field.ctype)) return false;
873 return if (lhs_field.name.toPoolSlice(lhs_pool)) |lhs_name|
874 if (rhs_field.name.toPoolSlice(rhs_pool)) |rhs_name|
875 std.mem.eql(u8, lhs_name, rhs_name)
876 else
877 false
878 else
879 lhs_field.name.index == rhs_field.name.index;
880 }
881 };
882
883 pub const FwdDecl = struct {
884 tag: AggregateTag,
885 name: union(enum) {
886 anon: Field.Slice,
887 index: InternPool.Index,
888 },
889 };
890
891 pub const Aggregate = struct {
892 tag: AggregateTag,
893 @"packed": bool = false,
894 name: union(enum) {
895 anon: struct {
896 index: InternPool.Index,
897 id: u32,
898 },
899 fwd_decl: CType,
900 },
901 fields: Field.Slice,
902 };
903
904 pub const Function = struct {
905 return_ctype: CType,
906 param_ctypes: CType.Slice,
907 varargs: bool = false,
908 };
909
910 pub fn eqlAdapted(
911 lhs_info: Info,
912 lhs_pool: *const Pool,
913 rhs_ctype: CType,
914 rhs_pool: *const Pool,
915 pool_adapter: anytype,
916 ) bool {
917 const rhs_info = rhs_ctype.info(rhs_pool);
918 if (@as(Info.Tag, lhs_info) != @as(Info.Tag, rhs_info)) return false;
919 return switch (lhs_info) {
920 .basic => |lhs_basic_info| lhs_basic_info == rhs_info.basic,
921 .pointer => |lhs_pointer_info| lhs_pointer_info.@"const" == rhs_info.pointer.@"const" and
922 lhs_pointer_info.@"volatile" == rhs_info.pointer.@"volatile" and
923 lhs_pointer_info.nonstring == rhs_info.pointer.nonstring and
924 pool_adapter.eql(lhs_pointer_info.elem_ctype, rhs_info.pointer.elem_ctype),
925 .aligned => |lhs_aligned_info| std.meta.eql(lhs_aligned_info.alignas, rhs_info.aligned.alignas) and
926 pool_adapter.eql(lhs_aligned_info.ctype, rhs_info.aligned.ctype),
927 .array => |lhs_array_info| lhs_array_info.len == rhs_info.array.len and
928 lhs_array_info.nonstring == rhs_info.array.nonstring and
929 pool_adapter.eql(lhs_array_info.elem_ctype, rhs_info.array.elem_ctype),
930 .vector => |lhs_vector_info| lhs_vector_info.len == rhs_info.vector.len and
931 lhs_vector_info.nonstring == rhs_info.vector.nonstring and
932 pool_adapter.eql(lhs_vector_info.elem_ctype, rhs_info.vector.elem_ctype),
933 .fwd_decl => |lhs_fwd_decl_info| lhs_fwd_decl_info.tag == rhs_info.fwd_decl.tag and
934 switch (lhs_fwd_decl_info.name) {
935 .anon => |lhs_anon| rhs_info.fwd_decl.name == .anon and lhs_anon.eqlAdapted(
936 lhs_pool,
937 rhs_info.fwd_decl.name.anon,
938 rhs_pool,
939 pool_adapter,
940 ),
941 .index => |lhs_index| rhs_info.fwd_decl.name == .index and
942 lhs_index == rhs_info.fwd_decl.name.index,
943 },
944 .aggregate => |lhs_aggregate_info| lhs_aggregate_info.tag == rhs_info.aggregate.tag and
945 lhs_aggregate_info.@"packed" == rhs_info.aggregate.@"packed" and
946 switch (lhs_aggregate_info.name) {
947 .anon => |lhs_anon| rhs_info.aggregate.name == .anon and
948 lhs_anon.index == rhs_info.aggregate.name.anon.index and
949 lhs_anon.id == rhs_info.aggregate.name.anon.id,
950 .fwd_decl => |lhs_fwd_decl| rhs_info.aggregate.name == .fwd_decl and
951 pool_adapter.eql(lhs_fwd_decl, rhs_info.aggregate.name.fwd_decl),
952 } and lhs_aggregate_info.fields.eqlAdapted(
953 lhs_pool,
954 rhs_info.aggregate.fields,
955 rhs_pool,
956 pool_adapter,
957 ),
958 .function => |lhs_function_info| lhs_function_info.param_ctypes.len ==
959 rhs_info.function.param_ctypes.len and
960 pool_adapter.eql(lhs_function_info.return_ctype, rhs_info.function.return_ctype) and
961 for (0..lhs_function_info.param_ctypes.len) |param_index| {
962 if (!pool_adapter.eql(
963 lhs_function_info.param_ctypes.at(param_index, lhs_pool),
964 rhs_info.function.param_ctypes.at(param_index, rhs_pool),
965 )) break false;
966 } else true,
967 };
968 }
969};
970
971pub const Pool = struct {
972 map: Map,
973 items: std.MultiArrayList(Item),
974 extra: std.ArrayList(u32),
975
976 string_map: Map,
977 string_indices: std.ArrayList(u32),
978 string_bytes: std.ArrayList(u8),
979
980 const Map = std.AutoArrayHashMapUnmanaged(void, void);
981
982 pub const String = struct {
983 index: String.Index,
984
985 const FormatData = struct { string: String, pool: *const Pool };
986 fn format(data: FormatData, writer: *Writer) Writer.Error!void {
987 if (data.string.toSlice(data.pool)) |slice|
988 try writer.writeAll(slice)
989 else
990 try writer.print("f{d}", .{@intFromEnum(data.string.index)});
991 }
992 pub fn fmt(str: String, pool: *const Pool) std.fmt.Alt(FormatData, format) {
993 return .{ .data = .{ .string = str, .pool = pool } };
994 }
995
996 fn fromUnnamed(index: u31) String {
997 return .{ .index = @enumFromInt(index) };
998 }
999
1000 fn isNamed(str: String) bool {
1001 return @intFromEnum(str.index) >= String.Index.first_named_index;
1002 }
1003
1004 pub fn toSlice(str: String, pool: *const Pool) ?[]const u8 {
1005 return str.toPoolSlice(pool) orelse if (str.isNamed()) @tagName(str.index) else null;
1006 }
1007
1008 fn toPoolSlice(str: String, pool: *const Pool) ?[]const u8 {
1009 if (str.toPoolIndex()) |pool_index| {
1010 const start = pool.string_indices.items[pool_index + 0];
1011 const end = pool.string_indices.items[pool_index + 1];
1012 return pool.string_bytes.items[start..end];
1013 } else return null;
1014 }
1015
1016 fn fromPoolIndex(pool_index: usize) String {
1017 return .{ .index = @enumFromInt(String.Index.first_pool_index + pool_index) };
1018 }
1019
1020 fn toPoolIndex(str: String) ?u32 {
1021 const pool_index, const is_null =
1022 @subWithOverflow(@intFromEnum(str.index), String.Index.first_pool_index);
1023 return switch (is_null) {
1024 0 => pool_index,
1025 1 => null,
1026 };
1027 }
1028
1029 const Index = enum(u32) {
1030 array = first_named_index,
1031 @"error",
1032 is_null,
1033 len,
1034 payload,
1035 ptr,
1036 tag,
1037 _,
1038
1039 const first_named_index: u32 = 1 << 31;
1040 const first_pool_index: u32 = first_named_index + @typeInfo(String.Index).@"enum".fields.len;
1041 };
1042
1043 const Adapter = struct {
1044 pool: *const Pool,
1045 pub fn hash(_: @This(), slice: []const u8) Map.Hash {
1046 return @truncate(Hasher.Impl.hash(1, slice));
1047 }
1048 pub fn eql(string_adapter: @This(), lhs_slice: []const u8, _: void, rhs_index: usize) bool {
1049 const rhs_string = String.fromPoolIndex(rhs_index);
1050 const rhs_slice = rhs_string.toPoolSlice(string_adapter.pool).?;
1051 return std.mem.eql(u8, lhs_slice, rhs_slice);
1052 }
1053 };
1054 };
1055
1056 pub const empty: Pool = .{
1057 .map = .{},
1058 .items = .{},
1059 .extra = .{},
1060
1061 .string_map = .{},
1062 .string_indices = .{},
1063 .string_bytes = .{},
1064 };
1065
1066 pub fn init(pool: *Pool, allocator: std.mem.Allocator) !void {
1067 if (pool.string_indices.items.len == 0)
1068 try pool.string_indices.append(allocator, 0);
1069 }
1070
1071 pub fn deinit(pool: *Pool, allocator: std.mem.Allocator) void {
1072 pool.map.deinit(allocator);
1073 pool.items.deinit(allocator);
1074 pool.extra.deinit(allocator);
1075
1076 pool.string_map.deinit(allocator);
1077 pool.string_indices.deinit(allocator);
1078 pool.string_bytes.deinit(allocator);
1079
1080 pool.* = undefined;
1081 }
1082
1083 pub fn move(pool: *Pool) Pool {
1084 defer pool.* = empty;
1085 return pool.*;
1086 }
1087
1088 pub fn clearRetainingCapacity(pool: *Pool) void {
1089 pool.map.clearRetainingCapacity();
1090 pool.items.shrinkRetainingCapacity(0);
1091 pool.extra.clearRetainingCapacity();
1092
1093 pool.string_map.clearRetainingCapacity();
1094 pool.string_indices.shrinkRetainingCapacity(1);
1095 pool.string_bytes.clearRetainingCapacity();
1096 }
1097
1098 pub fn freeUnusedCapacity(pool: *Pool, allocator: std.mem.Allocator) void {
1099 pool.map.shrinkAndFree(allocator, pool.map.count());
1100 pool.items.shrinkAndFree(allocator, pool.items.len);
1101 pool.extra.shrinkAndFree(allocator, pool.extra.items.len);
1102
1103 pool.string_map.shrinkAndFree(allocator, pool.string_map.count());
1104 pool.string_indices.shrinkAndFree(allocator, pool.string_indices.items.len);
1105 pool.string_bytes.shrinkAndFree(allocator, pool.string_bytes.items.len);
1106 }
1107
1108 pub fn getPointer(pool: *Pool, allocator: std.mem.Allocator, pointer_info: Info.Pointer) !CType {
1109 var hasher = Hasher.init;
1110 hasher.update(pointer_info.elem_ctype.hash(pool));
1111 return pool.getNonString(allocator, try pool.tagData(
1112 allocator,
1113 hasher,
1114 pointer_info.tag(),
1115 @intFromEnum(pointer_info.elem_ctype.index),
1116 ), pointer_info.nonstring);
1117 }
1118
1119 pub fn getAligned(pool: *Pool, allocator: std.mem.Allocator, aligned_info: Info.Aligned) !CType {
1120 return pool.tagExtra(allocator, .aligned, Aligned, .{
1121 .ctype = aligned_info.ctype.index,
1122 .flags = .{ .alignas = aligned_info.alignas },
1123 });
1124 }
1125
1126 pub fn getArray(pool: *Pool, allocator: std.mem.Allocator, array_info: Info.Sequence) !CType {
1127 return pool.getNonString(allocator, if (std.math.cast(u32, array_info.len)) |small_len|
1128 try pool.tagExtra(allocator, .array_small, SequenceSmall, .{
1129 .elem_ctype = array_info.elem_ctype.index,
1130 .len = small_len,
1131 })
1132 else
1133 try pool.tagExtra(allocator, .array_large, SequenceLarge, .{
1134 .elem_ctype = array_info.elem_ctype.index,
1135 .len_lo = @truncate(array_info.len >> 0),
1136 .len_hi = @truncate(array_info.len >> 32),
1137 }), array_info.nonstring);
1138 }
1139
1140 pub fn getVector(pool: *Pool, allocator: std.mem.Allocator, vector_info: Info.Sequence) !CType {
1141 return pool.getNonString(allocator, try pool.tagExtra(allocator, .vector, SequenceSmall, .{
1142 .elem_ctype = vector_info.elem_ctype.index,
1143 .len = @intCast(vector_info.len),
1144 }), vector_info.nonstring);
1145 }
1146
1147 pub fn getNonString(
1148 pool: *Pool,
1149 allocator: std.mem.Allocator,
1150 child_ctype: CType,
1151 nonstring: bool,
1152 ) !CType {
1153 if (!nonstring) return child_ctype;
1154 var hasher = Hasher.init;
1155 hasher.update(child_ctype.hash(pool));
1156 return pool.tagData(allocator, hasher, .nonstring, @intFromEnum(child_ctype.index));
1157 }
1158
1159 pub fn getFwdDecl(
1160 pool: *Pool,
1161 allocator: std.mem.Allocator,
1162 fwd_decl_info: struct {
1163 tag: Info.AggregateTag,
1164 name: union(enum) {
1165 anon: []const Info.Field,
1166 index: InternPool.Index,
1167 },
1168 },
1169 ) !CType {
1170 var hasher = Hasher.init;
1171 switch (fwd_decl_info.name) {
1172 .anon => |fields| {
1173 const ExpectedContents = [32]CType;
1174 var stack align(@max(
1175 @alignOf(std.heap.StackFallbackAllocator(0)),
1176 @alignOf(ExpectedContents),
1177 )) = std.heap.stackFallback(@sizeOf(ExpectedContents), allocator);
1178 const stack_allocator = stack.get();
1179 const field_ctypes = try stack_allocator.alloc(CType, fields.len);
1180 defer stack_allocator.free(field_ctypes);
1181 for (field_ctypes, fields) |*field_ctype, field|
1182 field_ctype.* = try field.ctype.toForward(pool, allocator);
1183 const extra: FwdDeclAnon = .{ .fields_len = @intCast(fields.len) };
1184 const extra_index = try pool.addExtra(
1185 allocator,
1186 FwdDeclAnon,
1187 extra,
1188 fields.len * @typeInfo(Field).@"struct".fields.len,
1189 );
1190 for (fields, field_ctypes) |field, field_ctype| pool.addHashedExtraAssumeCapacity(
1191 &hasher,
1192 Field,
1193 .{
1194 .name = field.name.index,
1195 .ctype = field_ctype.index,
1196 .flags = .{ .alignas = field.alignas },
1197 },
1198 );
1199 hasher.updateExtra(FwdDeclAnon, extra, pool);
1200 return pool.tagTrailingExtra(allocator, hasher, switch (fwd_decl_info.tag) {
1201 .@"struct" => .fwd_decl_struct_anon,
1202 .@"union" => .fwd_decl_union_anon,
1203 .@"enum" => unreachable,
1204 }, extra_index);
1205 },
1206 .index => |index| {
1207 hasher.update(index);
1208 return pool.tagData(allocator, hasher, switch (fwd_decl_info.tag) {
1209 .@"struct" => .fwd_decl_struct,
1210 .@"union" => .fwd_decl_union,
1211 .@"enum" => unreachable,
1212 }, @intFromEnum(index));
1213 },
1214 }
1215 }
1216
1217 pub fn getAggregate(
1218 pool: *Pool,
1219 allocator: std.mem.Allocator,
1220 aggregate_info: struct {
1221 tag: Info.AggregateTag,
1222 @"packed": bool = false,
1223 name: union(enum) {
1224 anon: struct {
1225 index: InternPool.Index,
1226 id: u32,
1227 },
1228 fwd_decl: CType,
1229 },
1230 fields: []const Info.Field,
1231 },
1232 ) !CType {
1233 var hasher = Hasher.init;
1234 switch (aggregate_info.name) {
1235 .anon => |anon| {
1236 const extra: AggregateAnon = .{
1237 .index = anon.index,
1238 .id = anon.id,
1239 .fields_len = @intCast(aggregate_info.fields.len),
1240 };
1241 const extra_index = try pool.addExtra(
1242 allocator,
1243 AggregateAnon,
1244 extra,
1245 aggregate_info.fields.len * @typeInfo(Field).@"struct".fields.len,
1246 );
1247 for (aggregate_info.fields) |field| pool.addHashedExtraAssumeCapacity(&hasher, Field, .{
1248 .name = field.name.index,
1249 .ctype = field.ctype.index,
1250 .flags = .{ .alignas = field.alignas },
1251 });
1252 hasher.updateExtra(AggregateAnon, extra, pool);
1253 return pool.tagTrailingExtra(allocator, hasher, switch (aggregate_info.tag) {
1254 .@"struct" => switch (aggregate_info.@"packed") {
1255 false => .aggregate_struct_anon,
1256 true => .aggregate_struct_packed_anon,
1257 },
1258 .@"union" => switch (aggregate_info.@"packed") {
1259 false => .aggregate_union_anon,
1260 true => .aggregate_union_packed_anon,
1261 },
1262 .@"enum" => unreachable,
1263 }, extra_index);
1264 },
1265 .fwd_decl => |fwd_decl| {
1266 const extra: Aggregate = .{
1267 .fwd_decl = fwd_decl.index,
1268 .fields_len = @intCast(aggregate_info.fields.len),
1269 };
1270 const extra_index = try pool.addExtra(
1271 allocator,
1272 Aggregate,
1273 extra,
1274 aggregate_info.fields.len * @typeInfo(Field).@"struct".fields.len,
1275 );
1276 for (aggregate_info.fields) |field| pool.addHashedExtraAssumeCapacity(&hasher, Field, .{
1277 .name = field.name.index,
1278 .ctype = field.ctype.index,
1279 .flags = .{ .alignas = field.alignas },
1280 });
1281 hasher.updateExtra(Aggregate, extra, pool);
1282 return pool.tagTrailingExtra(allocator, hasher, switch (aggregate_info.tag) {
1283 .@"struct" => switch (aggregate_info.@"packed") {
1284 false => .aggregate_struct,
1285 true => .aggregate_struct_packed,
1286 },
1287 .@"union" => switch (aggregate_info.@"packed") {
1288 false => .aggregate_union,
1289 true => .aggregate_union_packed,
1290 },
1291 .@"enum" => unreachable,
1292 }, extra_index);
1293 },
1294 }
1295 }
1296
1297 pub fn getFunction(
1298 pool: *Pool,
1299 allocator: std.mem.Allocator,
1300 function_info: struct {
1301 return_ctype: CType,
1302 param_ctypes: []const CType,
1303 varargs: bool = false,
1304 },
1305 ) !CType {
1306 var hasher = Hasher.init;
1307 const extra: Function = .{
1308 .return_ctype = function_info.return_ctype.index,
1309 .param_ctypes_len = @intCast(function_info.param_ctypes.len),
1310 };
1311 const extra_index = try pool.addExtra(allocator, Function, extra, function_info.param_ctypes.len);
1312 for (function_info.param_ctypes) |param_ctype| {
1313 hasher.update(param_ctype.hash(pool));
1314 pool.extra.appendAssumeCapacity(@intFromEnum(param_ctype.index));
1315 }
1316 hasher.updateExtra(Function, extra, pool);
1317 return pool.tagTrailingExtra(allocator, hasher, switch (function_info.varargs) {
1318 false => .function,
1319 true => .function_varargs,
1320 }, extra_index);
1321 }
1322
1323 pub fn fromFields(
1324 pool: *Pool,
1325 allocator: std.mem.Allocator,
1326 tag: Info.AggregateTag,
1327 fields: []Info.Field,
1328 kind: Kind,
1329 ) !CType {
1330 sortFields(fields);
1331 const fwd_decl = try pool.getFwdDecl(allocator, .{
1332 .tag = tag,
1333 .name = .{ .anon = fields },
1334 });
1335 return if (kind.isForward()) fwd_decl else pool.getAggregate(allocator, .{
1336 .tag = tag,
1337 .name = .{ .fwd_decl = fwd_decl },
1338 .fields = fields,
1339 });
1340 }
1341
1342 pub fn fromIntInfo(
1343 pool: *Pool,
1344 allocator: std.mem.Allocator,
1345 int_info: std.builtin.Type.Int,
1346 mod: *Module,
1347 kind: Kind,
1348 ) !CType {
1349 switch (int_info.bits) {
1350 0 => return .void,
1351 1...8 => switch (int_info.signedness) {
1352 .signed => return .i8,
1353 .unsigned => return .u8,
1354 },
1355 9...16 => switch (int_info.signedness) {
1356 .signed => return .i16,
1357 .unsigned => return .u16,
1358 },
1359 17...32 => switch (int_info.signedness) {
1360 .signed => return .i32,
1361 .unsigned => return .u32,
1362 },
1363 33...64 => switch (int_info.signedness) {
1364 .signed => return .i64,
1365 .unsigned => return .u64,
1366 },
1367 65...128 => switch (int_info.signedness) {
1368 .signed => return .i128,
1369 .unsigned => return .u128,
1370 },
1371 else => {
1372 const target = &mod.resolved_target.result;
1373 const abi_align_bytes = std.zig.target.intAlignment(target, int_info.bits);
1374 const limb_ctype = try pool.fromIntInfo(allocator, .{
1375 .signedness = .unsigned,
1376 .bits = @intCast(abi_align_bytes * 8),
1377 }, mod, kind.noParameter());
1378 const array_ctype = try pool.getArray(allocator, .{
1379 .len = @divExact(std.zig.target.intByteSize(target, int_info.bits), abi_align_bytes),
1380 .elem_ctype = limb_ctype,
1381 .nonstring = limb_ctype.isAnyChar(),
1382 });
1383 if (!kind.isParameter()) return array_ctype;
1384 var fields = [_]Info.Field{
1385 .{
1386 .name = .{ .index = .array },
1387 .ctype = array_ctype,
1388 .alignas = AlignAs.fromAbiAlignment(.fromByteUnits(abi_align_bytes)),
1389 },
1390 };
1391 return pool.fromFields(allocator, .@"struct", &fields, kind);
1392 },
1393 }
1394 }
1395
1396 pub fn fromType(
1397 pool: *Pool,
1398 allocator: std.mem.Allocator,
1399 scratch: *std.ArrayList(u32),
1400 ty: Type,
1401 pt: Zcu.PerThread,
1402 mod: *Module,
1403 kind: Kind,
1404 ) !CType {
1405 const ip = &pt.zcu.intern_pool;
1406 const zcu = pt.zcu;
1407 switch (ty.toIntern()) {
1408 .u0_type,
1409 .i0_type,
1410 .anyopaque_type,
1411 .void_type,
1412 .empty_tuple_type,
1413 .type_type,
1414 .comptime_int_type,
1415 .comptime_float_type,
1416 .null_type,
1417 .undefined_type,
1418 .enum_literal_type,
1419 .optional_type_type,
1420 .manyptr_const_type_type,
1421 .slice_const_type_type,
1422 => return .void,
1423 .u1_type, .u8_type => return .u8,
1424 .i8_type => return .i8,
1425 .u16_type => return .u16,
1426 .i16_type => return .i16,
1427 .u29_type, .u32_type => return .u32,
1428 .i32_type => return .i32,
1429 .u64_type => return .u64,
1430 .i64_type => return .i64,
1431 .u80_type, .u128_type => return .u128,
1432 .i128_type => return .i128,
1433 .u256_type => return pool.fromIntInfo(allocator, .{
1434 .signedness = .unsigned,
1435 .bits = 256,
1436 }, mod, kind),
1437 .usize_type => return .usize,
1438 .isize_type => return .isize,
1439 .c_char_type => return .{ .index = .char },
1440 .c_short_type => return .{ .index = .short },
1441 .c_ushort_type => return .{ .index = .@"unsigned short" },
1442 .c_int_type => return .{ .index = .int },
1443 .c_uint_type => return .{ .index = .@"unsigned int" },
1444 .c_long_type => return .{ .index = .long },
1445 .c_ulong_type => return .{ .index = .@"unsigned long" },
1446 .c_longlong_type => return .{ .index = .@"long long" },
1447 .c_ulonglong_type => return .{ .index = .@"unsigned long long" },
1448 .c_longdouble_type => return .{ .index = .@"long double" },
1449 .f16_type => return .f16,
1450 .f32_type => return .f32,
1451 .f64_type => return .f64,
1452 .f80_type => return .f80,
1453 .f128_type => return .f128,
1454 .bool_type, .optional_noreturn_type => return .bool,
1455 .noreturn_type,
1456 .anyframe_type,
1457 .generic_poison_type,
1458 => unreachable,
1459 .anyerror_type,
1460 .anyerror_void_error_union_type,
1461 .adhoc_inferred_error_set_type,
1462 => return pool.fromIntInfo(allocator, .{
1463 .signedness = .unsigned,
1464 .bits = pt.zcu.errorSetBits(),
1465 }, mod, kind),
1466
1467 .ptr_usize_type => return pool.getPointer(allocator, .{
1468 .elem_ctype = .usize,
1469 }),
1470 .ptr_const_comptime_int_type => return pool.getPointer(allocator, .{
1471 .elem_ctype = .void,
1472 .@"const" = true,
1473 }),
1474 .manyptr_u8_type => return pool.getPointer(allocator, .{
1475 .elem_ctype = .u8,
1476 .nonstring = true,
1477 }),
1478 .manyptr_const_u8_type => return pool.getPointer(allocator, .{
1479 .elem_ctype = .u8,
1480 .@"const" = true,
1481 .nonstring = true,
1482 }),
1483 .manyptr_const_u8_sentinel_0_type => return pool.getPointer(allocator, .{
1484 .elem_ctype = .u8,
1485 .@"const" = true,
1486 }),
1487 .slice_const_u8_type => {
1488 const target = &mod.resolved_target.result;
1489 var fields = [_]Info.Field{
1490 .{
1491 .name = .{ .index = .ptr },
1492 .ctype = try pool.getPointer(allocator, .{
1493 .elem_ctype = .u8,
1494 .@"const" = true,
1495 .nonstring = true,
1496 }),
1497 .alignas = AlignAs.fromAbiAlignment(Type.ptrAbiAlignment(target)),
1498 },
1499 .{
1500 .name = .{ .index = .len },
1501 .ctype = .usize,
1502 .alignas = AlignAs.fromAbiAlignment(
1503 .fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())),
1504 ),
1505 },
1506 };
1507 return pool.fromFields(allocator, .@"struct", &fields, kind);
1508 },
1509 .slice_const_u8_sentinel_0_type => {
1510 const target = &mod.resolved_target.result;
1511 var fields = [_]Info.Field{
1512 .{
1513 .name = .{ .index = .ptr },
1514 .ctype = try pool.getPointer(allocator, .{
1515 .elem_ctype = .u8,
1516 .@"const" = true,
1517 }),
1518 .alignas = AlignAs.fromAbiAlignment(Type.ptrAbiAlignment(target)),
1519 },
1520 .{
1521 .name = .{ .index = .len },
1522 .ctype = .usize,
1523 .alignas = AlignAs.fromAbiAlignment(
1524 .fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())),
1525 ),
1526 },
1527 };
1528 return pool.fromFields(allocator, .@"struct", &fields, kind);
1529 },
1530
1531 .manyptr_const_slice_const_u8_type => {
1532 const target = &mod.resolved_target.result;
1533 var fields: [2]Info.Field = .{
1534 .{
1535 .name = .{ .index = .ptr },
1536 .ctype = try pool.getPointer(allocator, .{
1537 .elem_ctype = .u8,
1538 .@"const" = true,
1539 .nonstring = true,
1540 }),
1541 .alignas = AlignAs.fromAbiAlignment(Type.ptrAbiAlignment(target)),
1542 },
1543 .{
1544 .name = .{ .index = .len },
1545 .ctype = .usize,
1546 .alignas = AlignAs.fromAbiAlignment(
1547 .fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())),
1548 ),
1549 },
1550 };
1551 const slice_const_u8 = try pool.fromFields(allocator, .@"struct", &fields, kind);
1552 return pool.getPointer(allocator, .{
1553 .elem_ctype = slice_const_u8,
1554 .@"const" = true,
1555 });
1556 },
1557 .slice_const_slice_const_u8_type => {
1558 const target = &mod.resolved_target.result;
1559 var fields: [2]Info.Field = .{
1560 .{
1561 .name = .{ .index = .ptr },
1562 .ctype = try pool.getPointer(allocator, .{
1563 .elem_ctype = .u8,
1564 .@"const" = true,
1565 .nonstring = true,
1566 }),
1567 .alignas = AlignAs.fromAbiAlignment(Type.ptrAbiAlignment(target)),
1568 },
1569 .{
1570 .name = .{ .index = .len },
1571 .ctype = .usize,
1572 .alignas = AlignAs.fromAbiAlignment(
1573 .fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())),
1574 ),
1575 },
1576 };
1577 const slice_const_u8 = try pool.fromFields(allocator, .@"struct", &fields, .forward);
1578 fields = .{
1579 .{
1580 .name = .{ .index = .ptr },
1581 .ctype = try pool.getPointer(allocator, .{
1582 .elem_ctype = slice_const_u8,
1583 .@"const" = true,
1584 }),
1585 .alignas = AlignAs.fromAbiAlignment(Type.ptrAbiAlignment(target)),
1586 },
1587 .{
1588 .name = .{ .index = .len },
1589 .ctype = .usize,
1590 .alignas = AlignAs.fromAbiAlignment(
1591 .fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())),
1592 ),
1593 },
1594 };
1595 return pool.fromFields(allocator, .@"struct", &fields, kind);
1596 },
1597
1598 .vector_8_i8_type => {
1599 const vector_ctype = try pool.getVector(allocator, .{
1600 .elem_ctype = .i8,
1601 .len = 8,
1602 .nonstring = true,
1603 });
1604 if (!kind.isParameter()) return vector_ctype;
1605 var fields = [_]Info.Field{
1606 .{
1607 .name = .{ .index = .array },
1608 .ctype = vector_ctype,
1609 .alignas = AlignAs.fromAbiAlignment(Type.i8.abiAlignment(zcu)),
1610 },
1611 };
1612 return pool.fromFields(allocator, .@"struct", &fields, kind);
1613 },
1614 .vector_16_i8_type => {
1615 const vector_ctype = try pool.getVector(allocator, .{
1616 .elem_ctype = .i8,
1617 .len = 16,
1618 .nonstring = true,
1619 });
1620 if (!kind.isParameter()) return vector_ctype;
1621 var fields = [_]Info.Field{
1622 .{
1623 .name = .{ .index = .array },
1624 .ctype = vector_ctype,
1625 .alignas = AlignAs.fromAbiAlignment(Type.i8.abiAlignment(zcu)),
1626 },
1627 };
1628 return pool.fromFields(allocator, .@"struct", &fields, kind);
1629 },
1630 .vector_32_i8_type => {
1631 const vector_ctype = try pool.getVector(allocator, .{
1632 .elem_ctype = .i8,
1633 .len = 32,
1634 .nonstring = true,
1635 });
1636 if (!kind.isParameter()) return vector_ctype;
1637 var fields = [_]Info.Field{
1638 .{
1639 .name = .{ .index = .array },
1640 .ctype = vector_ctype,
1641 .alignas = AlignAs.fromAbiAlignment(Type.i8.abiAlignment(zcu)),
1642 },
1643 };
1644 return pool.fromFields(allocator, .@"struct", &fields, kind);
1645 },
1646 .vector_64_i8_type => {
1647 const vector_ctype = try pool.getVector(allocator, .{
1648 .elem_ctype = .i8,
1649 .len = 64,
1650 .nonstring = true,
1651 });
1652 if (!kind.isParameter()) return vector_ctype;
1653 var fields = [_]Info.Field{
1654 .{
1655 .name = .{ .index = .array },
1656 .ctype = vector_ctype,
1657 .alignas = AlignAs.fromAbiAlignment(Type.i8.abiAlignment(zcu)),
1658 },
1659 };
1660 return pool.fromFields(allocator, .@"struct", &fields, kind);
1661 },
1662 .vector_1_u8_type => {
1663 const vector_ctype = try pool.getVector(allocator, .{
1664 .elem_ctype = .u8,
1665 .len = 1,
1666 .nonstring = true,
1667 });
1668 if (!kind.isParameter()) return vector_ctype;
1669 var fields = [_]Info.Field{
1670 .{
1671 .name = .{ .index = .array },
1672 .ctype = vector_ctype,
1673 .alignas = AlignAs.fromAbiAlignment(Type.u8.abiAlignment(zcu)),
1674 },
1675 };
1676 return pool.fromFields(allocator, .@"struct", &fields, kind);
1677 },
1678 .vector_2_u8_type => {
1679 const vector_ctype = try pool.getVector(allocator, .{
1680 .elem_ctype = .u8,
1681 .len = 2,
1682 .nonstring = true,
1683 });
1684 if (!kind.isParameter()) return vector_ctype;
1685 var fields = [_]Info.Field{
1686 .{
1687 .name = .{ .index = .array },
1688 .ctype = vector_ctype,
1689 .alignas = AlignAs.fromAbiAlignment(Type.u8.abiAlignment(zcu)),
1690 },
1691 };
1692 return pool.fromFields(allocator, .@"struct", &fields, kind);
1693 },
1694 .vector_4_u8_type => {
1695 const vector_ctype = try pool.getVector(allocator, .{
1696 .elem_ctype = .u8,
1697 .len = 4,
1698 .nonstring = true,
1699 });
1700 if (!kind.isParameter()) return vector_ctype;
1701 var fields = [_]Info.Field{
1702 .{
1703 .name = .{ .index = .array },
1704 .ctype = vector_ctype,
1705 .alignas = AlignAs.fromAbiAlignment(Type.u8.abiAlignment(zcu)),
1706 },
1707 };
1708 return pool.fromFields(allocator, .@"struct", &fields, kind);
1709 },
1710 .vector_8_u8_type => {
1711 const vector_ctype = try pool.getVector(allocator, .{
1712 .elem_ctype = .u8,
1713 .len = 8,
1714 .nonstring = true,
1715 });
1716 if (!kind.isParameter()) return vector_ctype;
1717 var fields = [_]Info.Field{
1718 .{
1719 .name = .{ .index = .array },
1720 .ctype = vector_ctype,
1721 .alignas = AlignAs.fromAbiAlignment(Type.u8.abiAlignment(zcu)),
1722 },
1723 };
1724 return pool.fromFields(allocator, .@"struct", &fields, kind);
1725 },
1726 .vector_16_u8_type => {
1727 const vector_ctype = try pool.getVector(allocator, .{
1728 .elem_ctype = .u8,
1729 .len = 16,
1730 .nonstring = true,
1731 });
1732 if (!kind.isParameter()) return vector_ctype;
1733 var fields = [_]Info.Field{
1734 .{
1735 .name = .{ .index = .array },
1736 .ctype = vector_ctype,
1737 .alignas = AlignAs.fromAbiAlignment(Type.u8.abiAlignment(zcu)),
1738 },
1739 };
1740 return pool.fromFields(allocator, .@"struct", &fields, kind);
1741 },
1742 .vector_32_u8_type => {
1743 const vector_ctype = try pool.getVector(allocator, .{
1744 .elem_ctype = .u8,
1745 .len = 32,
1746 .nonstring = true,
1747 });
1748 if (!kind.isParameter()) return vector_ctype;
1749 var fields = [_]Info.Field{
1750 .{
1751 .name = .{ .index = .array },
1752 .ctype = vector_ctype,
1753 .alignas = AlignAs.fromAbiAlignment(Type.u8.abiAlignment(zcu)),
1754 },
1755 };
1756 return pool.fromFields(allocator, .@"struct", &fields, kind);
1757 },
1758 .vector_64_u8_type => {
1759 const vector_ctype = try pool.getVector(allocator, .{
1760 .elem_ctype = .u8,
1761 .len = 64,
1762 .nonstring = true,
1763 });
1764 if (!kind.isParameter()) return vector_ctype;
1765 var fields = [_]Info.Field{
1766 .{
1767 .name = .{ .index = .array },
1768 .ctype = vector_ctype,
1769 .alignas = AlignAs.fromAbiAlignment(Type.u8.abiAlignment(zcu)),
1770 },
1771 };
1772 return pool.fromFields(allocator, .@"struct", &fields, kind);
1773 },
1774 .vector_2_i16_type => {
1775 const vector_ctype = try pool.getVector(allocator, .{
1776 .elem_ctype = .i16,
1777 .len = 2,
1778 });
1779 if (!kind.isParameter()) return vector_ctype;
1780 var fields = [_]Info.Field{
1781 .{
1782 .name = .{ .index = .array },
1783 .ctype = vector_ctype,
1784 .alignas = AlignAs.fromAbiAlignment(Type.i16.abiAlignment(zcu)),
1785 },
1786 };
1787 return pool.fromFields(allocator, .@"struct", &fields, kind);
1788 },
1789 .vector_4_i16_type => {
1790 const vector_ctype = try pool.getVector(allocator, .{
1791 .elem_ctype = .i16,
1792 .len = 4,
1793 });
1794 if (!kind.isParameter()) return vector_ctype;
1795 var fields = [_]Info.Field{
1796 .{
1797 .name = .{ .index = .array },
1798 .ctype = vector_ctype,
1799 .alignas = AlignAs.fromAbiAlignment(Type.i16.abiAlignment(zcu)),
1800 },
1801 };
1802 return pool.fromFields(allocator, .@"struct", &fields, kind);
1803 },
1804 .vector_8_i16_type => {
1805 const vector_ctype = try pool.getVector(allocator, .{
1806 .elem_ctype = .i16,
1807 .len = 8,
1808 });
1809 if (!kind.isParameter()) return vector_ctype;
1810 var fields = [_]Info.Field{
1811 .{
1812 .name = .{ .index = .array },
1813 .ctype = vector_ctype,
1814 .alignas = AlignAs.fromAbiAlignment(Type.i16.abiAlignment(zcu)),
1815 },
1816 };
1817 return pool.fromFields(allocator, .@"struct", &fields, kind);
1818 },
1819 .vector_16_i16_type => {
1820 const vector_ctype = try pool.getVector(allocator, .{
1821 .elem_ctype = .i16,
1822 .len = 16,
1823 });
1824 if (!kind.isParameter()) return vector_ctype;
1825 var fields = [_]Info.Field{
1826 .{
1827 .name = .{ .index = .array },
1828 .ctype = vector_ctype,
1829 .alignas = AlignAs.fromAbiAlignment(Type.i16.abiAlignment(zcu)),
1830 },
1831 };
1832 return pool.fromFields(allocator, .@"struct", &fields, kind);
1833 },
1834 .vector_32_i16_type => {
1835 const vector_ctype = try pool.getVector(allocator, .{
1836 .elem_ctype = .i16,
1837 .len = 32,
1838 });
1839 if (!kind.isParameter()) return vector_ctype;
1840 var fields = [_]Info.Field{
1841 .{
1842 .name = .{ .index = .array },
1843 .ctype = vector_ctype,
1844 .alignas = AlignAs.fromAbiAlignment(Type.i16.abiAlignment(zcu)),
1845 },
1846 };
1847 return pool.fromFields(allocator, .@"struct", &fields, kind);
1848 },
1849 .vector_4_u16_type => {
1850 const vector_ctype = try pool.getVector(allocator, .{
1851 .elem_ctype = .u16,
1852 .len = 4,
1853 });
1854 if (!kind.isParameter()) return vector_ctype;
1855 var fields = [_]Info.Field{
1856 .{
1857 .name = .{ .index = .array },
1858 .ctype = vector_ctype,
1859 .alignas = AlignAs.fromAbiAlignment(Type.u16.abiAlignment(zcu)),
1860 },
1861 };
1862 return pool.fromFields(allocator, .@"struct", &fields, kind);
1863 },
1864 .vector_8_u16_type => {
1865 const vector_ctype = try pool.getVector(allocator, .{
1866 .elem_ctype = .u16,
1867 .len = 8,
1868 });
1869 if (!kind.isParameter()) return vector_ctype;
1870 var fields = [_]Info.Field{
1871 .{
1872 .name = .{ .index = .array },
1873 .ctype = vector_ctype,
1874 .alignas = AlignAs.fromAbiAlignment(Type.u16.abiAlignment(zcu)),
1875 },
1876 };
1877 return pool.fromFields(allocator, .@"struct", &fields, kind);
1878 },
1879 .vector_16_u16_type => {
1880 const vector_ctype = try pool.getVector(allocator, .{
1881 .elem_ctype = .u16,
1882 .len = 16,
1883 });
1884 if (!kind.isParameter()) return vector_ctype;
1885 var fields = [_]Info.Field{
1886 .{
1887 .name = .{ .index = .array },
1888 .ctype = vector_ctype,
1889 .alignas = AlignAs.fromAbiAlignment(Type.u16.abiAlignment(zcu)),
1890 },
1891 };
1892 return pool.fromFields(allocator, .@"struct", &fields, kind);
1893 },
1894 .vector_32_u16_type => {
1895 const vector_ctype = try pool.getVector(allocator, .{
1896 .elem_ctype = .u16,
1897 .len = 32,
1898 });
1899 if (!kind.isParameter()) return vector_ctype;
1900 var fields = [_]Info.Field{
1901 .{
1902 .name = .{ .index = .array },
1903 .ctype = vector_ctype,
1904 .alignas = AlignAs.fromAbiAlignment(Type.u16.abiAlignment(zcu)),
1905 },
1906 };
1907 return pool.fromFields(allocator, .@"struct", &fields, kind);
1908 },
1909 .vector_2_i32_type => {
1910 const vector_ctype = try pool.getVector(allocator, .{
1911 .elem_ctype = .i32,
1912 .len = 2,
1913 });
1914 if (!kind.isParameter()) return vector_ctype;
1915 var fields = [_]Info.Field{
1916 .{
1917 .name = .{ .index = .array },
1918 .ctype = vector_ctype,
1919 .alignas = AlignAs.fromAbiAlignment(Type.i32.abiAlignment(zcu)),
1920 },
1921 };
1922 return pool.fromFields(allocator, .@"struct", &fields, kind);
1923 },
1924 .vector_4_i32_type => {
1925 const vector_ctype = try pool.getVector(allocator, .{
1926 .elem_ctype = .i32,
1927 .len = 4,
1928 });
1929 if (!kind.isParameter()) return vector_ctype;
1930 var fields = [_]Info.Field{
1931 .{
1932 .name = .{ .index = .array },
1933 .ctype = vector_ctype,
1934 .alignas = AlignAs.fromAbiAlignment(Type.i32.abiAlignment(zcu)),
1935 },
1936 };
1937 return pool.fromFields(allocator, .@"struct", &fields, kind);
1938 },
1939 .vector_8_i32_type => {
1940 const vector_ctype = try pool.getVector(allocator, .{
1941 .elem_ctype = .i32,
1942 .len = 8,
1943 });
1944 if (!kind.isParameter()) return vector_ctype;
1945 var fields = [_]Info.Field{
1946 .{
1947 .name = .{ .index = .array },
1948 .ctype = vector_ctype,
1949 .alignas = AlignAs.fromAbiAlignment(Type.i32.abiAlignment(zcu)),
1950 },
1951 };
1952 return pool.fromFields(allocator, .@"struct", &fields, kind);
1953 },
1954 .vector_16_i32_type => {
1955 const vector_ctype = try pool.getVector(allocator, .{
1956 .elem_ctype = .i32,
1957 .len = 16,
1958 });
1959 if (!kind.isParameter()) return vector_ctype;
1960 var fields = [_]Info.Field{
1961 .{
1962 .name = .{ .index = .array },
1963 .ctype = vector_ctype,
1964 .alignas = AlignAs.fromAbiAlignment(Type.i32.abiAlignment(zcu)),
1965 },
1966 };
1967 return pool.fromFields(allocator, .@"struct", &fields, kind);
1968 },
1969 .vector_4_u32_type => {
1970 const vector_ctype = try pool.getVector(allocator, .{
1971 .elem_ctype = .u32,
1972 .len = 4,
1973 });
1974 if (!kind.isParameter()) return vector_ctype;
1975 var fields = [_]Info.Field{
1976 .{
1977 .name = .{ .index = .array },
1978 .ctype = vector_ctype,
1979 .alignas = AlignAs.fromAbiAlignment(Type.u32.abiAlignment(zcu)),
1980 },
1981 };
1982 return pool.fromFields(allocator, .@"struct", &fields, kind);
1983 },
1984 .vector_8_u32_type => {
1985 const vector_ctype = try pool.getVector(allocator, .{
1986 .elem_ctype = .u32,
1987 .len = 8,
1988 });
1989 if (!kind.isParameter()) return vector_ctype;
1990 var fields = [_]Info.Field{
1991 .{
1992 .name = .{ .index = .array },
1993 .ctype = vector_ctype,
1994 .alignas = AlignAs.fromAbiAlignment(Type.u32.abiAlignment(zcu)),
1995 },
1996 };
1997 return pool.fromFields(allocator, .@"struct", &fields, kind);
1998 },
1999 .vector_16_u32_type => {
2000 const vector_ctype = try pool.getVector(allocator, .{
2001 .elem_ctype = .u32,
2002 .len = 16,
2003 });
2004 if (!kind.isParameter()) return vector_ctype;
2005 var fields = [_]Info.Field{
2006 .{
2007 .name = .{ .index = .array },
2008 .ctype = vector_ctype,
2009 .alignas = AlignAs.fromAbiAlignment(Type.u32.abiAlignment(zcu)),
2010 },
2011 };
2012 return pool.fromFields(allocator, .@"struct", &fields, kind);
2013 },
2014 .vector_2_i64_type => {
2015 const vector_ctype = try pool.getVector(allocator, .{
2016 .elem_ctype = .i64,
2017 .len = 2,
2018 });
2019 if (!kind.isParameter()) return vector_ctype;
2020 var fields = [_]Info.Field{
2021 .{
2022 .name = .{ .index = .array },
2023 .ctype = vector_ctype,
2024 .alignas = AlignAs.fromAbiAlignment(Type.i64.abiAlignment(zcu)),
2025 },
2026 };
2027 return pool.fromFields(allocator, .@"struct", &fields, kind);
2028 },
2029 .vector_4_i64_type => {
2030 const vector_ctype = try pool.getVector(allocator, .{
2031 .elem_ctype = .i64,
2032 .len = 4,
2033 });
2034 if (!kind.isParameter()) return vector_ctype;
2035 var fields = [_]Info.Field{
2036 .{
2037 .name = .{ .index = .array },
2038 .ctype = vector_ctype,
2039 .alignas = AlignAs.fromAbiAlignment(Type.i64.abiAlignment(zcu)),
2040 },
2041 };
2042 return pool.fromFields(allocator, .@"struct", &fields, kind);
2043 },
2044 .vector_8_i64_type => {
2045 const vector_ctype = try pool.getVector(allocator, .{
2046 .elem_ctype = .i64,
2047 .len = 8,
2048 });
2049 if (!kind.isParameter()) return vector_ctype;
2050 var fields = [_]Info.Field{
2051 .{
2052 .name = .{ .index = .array },
2053 .ctype = vector_ctype,
2054 .alignas = AlignAs.fromAbiAlignment(Type.i64.abiAlignment(zcu)),
2055 },
2056 };
2057 return pool.fromFields(allocator, .@"struct", &fields, kind);
2058 },
2059 .vector_2_u64_type => {
2060 const vector_ctype = try pool.getVector(allocator, .{
2061 .elem_ctype = .u64,
2062 .len = 2,
2063 });
2064 if (!kind.isParameter()) return vector_ctype;
2065 var fields = [_]Info.Field{
2066 .{
2067 .name = .{ .index = .array },
2068 .ctype = vector_ctype,
2069 .alignas = AlignAs.fromAbiAlignment(Type.u64.abiAlignment(zcu)),
2070 },
2071 };
2072 return pool.fromFields(allocator, .@"struct", &fields, kind);
2073 },
2074 .vector_4_u64_type => {
2075 const vector_ctype = try pool.getVector(allocator, .{
2076 .elem_ctype = .u64,
2077 .len = 4,
2078 });
2079 if (!kind.isParameter()) return vector_ctype;
2080 var fields = [_]Info.Field{
2081 .{
2082 .name = .{ .index = .array },
2083 .ctype = vector_ctype,
2084 .alignas = AlignAs.fromAbiAlignment(Type.u64.abiAlignment(zcu)),
2085 },
2086 };
2087 return pool.fromFields(allocator, .@"struct", &fields, kind);
2088 },
2089 .vector_8_u64_type => {
2090 const vector_ctype = try pool.getVector(allocator, .{
2091 .elem_ctype = .u64,
2092 .len = 8,
2093 });
2094 if (!kind.isParameter()) return vector_ctype;
2095 var fields = [_]Info.Field{
2096 .{
2097 .name = .{ .index = .array },
2098 .ctype = vector_ctype,
2099 .alignas = AlignAs.fromAbiAlignment(Type.u64.abiAlignment(zcu)),
2100 },
2101 };
2102 return pool.fromFields(allocator, .@"struct", &fields, kind);
2103 },
2104 .vector_1_u128_type => {
2105 const vector_ctype = try pool.getVector(allocator, .{
2106 .elem_ctype = .u128,
2107 .len = 1,
2108 });
2109 if (!kind.isParameter()) return vector_ctype;
2110 var fields = [_]Info.Field{
2111 .{
2112 .name = .{ .index = .array },
2113 .ctype = vector_ctype,
2114 .alignas = AlignAs.fromAbiAlignment(Type.u128.abiAlignment(zcu)),
2115 },
2116 };
2117 return pool.fromFields(allocator, .@"struct", &fields, kind);
2118 },
2119 .vector_2_u128_type => {
2120 const vector_ctype = try pool.getVector(allocator, .{
2121 .elem_ctype = .u128,
2122 .len = 2,
2123 });
2124 if (!kind.isParameter()) return vector_ctype;
2125 var fields = [_]Info.Field{
2126 .{
2127 .name = .{ .index = .array },
2128 .ctype = vector_ctype,
2129 .alignas = AlignAs.fromAbiAlignment(Type.u128.abiAlignment(zcu)),
2130 },
2131 };
2132 return pool.fromFields(allocator, .@"struct", &fields, kind);
2133 },
2134 .vector_1_u256_type => {
2135 const vector_ctype = try pool.getVector(allocator, .{
2136 .elem_ctype = try pool.fromIntInfo(allocator, .{
2137 .signedness = .unsigned,
2138 .bits = 256,
2139 }, mod, kind),
2140 .len = 1,
2141 });
2142 if (!kind.isParameter()) return vector_ctype;
2143 var fields = [_]Info.Field{
2144 .{
2145 .name = .{ .index = .array },
2146 .ctype = vector_ctype,
2147 .alignas = AlignAs.fromAbiAlignment(Type.u256.abiAlignment(zcu)),
2148 },
2149 };
2150 return pool.fromFields(allocator, .@"struct", &fields, kind);
2151 },
2152 .vector_4_f16_type => {
2153 const vector_ctype = try pool.getVector(allocator, .{
2154 .elem_ctype = .f16,
2155 .len = 4,
2156 });
2157 if (!kind.isParameter()) return vector_ctype;
2158 var fields = [_]Info.Field{
2159 .{
2160 .name = .{ .index = .array },
2161 .ctype = vector_ctype,
2162 .alignas = AlignAs.fromAbiAlignment(Type.f16.abiAlignment(zcu)),
2163 },
2164 };
2165 return pool.fromFields(allocator, .@"struct", &fields, kind);
2166 },
2167 .vector_8_f16_type => {
2168 const vector_ctype = try pool.getVector(allocator, .{
2169 .elem_ctype = .f16,
2170 .len = 8,
2171 });
2172 if (!kind.isParameter()) return vector_ctype;
2173 var fields = [_]Info.Field{
2174 .{
2175 .name = .{ .index = .array },
2176 .ctype = vector_ctype,
2177 .alignas = AlignAs.fromAbiAlignment(Type.f16.abiAlignment(zcu)),
2178 },
2179 };
2180 return pool.fromFields(allocator, .@"struct", &fields, kind);
2181 },
2182 .vector_16_f16_type => {
2183 const vector_ctype = try pool.getVector(allocator, .{
2184 .elem_ctype = .f16,
2185 .len = 16,
2186 });
2187 if (!kind.isParameter()) return vector_ctype;
2188 var fields = [_]Info.Field{
2189 .{
2190 .name = .{ .index = .array },
2191 .ctype = vector_ctype,
2192 .alignas = AlignAs.fromAbiAlignment(Type.f16.abiAlignment(zcu)),
2193 },
2194 };
2195 return pool.fromFields(allocator, .@"struct", &fields, kind);
2196 },
2197 .vector_32_f16_type => {
2198 const vector_ctype = try pool.getVector(allocator, .{
2199 .elem_ctype = .f16,
2200 .len = 32,
2201 });
2202 if (!kind.isParameter()) return vector_ctype;
2203 var fields = [_]Info.Field{
2204 .{
2205 .name = .{ .index = .array },
2206 .ctype = vector_ctype,
2207 .alignas = AlignAs.fromAbiAlignment(Type.f16.abiAlignment(zcu)),
2208 },
2209 };
2210 return pool.fromFields(allocator, .@"struct", &fields, kind);
2211 },
2212 .vector_2_f32_type => {
2213 const vector_ctype = try pool.getVector(allocator, .{
2214 .elem_ctype = .f32,
2215 .len = 2,
2216 });
2217 if (!kind.isParameter()) return vector_ctype;
2218 var fields = [_]Info.Field{
2219 .{
2220 .name = .{ .index = .array },
2221 .ctype = vector_ctype,
2222 .alignas = AlignAs.fromAbiAlignment(Type.f32.abiAlignment(zcu)),
2223 },
2224 };
2225 return pool.fromFields(allocator, .@"struct", &fields, kind);
2226 },
2227 .vector_4_f32_type => {
2228 const vector_ctype = try pool.getVector(allocator, .{
2229 .elem_ctype = .f32,
2230 .len = 4,
2231 });
2232 if (!kind.isParameter()) return vector_ctype;
2233 var fields = [_]Info.Field{
2234 .{
2235 .name = .{ .index = .array },
2236 .ctype = vector_ctype,
2237 .alignas = AlignAs.fromAbiAlignment(Type.f32.abiAlignment(zcu)),
2238 },
2239 };
2240 return pool.fromFields(allocator, .@"struct", &fields, kind);
2241 },
2242 .vector_8_f32_type => {
2243 const vector_ctype = try pool.getVector(allocator, .{
2244 .elem_ctype = .f32,
2245 .len = 8,
2246 });
2247 if (!kind.isParameter()) return vector_ctype;
2248 var fields = [_]Info.Field{
2249 .{
2250 .name = .{ .index = .array },
2251 .ctype = vector_ctype,
2252 .alignas = AlignAs.fromAbiAlignment(Type.f32.abiAlignment(zcu)),
2253 },
2254 };
2255 return pool.fromFields(allocator, .@"struct", &fields, kind);
2256 },
2257 .vector_16_f32_type => {
2258 const vector_ctype = try pool.getVector(allocator, .{
2259 .elem_ctype = .f32,
2260 .len = 16,
2261 });
2262 if (!kind.isParameter()) return vector_ctype;
2263 var fields = [_]Info.Field{
2264 .{
2265 .name = .{ .index = .array },
2266 .ctype = vector_ctype,
2267 .alignas = AlignAs.fromAbiAlignment(Type.f32.abiAlignment(zcu)),
2268 },
2269 };
2270 return pool.fromFields(allocator, .@"struct", &fields, kind);
2271 },
2272 .vector_2_f64_type => {
2273 const vector_ctype = try pool.getVector(allocator, .{
2274 .elem_ctype = .f64,
2275 .len = 2,
2276 });
2277 if (!kind.isParameter()) return vector_ctype;
2278 var fields = [_]Info.Field{
2279 .{
2280 .name = .{ .index = .array },
2281 .ctype = vector_ctype,
2282 .alignas = AlignAs.fromAbiAlignment(Type.f64.abiAlignment(zcu)),
2283 },
2284 };
2285 return pool.fromFields(allocator, .@"struct", &fields, kind);
2286 },
2287 .vector_4_f64_type => {
2288 const vector_ctype = try pool.getVector(allocator, .{
2289 .elem_ctype = .f64,
2290 .len = 4,
2291 });
2292 if (!kind.isParameter()) return vector_ctype;
2293 var fields = [_]Info.Field{
2294 .{
2295 .name = .{ .index = .array },
2296 .ctype = vector_ctype,
2297 .alignas = AlignAs.fromAbiAlignment(Type.f64.abiAlignment(zcu)),
2298 },
2299 };
2300 return pool.fromFields(allocator, .@"struct", &fields, kind);
2301 },
2302 .vector_8_f64_type => {
2303 const vector_ctype = try pool.getVector(allocator, .{
2304 .elem_ctype = .f64,
2305 .len = 8,
2306 });
2307 if (!kind.isParameter()) return vector_ctype;
2308 var fields = [_]Info.Field{
2309 .{
2310 .name = .{ .index = .array },
2311 .ctype = vector_ctype,
2312 .alignas = AlignAs.fromAbiAlignment(Type.f64.abiAlignment(zcu)),
2313 },
2314 };
2315 return pool.fromFields(allocator, .@"struct", &fields, kind);
2316 },
2317
2318 .undef,
2319 .undef_bool,
2320 .undef_usize,
2321 .undef_u1,
2322 .zero,
2323 .zero_usize,
2324 .zero_u1,
2325 .zero_u8,
2326 .one,
2327 .one_usize,
2328 .one_u1,
2329 .one_u8,
2330 .four_u8,
2331 .negative_one,
2332 .void_value,
2333 .unreachable_value,
2334 .null_value,
2335 .bool_true,
2336 .bool_false,
2337 .empty_tuple,
2338 .none,
2339 => unreachable, // values, not types
2340
2341 _ => |ip_index| switch (ip.indexToKey(ip_index)) {
2342 .int_type => |int_info| return pool.fromIntInfo(allocator, int_info, mod, kind),
2343 .ptr_type => |ptr_info| switch (ptr_info.flags.size) {
2344 .one, .many, .c => {
2345 const elem_ctype = elem_ctype: {
2346 if (ptr_info.packed_offset.host_size > 0 and
2347 ptr_info.flags.vector_index == .none)
2348 break :elem_ctype try pool.fromIntInfo(allocator, .{
2349 .signedness = .unsigned,
2350 .bits = ptr_info.packed_offset.host_size * 8,
2351 }, mod, .forward);
2352 const elem: Info.Aligned = .{
2353 .ctype = try pool.fromType(
2354 allocator,
2355 scratch,
2356 Type.fromInterned(ptr_info.child),
2357 pt,
2358 mod,
2359 .forward,
2360 ),
2361 .alignas = AlignAs.fromAlignment(.{
2362 .@"align" = ptr_info.flags.alignment,
2363 .abi = Type.fromInterned(ptr_info.child).abiAlignment(zcu),
2364 }),
2365 };
2366 break :elem_ctype if (elem.alignas.abiOrder().compare(.gte))
2367 elem.ctype
2368 else
2369 try pool.getAligned(allocator, elem);
2370 };
2371 const elem_tag: Info.Tag = switch (elem_ctype.info(pool)) {
2372 .aligned => |aligned_info| aligned_info.ctype.info(pool),
2373 else => |elem_tag| elem_tag,
2374 };
2375 return pool.getPointer(allocator, .{
2376 .elem_ctype = elem_ctype,
2377 .@"const" = switch (elem_tag) {
2378 .basic,
2379 .pointer,
2380 .aligned,
2381 .array,
2382 .vector,
2383 .fwd_decl,
2384 .aggregate,
2385 => ptr_info.flags.is_const,
2386 .function => false,
2387 },
2388 .@"volatile" = ptr_info.flags.is_volatile,
2389 .nonstring = elem_ctype.isAnyChar() and switch (ptr_info.sentinel) {
2390 .none => true,
2391 .zero_u8 => false,
2392 else => |sentinel| !Value.fromInterned(sentinel).compareAllWithZero(.eq, zcu),
2393 },
2394 });
2395 },
2396 .slice => {
2397 const target = &mod.resolved_target.result;
2398 var fields = [_]Info.Field{
2399 .{
2400 .name = .{ .index = .ptr },
2401 .ctype = try pool.fromType(
2402 allocator,
2403 scratch,
2404 Type.fromInterned(ip.slicePtrType(ip_index)),
2405 pt,
2406 mod,
2407 kind,
2408 ),
2409 .alignas = AlignAs.fromAbiAlignment(Type.ptrAbiAlignment(target)),
2410 },
2411 .{
2412 .name = .{ .index = .len },
2413 .ctype = .usize,
2414 .alignas = AlignAs.fromAbiAlignment(
2415 .fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())),
2416 ),
2417 },
2418 };
2419 return pool.fromFields(allocator, .@"struct", &fields, kind);
2420 },
2421 },
2422 .array_type => |array_info| {
2423 const len = array_info.lenIncludingSentinel();
2424 if (len == 0) return .void;
2425 const elem_type = Type.fromInterned(array_info.child);
2426 const elem_ctype = try pool.fromType(
2427 allocator,
2428 scratch,
2429 elem_type,
2430 pt,
2431 mod,
2432 kind.noParameter().asComplete(),
2433 );
2434 if (elem_ctype.index == .void) return .void;
2435 const array_ctype = try pool.getArray(allocator, .{
2436 .elem_ctype = elem_ctype,
2437 .len = len,
2438 .nonstring = elem_ctype.isAnyChar() and switch (array_info.sentinel) {
2439 .none => true,
2440 .zero_u8 => false,
2441 else => |sentinel| !Value.fromInterned(sentinel).compareAllWithZero(.eq, zcu),
2442 },
2443 });
2444 if (!kind.isParameter()) return array_ctype;
2445 var fields = [_]Info.Field{
2446 .{
2447 .name = .{ .index = .array },
2448 .ctype = array_ctype,
2449 .alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(zcu)),
2450 },
2451 };
2452 return pool.fromFields(allocator, .@"struct", &fields, kind);
2453 },
2454 .vector_type => |vector_info| {
2455 if (vector_info.len == 0) return .void;
2456 const elem_type = Type.fromInterned(vector_info.child);
2457 const elem_ctype = try pool.fromType(
2458 allocator,
2459 scratch,
2460 elem_type,
2461 pt,
2462 mod,
2463 kind.noParameter().asComplete(),
2464 );
2465 if (elem_ctype.index == .void) return .void;
2466 const vector_ctype = try pool.getVector(allocator, .{
2467 .elem_ctype = elem_ctype,
2468 .len = vector_info.len,
2469 .nonstring = elem_ctype.isAnyChar(),
2470 });
2471 if (!kind.isParameter()) return vector_ctype;
2472 var fields = [_]Info.Field{
2473 .{
2474 .name = .{ .index = .array },
2475 .ctype = vector_ctype,
2476 .alignas = AlignAs.fromAbiAlignment(elem_type.abiAlignment(zcu)),
2477 },
2478 };
2479 return pool.fromFields(allocator, .@"struct", &fields, kind);
2480 },
2481 .opt_type => |payload_type| {
2482 if (ip.isNoReturn(payload_type)) return .void;
2483 const payload_ctype = try pool.fromType(
2484 allocator,
2485 scratch,
2486 Type.fromInterned(payload_type),
2487 pt,
2488 mod,
2489 kind.noParameter(),
2490 );
2491 if (payload_ctype.index == .void) return .bool;
2492 switch (payload_type) {
2493 .anyerror_type => return payload_ctype,
2494 else => switch (ip.indexToKey(payload_type)) {
2495 .ptr_type => |payload_ptr_info| if (payload_ptr_info.flags.size != .c and
2496 !payload_ptr_info.flags.is_allowzero) return payload_ctype,
2497 .error_set_type, .inferred_error_set_type => return payload_ctype,
2498 else => {},
2499 },
2500 }
2501 var fields = [_]Info.Field{
2502 .{
2503 .name = .{ .index = .is_null },
2504 .ctype = .bool,
2505 .alignas = AlignAs.fromAbiAlignment(.@"1"),
2506 },
2507 .{
2508 .name = .{ .index = .payload },
2509 .ctype = payload_ctype,
2510 .alignas = AlignAs.fromAbiAlignment(
2511 Type.fromInterned(payload_type).abiAlignment(zcu),
2512 ),
2513 },
2514 };
2515 return pool.fromFields(allocator, .@"struct", &fields, kind);
2516 },
2517 .anyframe_type => unreachable,
2518 .error_union_type => |error_union_info| {
2519 const error_set_bits = pt.zcu.errorSetBits();
2520 const error_set_ctype = try pool.fromIntInfo(allocator, .{
2521 .signedness = .unsigned,
2522 .bits = error_set_bits,
2523 }, mod, kind);
2524 if (ip.isNoReturn(error_union_info.payload_type)) return error_set_ctype;
2525 const payload_type = Type.fromInterned(error_union_info.payload_type);
2526 const payload_ctype = try pool.fromType(
2527 allocator,
2528 scratch,
2529 payload_type,
2530 pt,
2531 mod,
2532 kind.noParameter(),
2533 );
2534 if (payload_ctype.index == .void) return error_set_ctype;
2535 const target = &mod.resolved_target.result;
2536 var fields = [_]Info.Field{
2537 .{
2538 .name = .{ .index = .@"error" },
2539 .ctype = error_set_ctype,
2540 .alignas = AlignAs.fromAbiAlignment(
2541 .fromByteUnits(std.zig.target.intAlignment(target, error_set_bits)),
2542 ),
2543 },
2544 .{
2545 .name = .{ .index = .payload },
2546 .ctype = payload_ctype,
2547 .alignas = AlignAs.fromAbiAlignment(payload_type.abiAlignment(zcu)),
2548 },
2549 };
2550 return pool.fromFields(allocator, .@"struct", &fields, kind);
2551 },
2552 .simple_type => unreachable,
2553 .struct_type => {
2554 const loaded_struct = ip.loadStructType(ip_index);
2555 switch (loaded_struct.layout) {
2556 .auto, .@"extern" => {
2557 const fwd_decl = try pool.getFwdDecl(allocator, .{
2558 .tag = .@"struct",
2559 .name = .{ .index = ip_index },
2560 });
2561 if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(zcu))
2562 fwd_decl
2563 else
2564 .void;
2565 const scratch_top = scratch.items.len;
2566 defer scratch.shrinkRetainingCapacity(scratch_top);
2567 try scratch.ensureUnusedCapacity(
2568 allocator,
2569 loaded_struct.field_types.len * @typeInfo(Field).@"struct".fields.len,
2570 );
2571 var hasher = Hasher.init;
2572 var tag: Pool.Tag = .aggregate_struct;
2573 var field_it = loaded_struct.iterateRuntimeOrder(ip);
2574 while (field_it.next()) |field_index| {
2575 const field_type = Type.fromInterned(
2576 loaded_struct.field_types.get(ip)[field_index],
2577 );
2578 const field_ctype = try pool.fromType(
2579 allocator,
2580 scratch,
2581 field_type,
2582 pt,
2583 mod,
2584 kind.noParameter(),
2585 );
2586 if (field_ctype.index == .void) continue;
2587 const field_name = try pool.string(allocator, loaded_struct.fieldName(ip, field_index).toSlice(ip));
2588 const field_alignas = AlignAs.fromAlignment(.{
2589 .@"align" = loaded_struct.fieldAlign(ip, field_index),
2590 .abi = field_type.abiAlignment(zcu),
2591 });
2592 pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{
2593 .name = field_name.index,
2594 .ctype = field_ctype.index,
2595 .flags = .{ .alignas = field_alignas },
2596 });
2597 if (field_alignas.abiOrder().compare(.lt))
2598 tag = .aggregate_struct_packed;
2599 }
2600 const fields_len: u32 = @intCast(@divExact(
2601 scratch.items.len - scratch_top,
2602 @typeInfo(Field).@"struct".fields.len,
2603 ));
2604 if (fields_len == 0) return .void;
2605 try pool.ensureUnusedCapacity(allocator, 1);
2606 const extra_index = try pool.addHashedExtra(allocator, &hasher, Aggregate, .{
2607 .fwd_decl = fwd_decl.index,
2608 .fields_len = fields_len,
2609 }, fields_len * @typeInfo(Field).@"struct".fields.len);
2610 pool.extra.appendSliceAssumeCapacity(scratch.items[scratch_top..]);
2611 return pool.tagTrailingExtraAssumeCapacity(hasher, tag, extra_index);
2612 },
2613 .@"packed" => return pool.fromType(
2614 allocator,
2615 scratch,
2616 Type.fromInterned(loaded_struct.backingIntTypeUnordered(ip)),
2617 pt,
2618 mod,
2619 kind,
2620 ),
2621 }
2622 },
2623 .tuple_type => |tuple_info| {
2624 const scratch_top = scratch.items.len;
2625 defer scratch.shrinkRetainingCapacity(scratch_top);
2626 try scratch.ensureUnusedCapacity(allocator, tuple_info.types.len *
2627 @typeInfo(Field).@"struct".fields.len);
2628 var hasher = Hasher.init;
2629 for (0..tuple_info.types.len) |field_index| {
2630 if (tuple_info.values.get(ip)[field_index] != .none) continue;
2631 const field_type = Type.fromInterned(
2632 tuple_info.types.get(ip)[field_index],
2633 );
2634 const field_ctype = try pool.fromType(
2635 allocator,
2636 scratch,
2637 field_type,
2638 pt,
2639 mod,
2640 kind.noParameter(),
2641 );
2642 if (field_ctype.index == .void) continue;
2643 const field_name = try pool.fmt(allocator, "f{d}", .{field_index});
2644 pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{
2645 .name = field_name.index,
2646 .ctype = field_ctype.index,
2647 .flags = .{ .alignas = AlignAs.fromAbiAlignment(
2648 field_type.abiAlignment(zcu),
2649 ) },
2650 });
2651 }
2652 const fields_len: u32 = @intCast(@divExact(
2653 scratch.items.len - scratch_top,
2654 @typeInfo(Field).@"struct".fields.len,
2655 ));
2656 if (fields_len == 0) return .void;
2657 if (kind.isForward()) {
2658 try pool.ensureUnusedCapacity(allocator, 1);
2659 const extra_index = try pool.addHashedExtra(
2660 allocator,
2661 &hasher,
2662 FwdDeclAnon,
2663 .{ .fields_len = fields_len },
2664 fields_len * @typeInfo(Field).@"struct".fields.len,
2665 );
2666 pool.extra.appendSliceAssumeCapacity(scratch.items[scratch_top..]);
2667 return pool.tagTrailingExtra(
2668 allocator,
2669 hasher,
2670 .fwd_decl_struct_anon,
2671 extra_index,
2672 );
2673 }
2674 const fwd_decl = try pool.fromType(allocator, scratch, ty, pt, mod, .forward);
2675 try pool.ensureUnusedCapacity(allocator, 1);
2676 const extra_index = try pool.addHashedExtra(allocator, &hasher, Aggregate, .{
2677 .fwd_decl = fwd_decl.index,
2678 .fields_len = fields_len,
2679 }, fields_len * @typeInfo(Field).@"struct".fields.len);
2680 pool.extra.appendSliceAssumeCapacity(scratch.items[scratch_top..]);
2681 return pool.tagTrailingExtraAssumeCapacity(hasher, .aggregate_struct, extra_index);
2682 },
2683 .union_type => {
2684 const loaded_union = ip.loadUnionType(ip_index);
2685 switch (loaded_union.flagsUnordered(ip).layout) {
2686 .auto, .@"extern" => {
2687 const has_tag = loaded_union.hasTag(ip);
2688 const fwd_decl = try pool.getFwdDecl(allocator, .{
2689 .tag = if (has_tag) .@"struct" else .@"union",
2690 .name = .{ .index = ip_index },
2691 });
2692 if (kind.isForward()) return if (ty.hasRuntimeBitsIgnoreComptime(zcu))
2693 fwd_decl
2694 else
2695 .void;
2696 const loaded_tag = loaded_union.loadTagType(ip);
2697 const scratch_top = scratch.items.len;
2698 defer scratch.shrinkRetainingCapacity(scratch_top);
2699 try scratch.ensureUnusedCapacity(
2700 allocator,
2701 loaded_union.field_types.len * @typeInfo(Field).@"struct".fields.len,
2702 );
2703 var hasher = Hasher.init;
2704 var tag: Pool.Tag = .aggregate_union;
2705 var payload_align: InternPool.Alignment = .@"1";
2706 for (0..loaded_union.field_types.len) |field_index| {
2707 const field_type = Type.fromInterned(
2708 loaded_union.field_types.get(ip)[field_index],
2709 );
2710 if (ip.isNoReturn(field_type.toIntern())) continue;
2711 const field_ctype = try pool.fromType(
2712 allocator,
2713 scratch,
2714 field_type,
2715 pt,
2716 mod,
2717 kind.noParameter(),
2718 );
2719 if (field_ctype.index == .void) continue;
2720 const field_name = try pool.string(
2721 allocator,
2722 loaded_tag.names.get(ip)[field_index].toSlice(ip),
2723 );
2724 const field_alignas = AlignAs.fromAlignment(.{
2725 .@"align" = loaded_union.fieldAlign(ip, field_index),
2726 .abi = field_type.abiAlignment(zcu),
2727 });
2728 pool.addHashedExtraAssumeCapacityTo(scratch, &hasher, Field, .{
2729 .name = field_name.index,
2730 .ctype = field_ctype.index,
2731 .flags = .{ .alignas = field_alignas },
2732 });
2733 if (field_alignas.abiOrder().compare(.lt))
2734 tag = .aggregate_union_packed;
2735 payload_align = payload_align.maxStrict(field_alignas.@"align");
2736 }
2737 const fields_len: u32 = @intCast(@divExact(
2738 scratch.items.len - scratch_top,
2739 @typeInfo(Field).@"struct".fields.len,
2740 ));
2741 if (!has_tag) {
2742 if (fields_len == 0) return .void;
2743 try pool.ensureUnusedCapacity(allocator, 1);
2744 const extra_index = try pool.addHashedExtra(
2745 allocator,
2746 &hasher,
2747 Aggregate,
2748 .{ .fwd_decl = fwd_decl.index, .fields_len = fields_len },
2749 fields_len * @typeInfo(Field).@"struct".fields.len,
2750 );
2751 pool.extra.appendSliceAssumeCapacity(scratch.items[scratch_top..]);
2752 return pool.tagTrailingExtraAssumeCapacity(hasher, tag, extra_index);
2753 }
2754 try pool.ensureUnusedCapacity(allocator, 2);
2755 var struct_fields: [2]Info.Field = undefined;
2756 var struct_fields_len: usize = 0;
2757 if (loaded_tag.tag_ty != .comptime_int_type) {
2758 const tag_type = Type.fromInterned(loaded_tag.tag_ty);
2759 const tag_ctype: CType = try pool.fromType(
2760 allocator,
2761 scratch,
2762 tag_type,
2763 pt,
2764 mod,
2765 kind.noParameter(),
2766 );
2767 if (tag_ctype.index != .void) {
2768 struct_fields[struct_fields_len] = .{
2769 .name = .{ .index = .tag },
2770 .ctype = tag_ctype,
2771 .alignas = AlignAs.fromAbiAlignment(tag_type.abiAlignment(zcu)),
2772 };
2773 struct_fields_len += 1;
2774 }
2775 }
2776 if (fields_len > 0) {
2777 const payload_ctype = payload_ctype: {
2778 const extra_index = try pool.addHashedExtra(
2779 allocator,
2780 &hasher,
2781 AggregateAnon,
2782 .{
2783 .index = ip_index,
2784 .id = 0,
2785 .fields_len = fields_len,
2786 },
2787 fields_len * @typeInfo(Field).@"struct".fields.len,
2788 );
2789 pool.extra.appendSliceAssumeCapacity(scratch.items[scratch_top..]);
2790 break :payload_ctype pool.tagTrailingExtraAssumeCapacity(
2791 hasher,
2792 switch (tag) {
2793 .aggregate_union => .aggregate_union_anon,
2794 .aggregate_union_packed => .aggregate_union_packed_anon,
2795 else => unreachable,
2796 },
2797 extra_index,
2798 );
2799 };
2800 if (payload_ctype.index != .void) {
2801 struct_fields[struct_fields_len] = .{
2802 .name = .{ .index = .payload },
2803 .ctype = payload_ctype,
2804 .alignas = AlignAs.fromAbiAlignment(payload_align),
2805 };
2806 struct_fields_len += 1;
2807 }
2808 }
2809 if (struct_fields_len == 0) return .void;
2810 sortFields(struct_fields[0..struct_fields_len]);
2811 return pool.getAggregate(allocator, .{
2812 .tag = .@"struct",
2813 .name = .{ .fwd_decl = fwd_decl },
2814 .fields = struct_fields[0..struct_fields_len],
2815 });
2816 },
2817 .@"packed" => return pool.fromIntInfo(allocator, .{
2818 .signedness = .unsigned,
2819 .bits = @intCast(ty.bitSize(zcu)),
2820 }, mod, kind),
2821 }
2822 },
2823 .opaque_type => return .void,
2824 .enum_type => return pool.fromType(
2825 allocator,
2826 scratch,
2827 Type.fromInterned(ip.loadEnumType(ip_index).tag_ty),
2828 pt,
2829 mod,
2830 kind,
2831 ),
2832 .func_type => |func_info| if (func_info.is_generic) return .void else {
2833 const scratch_top = scratch.items.len;
2834 defer scratch.shrinkRetainingCapacity(scratch_top);
2835 try scratch.ensureUnusedCapacity(allocator, func_info.param_types.len);
2836 var hasher = Hasher.init;
2837 const return_type = Type.fromInterned(func_info.return_type);
2838 const return_ctype: CType =
2839 if (!ip.isNoReturn(func_info.return_type)) try pool.fromType(
2840 allocator,
2841 scratch,
2842 return_type,
2843 pt,
2844 mod,
2845 kind.asParameter(),
2846 ) else .void;
2847 for (0..func_info.param_types.len) |param_index| {
2848 const param_type = Type.fromInterned(
2849 func_info.param_types.get(ip)[param_index],
2850 );
2851 const param_ctype = try pool.fromType(
2852 allocator,
2853 scratch,
2854 param_type,
2855 pt,
2856 mod,
2857 kind.asParameter(),
2858 );
2859 if (param_ctype.index == .void) continue;
2860 hasher.update(param_ctype.hash(pool));
2861 scratch.appendAssumeCapacity(@intFromEnum(param_ctype.index));
2862 }
2863 const param_ctypes_len: u32 = @intCast(scratch.items.len - scratch_top);
2864 try pool.ensureUnusedCapacity(allocator, 1);
2865 const extra_index = try pool.addHashedExtra(allocator, &hasher, Function, .{
2866 .return_ctype = return_ctype.index,
2867 .param_ctypes_len = param_ctypes_len,
2868 }, param_ctypes_len);
2869 pool.extra.appendSliceAssumeCapacity(scratch.items[scratch_top..]);
2870 return pool.tagTrailingExtraAssumeCapacity(hasher, switch (func_info.is_var_args) {
2871 false => .function,
2872 true => .function_varargs,
2873 }, extra_index);
2874 },
2875 .error_set_type,
2876 .inferred_error_set_type,
2877 => return pool.fromIntInfo(allocator, .{
2878 .signedness = .unsigned,
2879 .bits = pt.zcu.errorSetBits(),
2880 }, mod, kind),
2881
2882 .undef,
2883 .simple_value,
2884 .variable,
2885 .@"extern",
2886 .func,
2887 .int,
2888 .err,
2889 .error_union,
2890 .enum_literal,
2891 .enum_tag,
2892 .empty_enum_value,
2893 .float,
2894 .ptr,
2895 .slice,
2896 .opt,
2897 .aggregate,
2898 .un,
2899 .memoized_call,
2900 => unreachable, // values, not types
2901 },
2902 }
2903 }
2904
2905 pub fn getOrPutAdapted(
2906 pool: *Pool,
2907 allocator: std.mem.Allocator,
2908 source_pool: *const Pool,
2909 source_ctype: CType,
2910 pool_adapter: anytype,
2911 ) !struct { CType, bool } {
2912 const tag = source_pool.items.items(.tag)[
2913 source_ctype.toPoolIndex() orelse return .{ source_ctype, true }
2914 ];
2915 try pool.ensureUnusedCapacity(allocator, 1);
2916 const CTypeAdapter = struct {
2917 pool: *const Pool,
2918 source_pool: *const Pool,
2919 source_info: Info,
2920 pool_adapter: @TypeOf(pool_adapter),
2921 pub fn hash(map_adapter: @This(), key_ctype: CType) Map.Hash {
2922 return key_ctype.hash(map_adapter.source_pool);
2923 }
2924 pub fn eql(map_adapter: @This(), _: CType, _: void, pool_index: usize) bool {
2925 return map_adapter.source_info.eqlAdapted(
2926 map_adapter.source_pool,
2927 .fromPoolIndex(pool_index),
2928 map_adapter.pool,
2929 map_adapter.pool_adapter,
2930 );
2931 }
2932 };
2933 const source_info = source_ctype.info(source_pool);
2934 const gop = pool.map.getOrPutAssumeCapacityAdapted(source_ctype, CTypeAdapter{
2935 .pool = pool,
2936 .source_pool = source_pool,
2937 .source_info = source_info,
2938 .pool_adapter = pool_adapter,
2939 });
2940 errdefer _ = pool.map.pop();
2941 const ctype: CType = .fromPoolIndex(gop.index);
2942 if (!gop.found_existing) switch (source_info) {
2943 .basic => unreachable,
2944 .pointer => |pointer_info| pool.items.appendAssumeCapacity(switch (pointer_info.nonstring) {
2945 false => .{
2946 .tag = tag,
2947 .data = @intFromEnum(pool_adapter.copy(pointer_info.elem_ctype).index),
2948 },
2949 true => .{
2950 .tag = .nonstring,
2951 .data = @intFromEnum(pool_adapter.copy(.{ .index = @enumFromInt(
2952 source_pool.items.items(.data)[source_ctype.toPoolIndex().?],
2953 ) }).index),
2954 },
2955 }),
2956 .aligned => |aligned_info| pool.items.appendAssumeCapacity(.{
2957 .tag = tag,
2958 .data = try pool.addExtra(allocator, Aligned, .{
2959 .ctype = pool_adapter.copy(aligned_info.ctype).index,
2960 .flags = .{ .alignas = aligned_info.alignas },
2961 }, 0),
2962 }),
2963 .array, .vector => |sequence_info| pool.items.appendAssumeCapacity(switch (sequence_info.nonstring) {
2964 false => .{
2965 .tag = tag,
2966 .data = switch (tag) {
2967 .array_small, .vector => try pool.addExtra(allocator, SequenceSmall, .{
2968 .elem_ctype = pool_adapter.copy(sequence_info.elem_ctype).index,
2969 .len = @intCast(sequence_info.len),
2970 }, 0),
2971 .array_large => try pool.addExtra(allocator, SequenceLarge, .{
2972 .elem_ctype = pool_adapter.copy(sequence_info.elem_ctype).index,
2973 .len_lo = @truncate(sequence_info.len >> 0),
2974 .len_hi = @truncate(sequence_info.len >> 32),
2975 }, 0),
2976 else => unreachable,
2977 },
2978 },
2979 true => .{
2980 .tag = .nonstring,
2981 .data = @intFromEnum(pool_adapter.copy(.{ .index = @enumFromInt(
2982 source_pool.items.items(.data)[source_ctype.toPoolIndex().?],
2983 ) }).index),
2984 },
2985 }),
2986 .fwd_decl => |fwd_decl_info| switch (fwd_decl_info.name) {
2987 .anon => |fields| {
2988 pool.items.appendAssumeCapacity(.{
2989 .tag = tag,
2990 .data = try pool.addExtra(allocator, FwdDeclAnon, .{
2991 .fields_len = fields.len,
2992 }, fields.len * @typeInfo(Field).@"struct".fields.len),
2993 });
2994 for (0..fields.len) |field_index| {
2995 const field = fields.at(field_index, source_pool);
2996 const field_name = if (field.name.toPoolSlice(source_pool)) |slice|
2997 try pool.string(allocator, slice)
2998 else
2999 field.name;
3000 pool.addExtraAssumeCapacity(Field, .{
3001 .name = field_name.index,
3002 .ctype = pool_adapter.copy(field.ctype).index,
3003 .flags = .{ .alignas = field.alignas },
3004 });
3005 }
3006 },
3007 .index => |index| pool.items.appendAssumeCapacity(.{
3008 .tag = tag,
3009 .data = @intFromEnum(index),
3010 }),
3011 },
3012 .aggregate => |aggregate_info| {
3013 pool.items.appendAssumeCapacity(.{
3014 .tag = tag,
3015 .data = switch (aggregate_info.name) {
3016 .anon => |anon| try pool.addExtra(allocator, AggregateAnon, .{
3017 .index = anon.index,
3018 .id = anon.id,
3019 .fields_len = aggregate_info.fields.len,
3020 }, aggregate_info.fields.len * @typeInfo(Field).@"struct".fields.len),
3021 .fwd_decl => |fwd_decl| try pool.addExtra(allocator, Aggregate, .{
3022 .fwd_decl = pool_adapter.copy(fwd_decl).index,
3023 .fields_len = aggregate_info.fields.len,
3024 }, aggregate_info.fields.len * @typeInfo(Field).@"struct".fields.len),
3025 },
3026 });
3027 for (0..aggregate_info.fields.len) |field_index| {
3028 const field = aggregate_info.fields.at(field_index, source_pool);
3029 const field_name = if (field.name.toPoolSlice(source_pool)) |slice|
3030 try pool.string(allocator, slice)
3031 else
3032 field.name;
3033 pool.addExtraAssumeCapacity(Field, .{
3034 .name = field_name.index,
3035 .ctype = pool_adapter.copy(field.ctype).index,
3036 .flags = .{ .alignas = field.alignas },
3037 });
3038 }
3039 },
3040 .function => |function_info| {
3041 pool.items.appendAssumeCapacity(.{
3042 .tag = tag,
3043 .data = try pool.addExtra(allocator, Function, .{
3044 .return_ctype = pool_adapter.copy(function_info.return_ctype).index,
3045 .param_ctypes_len = function_info.param_ctypes.len,
3046 }, function_info.param_ctypes.len),
3047 });
3048 for (0..function_info.param_ctypes.len) |param_index| pool.extra.appendAssumeCapacity(
3049 @intFromEnum(pool_adapter.copy(
3050 function_info.param_ctypes.at(param_index, source_pool),
3051 ).index),
3052 );
3053 },
3054 };
3055 assert(source_info.eqlAdapted(source_pool, ctype, pool, pool_adapter));
3056 assert(source_ctype.hash(source_pool) == ctype.hash(pool));
3057 return .{ ctype, gop.found_existing };
3058 }
3059
3060 pub fn string(pool: *Pool, allocator: std.mem.Allocator, slice: []const u8) !String {
3061 try pool.string_bytes.appendSlice(allocator, slice);
3062 return pool.trailingString(allocator);
3063 }
3064
3065 pub fn fmt(
3066 pool: *Pool,
3067 allocator: std.mem.Allocator,
3068 comptime fmt_str: []const u8,
3069 fmt_args: anytype,
3070 ) !String {
3071 try pool.string_bytes.print(allocator, fmt_str, fmt_args);
3072 return pool.trailingString(allocator);
3073 }
3074
3075 fn ensureUnusedCapacity(pool: *Pool, allocator: std.mem.Allocator, len: u32) !void {
3076 try pool.map.ensureUnusedCapacity(allocator, len);
3077 try pool.items.ensureUnusedCapacity(allocator, len);
3078 }
3079
3080 const Hasher = struct {
3081 const Impl = std.hash.Wyhash;
3082 impl: Impl,
3083
3084 const init: Hasher = .{ .impl = Impl.init(0) };
3085
3086 fn updateExtra(hasher: *Hasher, comptime Extra: type, extra: Extra, pool: *const Pool) void {
3087 inline for (@typeInfo(Extra).@"struct".fields) |field| {
3088 const value = @field(extra, field.name);
3089 switch (field.type) {
3090 Pool.Tag, String, CType => unreachable,
3091 CType.Index => hasher.update((CType{ .index = value }).hash(pool)),
3092 String.Index => if ((String{ .index = value }).toPoolSlice(pool)) |slice|
3093 hasher.update(slice)
3094 else
3095 hasher.update(@intFromEnum(value)),
3096 else => hasher.update(value),
3097 }
3098 }
3099 }
3100 fn update(hasher: *Hasher, data: anytype) void {
3101 switch (@TypeOf(data)) {
3102 Pool.Tag => @compileError("pass tag to final"),
3103 CType, CType.Index => @compileError("hash ctype.hash(pool) instead"),
3104 String, String.Index => @compileError("hash string.slice(pool) instead"),
3105 u32, InternPool.Index, Aligned.Flags => hasher.impl.update(std.mem.asBytes(&data)),
3106 []const u8 => hasher.impl.update(data),
3107 else => @compileError("unhandled type: " ++ @typeName(@TypeOf(data))),
3108 }
3109 }
3110
3111 fn final(hasher: Hasher, tag: Pool.Tag) Map.Hash {
3112 var impl = hasher.impl;
3113 impl.update(std.mem.asBytes(&tag));
3114 return @truncate(impl.final());
3115 }
3116 };
3117
3118 fn tagData(
3119 pool: *Pool,
3120 allocator: std.mem.Allocator,
3121 hasher: Hasher,
3122 tag: Pool.Tag,
3123 data: u32,
3124 ) !CType {
3125 try pool.ensureUnusedCapacity(allocator, 1);
3126 const Key = struct { hash: Map.Hash, tag: Pool.Tag, data: u32 };
3127 const CTypeAdapter = struct {
3128 pool: *const Pool,
3129 pub fn hash(_: @This(), key: Key) Map.Hash {
3130 return key.hash;
3131 }
3132 pub fn eql(ctype_adapter: @This(), lhs_key: Key, _: void, rhs_index: usize) bool {
3133 const rhs_item = ctype_adapter.pool.items.get(rhs_index);
3134 return lhs_key.tag == rhs_item.tag and lhs_key.data == rhs_item.data;
3135 }
3136 };
3137 const gop = pool.map.getOrPutAssumeCapacityAdapted(
3138 Key{ .hash = hasher.final(tag), .tag = tag, .data = data },
3139 CTypeAdapter{ .pool = pool },
3140 );
3141 if (!gop.found_existing) pool.items.appendAssumeCapacity(.{ .tag = tag, .data = data });
3142 return .fromPoolIndex(gop.index);
3143 }
3144
3145 fn tagExtra(
3146 pool: *Pool,
3147 allocator: std.mem.Allocator,
3148 tag: Pool.Tag,
3149 comptime Extra: type,
3150 extra: Extra,
3151 ) !CType {
3152 var hasher = Hasher.init;
3153 hasher.updateExtra(Extra, extra, pool);
3154 return pool.tagTrailingExtra(
3155 allocator,
3156 hasher,
3157 tag,
3158 try pool.addExtra(allocator, Extra, extra, 0),
3159 );
3160 }
3161
3162 fn tagTrailingExtra(
3163 pool: *Pool,
3164 allocator: std.mem.Allocator,
3165 hasher: Hasher,
3166 tag: Pool.Tag,
3167 extra_index: ExtraIndex,
3168 ) !CType {
3169 try pool.ensureUnusedCapacity(allocator, 1);
3170 return pool.tagTrailingExtraAssumeCapacity(hasher, tag, extra_index);
3171 }
3172
3173 fn tagTrailingExtraAssumeCapacity(
3174 pool: *Pool,
3175 hasher: Hasher,
3176 tag: Pool.Tag,
3177 extra_index: ExtraIndex,
3178 ) CType {
3179 const Key = struct { hash: Map.Hash, tag: Pool.Tag, extra: []const u32 };
3180 const CTypeAdapter = struct {
3181 pool: *const Pool,
3182 pub fn hash(_: @This(), key: Key) Map.Hash {
3183 return key.hash;
3184 }
3185 pub fn eql(ctype_adapter: @This(), lhs_key: Key, _: void, rhs_index: usize) bool {
3186 const rhs_item = ctype_adapter.pool.items.get(rhs_index);
3187 if (lhs_key.tag != rhs_item.tag) return false;
3188 const rhs_extra = ctype_adapter.pool.extra.items[rhs_item.data..];
3189 return std.mem.startsWith(u32, rhs_extra, lhs_key.extra);
3190 }
3191 };
3192 const gop = pool.map.getOrPutAssumeCapacityAdapted(
3193 Key{ .hash = hasher.final(tag), .tag = tag, .extra = pool.extra.items[extra_index..] },
3194 CTypeAdapter{ .pool = pool },
3195 );
3196 if (gop.found_existing)
3197 pool.extra.shrinkRetainingCapacity(extra_index)
3198 else
3199 pool.items.appendAssumeCapacity(.{ .tag = tag, .data = extra_index });
3200 return .fromPoolIndex(gop.index);
3201 }
3202
3203 fn sortFields(fields: []Info.Field) void {
3204 std.mem.sort(Info.Field, fields, {}, struct {
3205 fn before(_: void, lhs_field: Info.Field, rhs_field: Info.Field) bool {
3206 return lhs_field.alignas.order(rhs_field.alignas).compare(.gt);
3207 }
3208 }.before);
3209 }
3210
3211 fn trailingString(pool: *Pool, allocator: std.mem.Allocator) !String {
3212 const start = pool.string_indices.getLast();
3213 const slice: []const u8 = pool.string_bytes.items[start..];
3214 if (slice.len >= 2 and slice[0] == 'f' and switch (slice[1]) {
3215 '0' => slice.len == 2,
3216 '1'...'9' => true,
3217 else => false,
3218 }) if (std.fmt.parseInt(u31, slice[1..], 10)) |unnamed| {
3219 pool.string_bytes.shrinkRetainingCapacity(start);
3220 return String.fromUnnamed(unnamed);
3221 } else |_| {};
3222 if (std.meta.stringToEnum(String.Index, slice)) |index| {
3223 pool.string_bytes.shrinkRetainingCapacity(start);
3224 return .{ .index = index };
3225 }
3226
3227 try pool.string_map.ensureUnusedCapacity(allocator, 1);
3228 try pool.string_indices.ensureUnusedCapacity(allocator, 1);
3229
3230 const gop = pool.string_map.getOrPutAssumeCapacityAdapted(slice, String.Adapter{ .pool = pool });
3231 if (gop.found_existing)
3232 pool.string_bytes.shrinkRetainingCapacity(start)
3233 else
3234 pool.string_indices.appendAssumeCapacity(@intCast(pool.string_bytes.items.len));
3235 return String.fromPoolIndex(gop.index);
3236 }
3237
3238 const Item = struct {
3239 tag: Pool.Tag,
3240 data: u32,
3241 };
3242
3243 const ExtraIndex = u32;
3244
3245 const Tag = enum(u8) {
3246 basic,
3247 pointer,
3248 pointer_const,
3249 pointer_volatile,
3250 pointer_const_volatile,
3251 aligned,
3252 array_small,
3253 array_large,
3254 vector,
3255 nonstring,
3256 fwd_decl_struct_anon,
3257 fwd_decl_union_anon,
3258 fwd_decl_struct,
3259 fwd_decl_union,
3260 aggregate_struct_anon,
3261 aggregate_struct_packed_anon,
3262 aggregate_union_anon,
3263 aggregate_union_packed_anon,
3264 aggregate_struct,
3265 aggregate_struct_packed,
3266 aggregate_union,
3267 aggregate_union_packed,
3268 function,
3269 function_varargs,
3270 };
3271
3272 const Aligned = struct {
3273 ctype: CType.Index,
3274 flags: Flags,
3275
3276 const Flags = packed struct(u32) {
3277 alignas: AlignAs,
3278 _: u20 = 0,
3279 };
3280 };
3281
3282 const SequenceSmall = struct {
3283 elem_ctype: CType.Index,
3284 len: u32,
3285 };
3286
3287 const SequenceLarge = struct {
3288 elem_ctype: CType.Index,
3289 len_lo: u32,
3290 len_hi: u32,
3291
3292 fn len(extra: SequenceLarge) u64 {
3293 return @as(u64, extra.len_lo) << 0 |
3294 @as(u64, extra.len_hi) << 32;
3295 }
3296 };
3297
3298 const Field = struct {
3299 name: String.Index,
3300 ctype: CType.Index,
3301 flags: Flags,
3302
3303 const Flags = Aligned.Flags;
3304 };
3305
3306 const FwdDeclAnon = struct {
3307 fields_len: u32,
3308 };
3309
3310 const AggregateAnon = struct {
3311 index: InternPool.Index,
3312 id: u32,
3313 fields_len: u32,
3314 };
3315
3316 const Aggregate = struct {
3317 fwd_decl: CType.Index,
3318 fields_len: u32,
3319 };
3320
3321 const Function = struct {
3322 return_ctype: CType.Index,
3323 param_ctypes_len: u32,
3324 };
3325
3326 fn addExtra(
3327 pool: *Pool,
3328 allocator: std.mem.Allocator,
3329 comptime Extra: type,
3330 extra: Extra,
3331 trailing_len: usize,
3332 ) !ExtraIndex {
3333 try pool.extra.ensureUnusedCapacity(
3334 allocator,
3335 @typeInfo(Extra).@"struct".fields.len + trailing_len,
3336 );
3337 defer pool.addExtraAssumeCapacity(Extra, extra);
3338 return @intCast(pool.extra.items.len);
3339 }
3340 fn addExtraAssumeCapacity(pool: *Pool, comptime Extra: type, extra: Extra) void {
3341 addExtraAssumeCapacityTo(&pool.extra, Extra, extra);
3342 }
3343 fn addExtraAssumeCapacityTo(
3344 array: *std.ArrayList(u32),
3345 comptime Extra: type,
3346 extra: Extra,
3347 ) void {
3348 inline for (@typeInfo(Extra).@"struct".fields) |field| {
3349 const value = @field(extra, field.name);
3350 array.appendAssumeCapacity(switch (field.type) {
3351 u32 => value,
3352 CType.Index, String.Index, InternPool.Index => @intFromEnum(value),
3353 Aligned.Flags => @bitCast(value),
3354 else => @compileError("bad field type: " ++ field.name ++ ": " ++
3355 @typeName(field.type)),
3356 });
3357 }
3358 }
3359
3360 fn addHashedExtra(
3361 pool: *Pool,
3362 allocator: std.mem.Allocator,
3363 hasher: *Hasher,
3364 comptime Extra: type,
3365 extra: Extra,
3366 trailing_len: usize,
3367 ) !ExtraIndex {
3368 hasher.updateExtra(Extra, extra, pool);
3369 return pool.addExtra(allocator, Extra, extra, trailing_len);
3370 }
3371 fn addHashedExtraAssumeCapacity(
3372 pool: *Pool,
3373 hasher: *Hasher,
3374 comptime Extra: type,
3375 extra: Extra,
3376 ) void {
3377 hasher.updateExtra(Extra, extra, pool);
3378 pool.addExtraAssumeCapacity(Extra, extra);
3379 }
3380 fn addHashedExtraAssumeCapacityTo(
3381 pool: *Pool,
3382 array: *std.ArrayList(u32),
3383 hasher: *Hasher,
3384 comptime Extra: type,
3385 extra: Extra,
3386 ) void {
3387 hasher.updateExtra(Extra, extra, pool);
3388 addExtraAssumeCapacityTo(array, Extra, extra);
3389 }
3390
3391 const ExtraTrail = struct {
3392 extra_index: ExtraIndex,
3393
3394 fn next(
3395 extra_trail: *ExtraTrail,
3396 len: u32,
3397 comptime Extra: type,
3398 pool: *const Pool,
3399 ) []const Extra {
3400 defer extra_trail.extra_index += @intCast(len);
3401 return @ptrCast(pool.extra.items[extra_trail.extra_index..][0..len]);
3402 }
3403 };
3404
3405 fn getExtraTrail(
3406 pool: *const Pool,
3407 comptime Extra: type,
3408 extra_index: ExtraIndex,
3409 ) struct { extra: Extra, trail: ExtraTrail } {
3410 var extra: Extra = undefined;
3411 const fields = @typeInfo(Extra).@"struct".fields;
3412 inline for (fields, pool.extra.items[extra_index..][0..fields.len]) |field, value|
3413 @field(extra, field.name) = switch (field.type) {
3414 u32 => value,
3415 CType.Index, String.Index, InternPool.Index => @enumFromInt(value),
3416 Aligned.Flags => @bitCast(value),
3417 else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)),
3418 };
3419 return .{
3420 .extra = extra,
3421 .trail = .{ .extra_index = extra_index + @as(ExtraIndex, @intCast(fields.len)) },
3422 };
3423 }
3424
3425 fn getExtra(pool: *const Pool, comptime Extra: type, extra_index: ExtraIndex) Extra {
3426 return pool.getExtraTrail(Extra, extra_index).extra;
3427 }
3428};
3429
3430pub const AlignAs = packed struct {
3431 @"align": InternPool.Alignment,
3432 abi: InternPool.Alignment,
3433
3434 pub fn fromAlignment(alignas: AlignAs) AlignAs {
3435 assert(alignas.abi != .none);
3436 return .{
3437 .@"align" = if (alignas.@"align" != .none) alignas.@"align" else alignas.abi,
3438 .abi = alignas.abi,
3439 };
3440 }
3441 pub fn fromAbiAlignment(abi: InternPool.Alignment) AlignAs {
3442 assert(abi != .none);
3443 return .{ .@"align" = abi, .abi = abi };
3444 }
3445 pub fn fromByteUnits(@"align": u64, abi: u64) AlignAs {
3446 return fromAlignment(.{
3447 .@"align" = InternPool.Alignment.fromByteUnits(@"align"),
3448 .abi = InternPool.Alignment.fromNonzeroByteUnits(abi),
3449 });
3450 }
3451
3452 pub fn order(lhs: AlignAs, rhs: AlignAs) std.math.Order {
3453 return lhs.@"align".order(rhs.@"align");
3454 }
3455 pub fn abiOrder(alignas: AlignAs) std.math.Order {
3456 return alignas.@"align".order(alignas.abi);
3457 }
3458 pub fn toByteUnits(alignas: AlignAs) u64 {
3459 return alignas.@"align".toByteUnits().?;
3460 }
3461};
3462
3463const std = @import("std");
3464const assert = std.debug.assert;
3465const Writer = std.Io.Writer;
3466
3467const CType = @This();
3468const InternPool = @import("../../InternPool.zig");
3469const Module = @import("../../Package/Module.zig");
3470const Type = @import("../../Type.zig");
3471const Value = @import("../../Value.zig");
3472const Zcu = @import("../../Zcu.zig");
src/codegen/c/type.zig created+1023
......@@ -0,0 +1,1023 @@
1pub const CType = union(enum) {
2 pub const render_defs = @import("type/render_defs.zig");
3
4 // The first nodes are primitive types (or standard typedefs).
5
6 void,
7 bool,
8 int: Int,
9 float: Float,
10
11 // These next nodes are all typedefs, structs, or unions.
12
13 @"fn": Type,
14 @"enum": Type,
15 bitpack: Type,
16 @"struct": Type,
17 union_auto: Type,
18 union_extern: Type,
19 slice: Type,
20 opt: Type,
21 arr: Type,
22 vec: Type,
23 errunion: struct { payload_ty: Type },
24 aligned: struct {
25 ty: Type,
26 alignment: InternPool.Alignment,
27 },
28 bigint: BigInt,
29
30 // The remaining nodes have children.
31
32 pointer: struct {
33 @"const": bool,
34 @"volatile": bool,
35 elem_ty: *const CType,
36 nonstring: bool,
37 },
38 array: struct {
39 len: u64,
40 elem_ty: *const CType,
41 nonstring: bool,
42 },
43 function: struct {
44 param_tys: []const CType,
45 ret_ty: *const CType,
46 varargs: bool,
47 },
48
49 /// Returns `true` if this node has a postfix operator, meaning an `[...]` or `(...)` appears
50 /// after the identifier in a declarator with this type. In this case, if this node is wrapped
51 /// in a pointer type, we will need to add parentheses due to operator precedence.
52 ///
53 /// For instance, when lowering a Zig declaration `foo: *const fn (c_int) void`, it would be a
54 /// bug to write the C declarator as `void *foo(int)`, because the `(int)` suffix declaring the
55 /// function type has higher precedence than the `*` prefix declaring the pointer type. Instead,
56 /// this type must be lowered as `void (*foo)(int)`.
57 fn kind(cty: *const CType) enum {
58 /// `cty` is just a C type specifier, i.e. a typedef or a named struct/union type.
59 specifier,
60 /// `cty` is a C function or array type. It will have a postfix "operator" in its suffix to
61 /// declare the type, either `(...)` (for a function type) or `[...]` (for an array type).
62 postfix_op,
63 /// `cty` is a C pointer type. Its prefix will end with "*".
64 pointer,
65 } {
66 return switch (cty.*) {
67 .void,
68 .bool,
69 .int,
70 .float,
71 .@"fn",
72 .@"enum",
73 .bitpack,
74 .@"struct",
75 .union_auto,
76 .union_extern,
77 .slice,
78 .opt,
79 .arr,
80 .vec,
81 .errunion,
82 .aligned,
83 .bigint,
84 => .specifier,
85
86 .array,
87 .function,
88 => .postfix_op,
89
90 .pointer => .pointer,
91 };
92 }
93
94 pub const Int = enum {
95 char,
96
97 @"unsigned short",
98 @"unsigned int",
99 @"unsigned long",
100 @"unsigned long long",
101
102 @"signed short",
103 @"signed int",
104 @"signed long",
105 @"signed long long",
106
107 uint8_t,
108 uint16_t,
109 uint32_t,
110 uint64_t,
111 zig_u128,
112
113 int8_t,
114 int16_t,
115 int32_t,
116 int64_t,
117 zig_i128,
118
119 uintptr_t,
120 intptr_t,
121
122 pub fn bits(int: Int, target: *const std.Target) u16 {
123 return switch (int) {
124 // zig fmt: off
125 .char => target.cTypeBitSize(.char),
126
127 .@"unsigned short" => target.cTypeBitSize(.ushort),
128 .@"unsigned int" => target.cTypeBitSize(.uint),
129 .@"unsigned long" => target.cTypeBitSize(.ulong),
130 .@"unsigned long long" => target.cTypeBitSize(.ulonglong),
131
132 .@"signed short" => target.cTypeBitSize(.short),
133 .@"signed int" => target.cTypeBitSize(.int),
134 .@"signed long" => target.cTypeBitSize(.long),
135 .@"signed long long" => target.cTypeBitSize(.longlong),
136
137 .uintptr_t, .intptr_t => target.ptrBitWidth(),
138
139 .uint8_t, .int8_t => 8,
140 .uint16_t, .int16_t => 16,
141 .uint32_t, .int32_t => 32,
142 .uint64_t, .int64_t => 64,
143 .zig_u128, .zig_i128 => 128,
144 // zig fmt: on
145 };
146 }
147 };
148
149 pub const BigInt = struct {
150 limb_size: LimbSize,
151 /// Always greater than 1.
152 limbs_len: u16,
153
154 pub const LimbSize = enum {
155 @"8",
156 @"16",
157 @"32",
158 @"64",
159 @"128",
160 pub fn bits(s: LimbSize) u8 {
161 return switch (s) {
162 .@"8" => 8,
163 .@"16" => 16,
164 .@"32" => 32,
165 .@"64" => 64,
166 .@"128" => 128,
167 };
168 }
169 pub fn unsigned(s: LimbSize) Int {
170 return switch (s) {
171 .@"8" => .uint8_t,
172 .@"16" => .uint16_t,
173 .@"32" => .uint32_t,
174 .@"64" => .uint64_t,
175 .@"128" => .zig_u128,
176 };
177 }
178 pub fn signed(s: LimbSize) Int {
179 return switch (s) {
180 .@"8" => .int8_t,
181 .@"16" => .int16_t,
182 .@"32" => .int32_t,
183 .@"64" => .int64_t,
184 .@"128" => .zig_i128,
185 };
186 }
187 };
188 };
189
190 pub const Float = enum {
191 @"long double",
192 zig_f16,
193 zig_f32,
194 zig_f64,
195 zig_f80,
196 zig_f128,
197 zig_u128,
198 zig_i128,
199 };
200
201 pub fn isStringElem(cty: CType) bool {
202 return switch (cty) {
203 .int => |int| switch (int) {
204 .char, .int8_t, .uint8_t => true,
205 else => false,
206 },
207 else => false,
208 };
209 }
210
211 pub fn lower(
212 ty: Type,
213 deps: *Dependencies,
214 arena: Allocator,
215 zcu: *const Zcu,
216 ) Allocator.Error!CType {
217 return lowerInner(ty, false, deps, arena, zcu);
218 }
219 fn lowerInner(
220 start_ty: Type,
221 allow_incomplete: bool,
222 deps: *Dependencies,
223 arena: Allocator,
224 zcu: *const Zcu,
225 ) Allocator.Error!CType {
226 const gpa = zcu.comp.gpa;
227 const ip = &zcu.intern_pool;
228 var cur_ty = start_ty;
229 while (true) {
230 switch (cur_ty.zigTypeTag(zcu)) {
231 .type,
232 .comptime_int,
233 .comptime_float,
234 .undefined,
235 .null,
236 .enum_literal,
237 .@"opaque",
238 .noreturn,
239 .void,
240 => return .void,
241
242 .bool => return .bool,
243
244 .int, .error_set => switch (classifyInt(cur_ty, zcu)) {
245 .void => return .void,
246 .small => |s| return .{ .int = s },
247 .big => |big| {
248 try deps.bigint.put(gpa, big, {});
249 return .{ .bigint = big };
250 },
251 },
252
253 .float => return .{ .float = switch (cur_ty.toIntern()) {
254 .c_longdouble_type => .@"long double",
255 .f16_type => .zig_f16,
256 .f32_type => .zig_f32,
257 .f64_type => .zig_f64,
258 .f80_type => .zig_f80,
259 .f128_type => .zig_f128,
260 else => unreachable,
261 } },
262 .vector => {
263 try deps.addType(gpa, cur_ty, allow_incomplete);
264 return .{ .vec = cur_ty };
265 },
266 .array => {
267 try deps.addType(gpa, cur_ty, allow_incomplete);
268 return .{ .arr = cur_ty };
269 },
270
271 .pointer => {
272 const ptr = cur_ty.ptrInfo(zcu);
273 switch (ptr.flags.size) {
274 .slice => {
275 try deps.addType(gpa, cur_ty, allow_incomplete);
276 return .{ .slice = cur_ty };
277 },
278 .one, .many, .c => {
279 const elem_ty: Type = .fromInterned(ptr.child);
280 const is_fn_ptr = elem_ty.zigTypeTag(zcu) == .@"fn";
281 const elem_cty: CType = elem_cty: {
282 if (ptr.packed_offset.host_size > 0 and ptr.flags.vector_index == .none) {
283 switch (classifyBitInt(.unsigned, ptr.packed_offset.host_size * 8, zcu)) {
284 .void => break :elem_cty .void,
285 .small => |s| break :elem_cty .{ .int = s },
286 .big => |big| {
287 try deps.bigint.put(gpa, big, {});
288 break :elem_cty .{ .bigint = big };
289 },
290 }
291 }
292 if (ptr.flags.alignment != .none and !is_fn_ptr) {
293 // The pointer has an explicit alignment---if it's an underalignment
294 // then we need to use an "aligned" typedef.
295 const ptr_align = ptr.flags.alignment;
296 if (!alwaysHasLayout(elem_ty, ip) or
297 ptr_align.compareStrict(.lt, elem_ty.abiAlignment(zcu)))
298 {
299 const gop = try deps.aligned_type_fwd.getOrPut(gpa, elem_ty.toIntern());
300 if (!gop.found_existing) gop.value_ptr.* = 0;
301 gop.value_ptr.* |= @as(u64, 1) << ptr_align.toLog2Units();
302 break :elem_cty .{ .aligned = .{
303 .ty = elem_ty,
304 .alignment = ptr_align,
305 } };
306 }
307 }
308 break :elem_cty try .lowerInner(elem_ty, true, deps, arena, zcu);
309 };
310 const elem_cty_buf = try arena.create(CType);
311 elem_cty_buf.* = elem_cty;
312 return .{ .pointer = .{
313 .@"const" = ptr.flags.is_const and !is_fn_ptr,
314 .@"volatile" = ptr.flags.is_volatile and !is_fn_ptr,
315 .elem_ty = elem_cty_buf,
316 .nonstring = nonstring: {
317 if (!elem_cty.isStringElem()) break :nonstring false;
318 if (ptr.sentinel == .none) break :nonstring true;
319 break :nonstring Value.compareHetero(
320 .fromInterned(ptr.sentinel),
321 .neq,
322 .zero_comptime_int,
323 zcu,
324 );
325 },
326 } };
327 },
328 }
329 },
330
331 .@"fn" => {
332 const func_type = ip.indexToKey(cur_ty.toIntern()).func_type;
333 direct: {
334 const ret_ty: Type = .fromInterned(func_type.return_type);
335 if (!alwaysHasLayout(ret_ty, ip)) break :direct;
336 var params_len: usize = 0; // only counts parameter types with runtime bits
337 for (func_type.param_types.get(ip)) |param_ty_ip| {
338 const param_ty: Type = .fromInterned(param_ty_ip);
339 if (!alwaysHasLayout(param_ty, ip)) break :direct;
340 if (param_ty.hasRuntimeBits(zcu)) params_len += 1;
341 }
342 // We can actually write this function type directly!
343 if (!cur_ty.fnHasRuntimeBits(zcu)) return .void;
344 const ret_cty_buf = try arena.create(CType);
345 if (!ret_ty.hasRuntimeBits(zcu)) {
346 // Incomplete function return types must always be `void`.
347 ret_cty_buf.* = .void;
348 } else {
349 ret_cty_buf.* = try .lowerInner(ret_ty, allow_incomplete, deps, arena, zcu);
350 }
351 const param_cty_buf = try arena.alloc(CType, params_len);
352 var param_index: usize = 0;
353 for (func_type.param_types.get(ip)) |param_ty_ip| {
354 const param_ty: Type = .fromInterned(param_ty_ip);
355 if (!param_ty.hasRuntimeBits(zcu)) continue;
356 param_cty_buf[param_index] = try .lowerInner(param_ty, allow_incomplete, deps, arena, zcu);
357 param_index += 1;
358 }
359 assert(param_index == params_len);
360 return .{ .function = .{
361 .ret_ty = ret_cty_buf,
362 .param_tys = param_cty_buf,
363 .varargs = func_type.is_var_args,
364 } };
365 }
366 try deps.addType(gpa, cur_ty, allow_incomplete);
367 return .{ .@"fn" = cur_ty };
368 },
369
370 .@"struct" => {
371 try deps.addType(gpa, cur_ty, allow_incomplete);
372 switch (cur_ty.containerLayout(zcu)) {
373 .auto, .@"extern" => return .{ .@"struct" = cur_ty },
374 .@"packed" => return .{ .bitpack = cur_ty },
375 }
376 },
377 .@"union" => {
378 try deps.addType(gpa, cur_ty, allow_incomplete);
379 switch (cur_ty.containerLayout(zcu)) {
380 .auto => return .{ .union_auto = cur_ty },
381 .@"extern" => return .{ .union_extern = cur_ty },
382 .@"packed" => return .{ .bitpack = cur_ty },
383 }
384 },
385 .@"enum" => {
386 try deps.addType(gpa, cur_ty, allow_incomplete);
387 return .{ .@"enum" = cur_ty };
388 },
389
390 .optional => {
391 // This query does not require any type resolution.
392 if (cur_ty.optionalReprIsPayload(zcu)) {
393 // Either a pointer-like optional, or an optional error set. Just lower the payload.
394 cur_ty = cur_ty.optionalChild(zcu);
395 continue;
396 }
397 if (alwaysHasLayout(cur_ty, ip)) switch (classifyOptional(cur_ty, zcu)) {
398 .error_set, .ptr_like, .slice_like => unreachable, // handled above
399 .npv_payload => return .void,
400 .opv_payload, .@"struct" => {},
401 };
402 try deps.addType(gpa, cur_ty, allow_incomplete);
403 return .{ .opt = cur_ty };
404 },
405
406 .error_union => {
407 const payload_ty = cur_ty.errorUnionPayload(zcu);
408 if (allow_incomplete) {
409 try deps.errunion_type_fwd.put(gpa, payload_ty.toIntern(), {});
410 } else {
411 try deps.errunion_type.put(gpa, payload_ty.toIntern(), {});
412 }
413 return .{ .errunion = .{
414 .payload_ty = payload_ty,
415 } };
416 },
417
418 .frame,
419 .@"anyframe",
420 => unreachable,
421 }
422 comptime unreachable;
423 }
424 }
425
426 pub fn classifyOptional(opt_ty: Type, zcu: *const Zcu) enum {
427 /// The optional is something like `?noreturn`; it lowers to `void`.
428 npv_payload,
429 /// The payload type is an error set; the representation matches that of the error set, with
430 /// the value 0 representing `null`.
431 error_set,
432 /// The payload type is a non-optional pointer; the NULL pointer is used for `null`.
433 ptr_like,
434 /// The payload type is a non-optional slice; a NULL pointer field is used for `null`.
435 slice_like,
436 /// The optional is something like `?void`; it lowers to a struct, but one containing only
437 /// one field `is_null` (the payload is omitted).
438 opv_payload,
439 /// The optional uses the "default" lowering of a struct with two fields, like this:
440 /// struct optional_1234 { payload_ty payload; bool is_null; }
441 @"struct",
442 } {
443 const payload_ty = opt_ty.optionalChild(zcu);
444 if (opt_ty.optionalReprIsPayload(zcu)) {
445 return switch (payload_ty.zigTypeTag(zcu)) {
446 .error_set => .error_set,
447 .pointer => if (payload_ty.isSlice(zcu)) .slice_like else .ptr_like,
448 else => unreachable,
449 };
450 } else {
451 return switch (payload_ty.classify(zcu)) {
452 .no_possible_value => .npv_payload,
453 .one_possible_value => .opv_payload,
454 else => .@"struct",
455 };
456 }
457 }
458
459 pub const IntClass = union(enum) {
460 /// The integer type is zero-bit, so lowers to `void`.
461 void,
462 /// The integer is under 128 bits long, so lowers to this C integer type.
463 small: Int,
464 /// The integer is over 128 bits long, so lowers to an array of limbs.
465 big: BigInt,
466 };
467
468 /// Asserts that `ty` is an integer, enum, bitpack, or error set.
469 pub fn classifyInt(ty: Type, zcu: *const Zcu) IntClass {
470 const int_ty: Type = switch (ty.zigTypeTag(zcu)) {
471 .error_set => return classifyBitInt(.unsigned, zcu.errorSetBits(), zcu),
472 .@"enum" => ty.intTagType(zcu),
473 .@"struct", .@"union" => ty.bitpackBackingInt(zcu),
474 .int => ty,
475 else => unreachable,
476 };
477 switch (int_ty.toIntern()) {
478 // zig fmt: off
479 .usize_type => return .{ .small = .uintptr_t },
480 .isize_type => return .{ .small = .intptr_t },
481
482 .c_char_type => return .{ .small = .char },
483
484 .c_short_type => return .{ .small = .@"signed short" },
485 .c_int_type => return .{ .small = .@"signed int" },
486 .c_long_type => return .{ .small = .@"signed long" },
487 .c_longlong_type => return .{ .small = .@"signed long long" },
488
489 .c_ushort_type => return .{ .small = .@"unsigned short" },
490 .c_uint_type => return .{ .small = .@"unsigned int" },
491 .c_ulong_type => return .{ .small = .@"unsigned long" },
492 .c_ulonglong_type => return .{ .small = .@"unsigned long long" },
493 // zig fmt: on
494
495 else => {
496 const int = ty.intInfo(zcu);
497 return classifyBitInt(int.signedness, int.bits, zcu);
498 },
499 }
500 }
501 fn classifyBitInt(signedness: std.builtin.Signedness, bits: u16, zcu: *const Zcu) IntClass {
502 return switch (bits) {
503 0 => .void,
504 1...8 => switch (signedness) {
505 .unsigned => .{ .small = .uint8_t },
506 .signed => .{ .small = .int8_t },
507 },
508 9...16 => switch (signedness) {
509 .unsigned => .{ .small = .uint16_t },
510 .signed => .{ .small = .int16_t },
511 },
512 17...32 => switch (signedness) {
513 .unsigned => .{ .small = .uint32_t },
514 .signed => .{ .small = .int32_t },
515 },
516 33...64 => switch (signedness) {
517 .unsigned => .{ .small = .uint64_t },
518 .signed => .{ .small = .int64_t },
519 },
520 65...128 => switch (signedness) {
521 .unsigned => .{ .small = .zig_u128 },
522 .signed => .{ .small = .zig_i128 },
523 },
524 else => {
525 @branchHint(.unlikely);
526 const target = zcu.getTarget();
527 const limb_bytes = std.zig.target.intAlignment(target, bits);
528 return .{ .big = .{
529 .limb_size = switch (limb_bytes) {
530 1 => .@"8",
531 2 => .@"16",
532 4 => .@"32",
533 8 => .@"64",
534 16 => .@"128",
535 else => unreachable,
536 },
537 .limbs_len = @divExact(
538 std.zig.target.intByteSize(target, bits),
539 limb_bytes,
540 ),
541 } };
542 },
543 };
544 }
545
546 /// Describes a set of types which must be declared or completed in the C source file before
547 /// some string of rendered C code (such as a function), due to said C code using these types.
548 pub const Dependencies = struct {
549 /// Key is any Zig type which corresponds to a C `struct`, `union`, or `typedef`. That C
550 /// type must be declared and complete.
551 type: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
552
553 /// Key is a Zig type which is the *payload* of an error union. The C `struct` type
554 /// corresponding to such an error union must be declared and complete.
555 ///
556 /// These are separate from `type` to avoid redundant types for every different error set
557 /// used with the same payload type---for instance a different C type for every `E!void`.
558 errunion_type: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
559
560 /// Like `type`, but the type does not necessarily need to be completed yet: a forward
561 /// declaration is sufficient.
562 type_fwd: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
563
564 /// Like `errunion_type`, but the type does not necessarily need to be completed yet: a
565 /// forward declaration is sufficient.
566 errunion_type_fwd: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
567
568 /// Key is a Zig type; value is a bitmask of alignments. For every bit which is set, an
569 /// aligned typedef is required. For instance, if bit 3 is set, the C type 'aligned__8_foo'
570 /// must be declared through `typedef` (but not necessarily completed yet).
571 aligned_type_fwd: std.AutoArrayHashMapUnmanaged(InternPool.Index, u64),
572
573 /// Key specifies a big-int type whose C `struct` must be declared and complete.
574 bigint: std.AutoArrayHashMapUnmanaged(BigInt, void),
575
576 pub const empty: Dependencies = .{
577 .type = .empty,
578 .errunion_type = .empty,
579 .type_fwd = .empty,
580 .errunion_type_fwd = .empty,
581 .aligned_type_fwd = .empty,
582 .bigint = .empty,
583 };
584
585 pub fn deinit(deps: *Dependencies, gpa: Allocator) void {
586 deps.type.deinit(gpa);
587 deps.errunion_type.deinit(gpa);
588 deps.type_fwd.deinit(gpa);
589 deps.errunion_type_fwd.deinit(gpa);
590 deps.aligned_type_fwd.deinit(gpa);
591 deps.bigint.deinit(gpa);
592 }
593
594 pub fn clearRetainingCapacity(deps: *Dependencies) void {
595 deps.type.clearRetainingCapacity();
596 deps.errunion_type.clearRetainingCapacity();
597 deps.type_fwd.clearRetainingCapacity();
598 deps.errunion_type_fwd.clearRetainingCapacity();
599 deps.aligned_type_fwd.clearRetainingCapacity();
600 deps.bigint.clearRetainingCapacity();
601 }
602
603 pub fn move(deps: *Dependencies) Dependencies {
604 const moved = deps.*;
605 deps.* = .empty;
606 return moved;
607 }
608
609 fn addType(deps: *Dependencies, gpa: Allocator, ty: Type, allow_incomplete: bool) Allocator.Error!void {
610 if (allow_incomplete) {
611 try deps.type_fwd.put(gpa, ty.toIntern(), {});
612 } else {
613 try deps.type.put(gpa, ty.toIntern(), {});
614 }
615 }
616 };
617
618 /// Formats the bytes which appear *before* the identifier in a declarator. This includes the
619 /// type specifier and all "prefix type operators" in the declarator. e.g:
620 /// * for the declarator "int foo", writes "int "
621 /// * for the declarator "struct thing *foo", writes "struct thing *"
622 /// * for the declarator "void *(*foo)(int)", writes "void *(*"
623 pub fn fmtDeclaratorPrefix(cty: CType, zcu: *const Zcu) Formatter {
624 return .{
625 .cty = cty,
626 .zcu = zcu,
627 .kind = .declarator_prefix,
628 };
629 }
630 /// Formats the bytes which appear *before* the identifier in a declarator. This includes the
631 /// type specifier and all "prefix type operators" in the declarator. e.g:
632 /// * for the declarator "int foo", writes ""
633 /// * for the declarator "struct thing *foo", writes ""
634 /// * for the declarator "void *(*foo)(int)", writes ")(int)"
635 pub fn fmtDeclaratorSuffix(cty: CType, zcu: *const Zcu) Formatter {
636 return .{
637 .cty = cty,
638 .zcu = zcu,
639 .kind = .declarator_suffix,
640 };
641 }
642 /// Like `fmtDeclaratorSuffix`, except never emits a `zig_nonstring` annotation.
643 pub fn fmtDeclaratorSuffixIgnoreNonstring(cty: CType, zcu: *const Zcu) Formatter {
644 return .{
645 .cty = cty,
646 .zcu = zcu,
647 .kind = .declarator_suffix_ignore_nonstring,
648 };
649 }
650 /// Formats a type's full name, e.g. "int", "struct foo *", "void *(uint32_t)".
651 ///
652 /// This is almost identical to `fmtDeclaratorPrefix` followed by `fmtDeclaratorSuffix`, but
653 /// that sequence of calls may emit trailing whitespace where this one does not---for instance,
654 /// those calls would write the type "void" as "void ".
655 pub fn fmtTypeName(cty: CType, zcu: *const Zcu) Formatter {
656 return .{
657 .cty = cty,
658 .zcu = zcu,
659 .kind = .type_name,
660 };
661 }
662
663 const Formatter = struct {
664 cty: CType,
665 zcu: *const Zcu,
666 kind: enum { type_name, declarator_prefix, declarator_suffix, declarator_suffix_ignore_nonstring },
667
668 pub fn format(ctx: Formatter, w: *Writer) Writer.Error!void {
669 switch (ctx.kind) {
670 .type_name => {
671 try ctx.cty.writeTypePrefix(w, ctx.zcu);
672 try ctx.cty.writeTypeSuffix(w, ctx.zcu);
673 },
674 .declarator_prefix => {
675 try ctx.cty.writeTypePrefix(w, ctx.zcu);
676 switch (ctx.cty.kind()) {
677 .specifier => try w.writeByte(' '), // write "int " rather than "int"
678 .pointer => {}, // we already have something like "foo *"
679 .postfix_op => {}, // we already have something like "ret_ty "
680 }
681 },
682 .declarator_suffix => {
683 try ctx.cty.writeTypeSuffix(w, ctx.zcu);
684 const nonstring = switch (ctx.cty) {
685 .array => |arr| arr.nonstring,
686 .pointer => |ptr| ptr.nonstring,
687 else => false,
688 };
689 if (nonstring) try w.writeAll(" zig_nonstring");
690 },
691 .declarator_suffix_ignore_nonstring => {
692 try ctx.cty.writeTypeSuffix(w, ctx.zcu);
693 },
694 }
695 }
696 };
697
698 fn writeTypePrefix(cty: CType, w: *Writer, zcu: *const Zcu) Writer.Error!void {
699 switch (cty) {
700 .void => try w.writeAll("void"),
701 .bool => try w.writeAll("bool"),
702 .int => |int| try w.writeAll(@tagName(int)),
703 .float => |float| try w.writeAll(@tagName(float)),
704 .@"fn" => |ty| try w.print("{f}_{d}", .{ fmtZigType(ty, zcu), ty.toIntern() }),
705 .@"enum" => |ty| try w.print("enum__{f}_{d}", .{ fmtZigType(ty, zcu), ty.toIntern() }),
706 .bitpack => |ty| try w.print("bitpack__{f}_{d}", .{ fmtZigType(ty, zcu), ty.toIntern() }),
707 .@"struct" => |ty| try w.print("struct {f}_{d}", .{ fmtZigType(ty, zcu), ty.toIntern() }),
708 .union_auto => |ty| try w.print("struct {f}_{d}", .{ fmtZigType(ty, zcu), ty.toIntern() }),
709 .union_extern => |ty| try w.print("union {f}_{d}", .{ fmtZigType(ty, zcu), ty.toIntern() }),
710 .slice => |ty| try w.print("struct {f}_{d}", .{ fmtZigType(ty, zcu), ty.toIntern() }),
711 .opt => |ty| try w.print("struct {f}_{d}", .{ fmtZigType(ty, zcu), ty.toIntern() }),
712 .arr => |ty| try w.print("struct {f}_{d}", .{ fmtZigType(ty, zcu), ty.toIntern() }),
713 .vec => |ty| try w.print("struct {f}_{d}", .{ fmtZigType(ty, zcu), ty.toIntern() }),
714 .errunion => |eu| try w.print("struct errunion_{f}_{d}", .{
715 fmtZigType(eu.payload_ty, zcu),
716 eu.payload_ty.toIntern(),
717 }),
718 .aligned => |aligned| try w.print("aligned__{d}_{f}_{d}", .{
719 aligned.alignment.toByteUnits().?,
720 fmtZigType(aligned.ty, zcu),
721 aligned.ty.toIntern(),
722 }),
723 .bigint => |bigint| try w.print("struct int_{d}x{d}", .{
724 bigint.limb_size.bits(),
725 bigint.limbs_len,
726 }),
727
728 .pointer => |ptr| {
729 try ptr.elem_ty.writeTypePrefix(w, zcu);
730 switch (ptr.elem_ty.kind()) {
731 .pointer, .postfix_op => {},
732 .specifier => {
733 // We want "foo *" or "foo const *" rather than "foo*" or "fooconst *".
734 try w.writeByte(' ');
735 },
736 }
737 if (ptr.@"const") try w.writeAll("const ");
738 if (ptr.@"volatile") try w.writeAll("volatile ");
739 switch (ptr.elem_ty.kind()) {
740 .specifier, .pointer => {},
741 .postfix_op => {
742 // Prefix "*" is lower precedence than postfix "(x)" or "[x]" so use parens
743 // to disambiguate; e.g. "void (*foo)(int)" instead of "void *foo(int)".
744 try w.writeByte('(');
745 },
746 }
747 try w.writeByte('*');
748 },
749
750 .array => |array| {
751 try array.elem_ty.writeTypePrefix(w, zcu);
752 switch (array.elem_ty.kind()) {
753 .pointer, .postfix_op => {},
754 .specifier => {
755 // We want e.g. "struct foo [5]" rather than "struct foo[5]".
756 try w.writeByte(' ');
757 },
758 }
759 },
760
761 .function => |function| {
762 try function.ret_ty.writeTypePrefix(w, zcu);
763 switch (function.ret_ty.kind()) {
764 .pointer, .postfix_op => {},
765 .specifier => {
766 // We want e.g. "struct foo (void)" rather than "struct foo(void)".
767 try w.writeByte(' ');
768 },
769 }
770 },
771 }
772 }
773 fn writeTypeSuffix(cty: CType, w: *Writer, zcu: *const Zcu) Writer.Error!void {
774 switch (cty) {
775 // simple type specifiers
776 .void,
777 .bool,
778 .int,
779 .float,
780 .@"fn",
781 .@"enum",
782 .bitpack,
783 .@"struct",
784 .union_auto,
785 .union_extern,
786 .slice,
787 .opt,
788 .arr,
789 .vec,
790 .errunion,
791 .aligned,
792 .bigint,
793 => {},
794
795 .pointer => |ptr| {
796 // Match opening paren "(" write `writeTypePrefix`.
797 switch (ptr.elem_ty.kind()) {
798 .specifier, .pointer => {},
799 .postfix_op => try w.writeByte(')'),
800 }
801 try ptr.elem_ty.writeTypeSuffix(w, zcu);
802 },
803
804 .array => |array| {
805 try w.print("[{d}]", .{array.len});
806 try array.elem_ty.writeTypeSuffix(w, zcu);
807 },
808
809 .function => |function| {
810 if (function.param_tys.len == 0 and !function.varargs) {
811 try w.writeAll("(void)");
812 } else {
813 try w.writeByte('(');
814 for (function.param_tys, 0..) |param_ty, param_index| {
815 if (param_index > 0) try w.writeAll(", ");
816 try param_ty.writeTypePrefix(w, zcu);
817 try param_ty.writeTypeSuffix(w, zcu);
818 }
819 if (function.varargs) {
820 if (function.param_tys.len > 0) try w.writeAll(", ");
821 try w.writeAll("...");
822 }
823 try w.writeByte(')');
824 }
825 try function.ret_ty.writeTypeSuffix(w, zcu);
826 },
827 }
828 }
829
830 /// Renders Zig types using only bytes allowed in C identifiers in a somewhat-understandable
831 /// way. The output is *not* guaranteed to be unique.
832 fn fmtZigType(ty: Type, zcu: *const Zcu) FormatZigType {
833 return .{ .ty = ty, .zcu = zcu };
834 }
835 const FormatZigType = struct {
836 ty: Type,
837 zcu: *const Zcu,
838 pub fn format(ctx: FormatZigType, w: *Writer) Writer.Error!void {
839 const ty = ctx.ty;
840 const zcu = ctx.zcu;
841 const ip = &zcu.intern_pool;
842 switch (ty.zigTypeTag(zcu)) {
843 .frame => unreachable,
844 .@"anyframe" => unreachable,
845
846 .type => try w.writeAll("type"),
847 .void => try w.writeAll("void"),
848 .bool => try w.writeAll("bool"),
849 .noreturn => try w.writeAll("noreturn"),
850 .comptime_int => try w.writeAll("comptime_int"),
851 .comptime_float => try w.writeAll("comptime_float"),
852 .enum_literal => try w.writeAll("enum_literal"),
853 .undefined => try w.writeAll("undefined"),
854 .null => try w.writeAll("null"),
855
856 .int => switch (ty.toIntern()) {
857 .usize_type => try w.writeAll("usize"),
858 .isize_type => try w.writeAll("isize"),
859 .c_char_type => try w.writeAll("c_char"),
860 .c_short_type => try w.writeAll("c_short"),
861 .c_ushort_type => try w.writeAll("c_ushort"),
862 .c_int_type => try w.writeAll("c_int"),
863 .c_uint_type => try w.writeAll("c_uint"),
864 .c_long_type => try w.writeAll("c_long"),
865 .c_ulong_type => try w.writeAll("c_ulong"),
866 .c_longlong_type => try w.writeAll("c_longlong"),
867 .c_ulonglong_type => try w.writeAll("c_ulonglong"),
868 else => {
869 const info = ty.intInfo(zcu);
870 switch (info.signedness) {
871 .unsigned => try w.print("u{d}", .{info.bits}),
872 .signed => try w.print("i{d}", .{info.bits}),
873 }
874 },
875 },
876 .float => switch (ty.toIntern()) {
877 .c_longdouble_type => try w.writeAll("c_longdouble"),
878 .f16_type => try w.writeAll("f16"),
879 .f32_type => try w.writeAll("f32"),
880 .f64_type => try w.writeAll("f64"),
881 .f80_type => try w.writeAll("f80"),
882 .f128_type => try w.writeAll("f128"),
883 else => unreachable,
884 },
885 .error_set => switch (ty.toIntern()) {
886 .anyerror_type => try w.writeAll("anyerror"),
887 else => try w.print("error_{d}", .{@intFromEnum(ty.toIntern())}),
888 },
889 .optional => try w.print("opt_{f}", .{fmtZigType(ty.optionalChild(zcu), zcu)}),
890 .error_union => try w.print("errunion_{f}", .{fmtZigType(ty.errorUnionPayload(zcu), zcu)}),
891
892 .pointer => switch (ty.ptrSize(zcu)) {
893 .one, .many, .c => try w.print("ptr_{f}", .{fmtZigType(ty.childType(zcu), zcu)}),
894 .slice => try w.print("slice_{f}", .{fmtZigType(ty.childType(zcu), zcu)}),
895 },
896 .@"fn" => {
897 const func_type = ip.indexToKey(ty.toIntern()).func_type;
898 try w.writeAll("fn_"); // intentional double underscore to start
899 for (func_type.param_types.get(ip)) |param_ty_ip| {
900 const param_ty: Type = .fromInterned(param_ty_ip);
901 if (param_ty.isGenericPoison()) {
902 try w.writeAll("_Pgeneric");
903 } else {
904 try w.print("_P{f}", .{fmtZigType(param_ty, zcu)});
905 }
906 }
907 if (func_type.is_var_args) {
908 try w.writeAll("_VA");
909 }
910 const ret_ty: Type = .fromInterned(func_type.return_type);
911 if (ret_ty.isGenericPoison()) {
912 try w.writeAll("_Rgeneric");
913 } else if (ret_ty.zigTypeTag(zcu) == .error_union and ret_ty.errorUnionPayload(zcu).isGenericPoison()) {
914 try w.writeAll("_Rgeneric_ies");
915 } else {
916 try w.print("_R{f}", .{fmtZigType(ret_ty, zcu)});
917 }
918 },
919
920 .vector => try w.print("vec_{d}_{f}", .{
921 ty.arrayLen(zcu),
922 fmtZigType(ty.childType(zcu), zcu),
923 }),
924
925 .array => if (ty.sentinel(zcu)) |s| try w.print("arr_{d}s{d}_{f}", .{
926 ty.arrayLen(zcu),
927 @intFromEnum(s.toIntern()),
928 fmtZigType(ty.childType(zcu), zcu),
929 }) else try w.print("arr_{d}_{f}", .{
930 ty.arrayLen(zcu),
931 fmtZigType(ty.childType(zcu), zcu),
932 }),
933
934 .@"struct" => if (ty.isTuple(zcu)) {
935 const len = ty.structFieldCount(zcu);
936 try w.print("tuple_{d}", .{len});
937 for (0..len) |field_index| {
938 const field_ty = ty.fieldType(field_index, zcu);
939 try w.print("_{f}", .{fmtZigType(field_ty, zcu)});
940 }
941 } else {
942 const name = ty.containerTypeName(ip).toSlice(ip);
943 try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)});
944 },
945 .@"opaque" => if (ty.toIntern() == .anyopaque_type) {
946 try w.writeAll("anyopaque");
947 } else {
948 const name = ty.containerTypeName(ip).toSlice(ip);
949 try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)});
950 },
951 .@"union", .@"enum" => {
952 const name = ty.containerTypeName(ip).toSlice(ip);
953 try w.print("{f}", .{@import("../c.zig").fmtIdentUnsolo(name)});
954 },
955 }
956 }
957 };
958
959 /// Returns `true` if the layout of `ty` is known without any type resolution required. This
960 /// allows some types to be lowered directly where 'typedef' would otherwise be necessary.
961 fn alwaysHasLayout(ty: Type, ip: *const InternPool) bool {
962 return switch (ip.indexToKey(ty.toIntern())) {
963 .int_type,
964 .ptr_type,
965 .anyframe_type,
966 .simple_type,
967 .opaque_type,
968 .error_set_type,
969 .inferred_error_set_type,
970 => true,
971
972 .struct_type,
973 .union_type,
974 .enum_type,
975 => false,
976
977 .array_type => |arr| alwaysHasLayout(.fromInterned(arr.child), ip),
978 .vector_type => |vec| alwaysHasLayout(.fromInterned(vec.child), ip),
979 .opt_type => |child| alwaysHasLayout(.fromInterned(child), ip),
980 .error_union_type => |eu| alwaysHasLayout(.fromInterned(eu.payload_type), ip),
981
982 .tuple_type => |tuple| for (tuple.types.get(ip)) |field_ty| {
983 if (!alwaysHasLayout(.fromInterned(field_ty), ip)) break false;
984 } else true,
985
986 .func_type => |f| for (f.param_types.get(ip)) |param_ty| {
987 if (!alwaysHasLayout(.fromInterned(param_ty), ip)) break false;
988 } else alwaysHasLayout(.fromInterned(f.return_type), ip),
989
990 // values, not types
991 .undef,
992 .simple_value,
993 .variable,
994 .@"extern",
995 .func,
996 .int,
997 .err,
998 .error_union,
999 .enum_literal,
1000 .enum_tag,
1001 .float,
1002 .ptr,
1003 .slice,
1004 .opt,
1005 .aggregate,
1006 .un,
1007 .bitpack,
1008 // memoization, not types
1009 .memoized_call,
1010 => unreachable,
1011 };
1012 }
1013};
1014
1015const Zcu = @import("../../Zcu.zig");
1016const Type = @import("../../Type.zig");
1017const Value = @import("../../Value.zig");
1018const InternPool = @import("../../InternPool.zig");
1019
1020const std = @import("std");
1021const assert = std.debug.assert;
1022const Allocator = std.mem.Allocator;
1023const Writer = std.Io.Writer;
src/codegen/c/type/render_defs.zig created+710
......@@ -0,0 +1,710 @@
1/// Renders the `typedef` for an aligned type.
2pub fn defineAligned(
3 ty: Type,
4 alignment: Alignment,
5 complete: bool,
6 deps: *CType.Dependencies,
7 arena: Allocator,
8 w: *Writer,
9 pt: Zcu.PerThread,
10) (Allocator.Error || Writer.Error)!void {
11 const zcu = pt.zcu;
12
13 const name_cty: CType = .{ .aligned = .{
14 .ty = ty,
15 .alignment = alignment,
16 } };
17
18 const cty: CType = try .lower(ty, deps, arena, zcu);
19
20 try w.writeAll("typedef ");
21 if (complete and alignment.compareStrict(.lt, ty.abiAlignment(zcu))) {
22 try w.print("zig_under_align({d}) ", .{alignment.toByteUnits().?});
23 }
24 try w.print("{f}{f}{f}; /* align({d}) {f} */\n", .{
25 cty.fmtDeclaratorPrefix(zcu),
26 name_cty.fmtTypeName(zcu),
27 cty.fmtDeclaratorSuffix(zcu),
28 alignment.toByteUnits().?,
29 ty.fmt(pt),
30 });
31}
32/// Renders the definition of a big-int `struct`.
33pub fn defineBigInt(big: CType.BigInt, w: *Writer, zcu: *const Zcu) Writer.Error!void {
34 const name_cty: CType = .{ .bigint = .{
35 .limb_size = big.limb_size,
36 .limbs_len = big.limbs_len,
37 } };
38 const limb_cty: CType = .{ .int = big.limb_size.unsigned() };
39 const array_cty: CType = .{ .array = .{
40 .len = big.limbs_len,
41 .elem_ty = &limb_cty,
42 .nonstring = limb_cty.isStringElem(),
43 } };
44 try w.print("{f} {{ {f}limbs{f}; }}; /* {d} bits */\n", .{
45 name_cty.fmtTypeName(zcu),
46 array_cty.fmtDeclaratorPrefix(zcu),
47 array_cty.fmtDeclaratorSuffix(zcu),
48 big.limb_size.bits() * @as(u17, big.limbs_len),
49 });
50}
51
52/// Renders a forward declaration of the `struct` which represents an error union whose payload type
53/// is `payload_ty` (the error set type is unspecified).
54pub fn errunionFwdDecl(payload_ty: Type, w: *Writer, zcu: *const Zcu) Writer.Error!void {
55 const name_cty: CType = .{ .errunion = .{
56 .payload_ty = payload_ty,
57 } };
58 try w.print("{f};\n", .{name_cty.fmtTypeName(zcu)});
59}
60/// Renders the definition of the `struct` which represents an error union whose payload type is
61/// `payload_ty` (the error set type is unspecified).
62///
63/// Asserts that the layout of `payload_ty` is resolved.
64pub fn errunionDefineComplete(
65 payload_ty: Type,
66 deps: *CType.Dependencies,
67 arena: Allocator,
68 w: *Writer,
69 pt: Zcu.PerThread,
70) (Allocator.Error || Writer.Error)!void {
71 const zcu = pt.zcu;
72
73 payload_ty.assertHasLayout(zcu);
74
75 const name_cty: CType = .{ .errunion = .{
76 .payload_ty = payload_ty,
77 } };
78
79 const error_cty: CType = try .lower(.anyerror, deps, arena, zcu);
80
81 if (payload_ty.hasRuntimeBits(zcu)) {
82 const payload_cty: CType = try .lower(payload_ty, deps, arena, zcu);
83 try w.print(
84 \\{f} {{ /* anyerror!{f} */
85 \\ {f}payload{f};
86 \\ {f}error{f};
87 \\}};
88 \\
89 , .{
90 name_cty.fmtTypeName(zcu),
91 payload_ty.fmt(pt),
92 payload_cty.fmtDeclaratorPrefix(zcu),
93 payload_cty.fmtDeclaratorSuffix(zcu),
94 error_cty.fmtDeclaratorPrefix(zcu),
95 error_cty.fmtDeclaratorSuffix(zcu),
96 });
97 } else {
98 try w.print("{f} {{ {f}error{f}; }}; /* anyerror!{f} */\n", .{
99 name_cty.fmtTypeName(zcu),
100 error_cty.fmtDeclaratorPrefix(zcu),
101 error_cty.fmtDeclaratorSuffix(zcu),
102 payload_ty.fmt(pt),
103 });
104 }
105}
106
107/// If the Zig type `ty` lowers to a `struct` or `union` type, renders a forward declaration of that
108/// type. Does not write anything for error union types, because their forward declarations are
109/// instead rendered by `errunionFwdDecl`.
110pub fn fwdDecl(ty: Type, w: *Writer, zcu: *const Zcu) Writer.Error!void {
111 const name_cty: CType = switch (ty.zigTypeTag(zcu)) {
112 .@"struct" => switch (ty.containerLayout(zcu)) {
113 .auto, .@"extern" => .{ .@"struct" = ty },
114 .@"packed" => return,
115 },
116 .@"union" => switch (ty.containerLayout(zcu)) {
117 .auto => .{ .union_auto = ty },
118 .@"extern" => .{ .union_extern = ty },
119 .@"packed" => return,
120 },
121 .pointer => if (ty.isSlice(zcu)) .{ .slice = ty } else return,
122 .optional => .{ .opt = ty },
123 .array => .{ .arr = ty },
124 .vector => .{ .vec = ty },
125 else => return,
126 };
127 try w.print("{f};\n", .{name_cty.fmtTypeName(zcu)});
128}
129
130/// If the Zig type `ty` lowers to a `typedef`, renders a typedef of that type to `void`, because
131/// the type's layout is not resolved. This is only necessary for `typedef`s because a `struct` or
132/// `union` which is never defined is already an incomplete type, just like `void`.
133pub fn defineIncomplete(ty: Type, w: *Writer, pt: Zcu.PerThread) Writer.Error!void {
134 const zcu = pt.zcu;
135 const name_cty: CType = switch (ty.zigTypeTag(zcu)) {
136 .@"fn" => .{ .@"fn" = ty },
137 .@"enum" => .{ .@"enum" = ty },
138 .@"struct", .@"union" => switch (ty.containerLayout(zcu)) {
139 .auto, .@"extern" => return,
140 .@"packed" => .{ .bitpack = ty },
141 },
142 else => return,
143 };
144 try w.print("typedef void {f}; /* {f} */\n", .{
145 name_cty.fmtTypeName(zcu),
146 ty.fmt(pt),
147 });
148}
149
150/// If the Zig type `ty` lowers to a `struct` or `union` type, or to a `typedef`, renders the
151/// definition of that type. Does not write anything for error union types, because their
152/// definitions are instead rendered by `errunionDefine`.
153///
154/// Asserts that the layout of `ty` is resolved.
155pub fn defineComplete(
156 ty: Type,
157 deps: *CType.Dependencies,
158 arena: Allocator,
159 w: *Writer,
160 pt: Zcu.PerThread,
161) (Allocator.Error || Writer.Error)!void {
162 const zcu = pt.zcu;
163
164 ty.assertHasLayout(zcu);
165
166 switch (ty.zigTypeTag(zcu)) {
167 .@"fn" => if (!ty.fnHasRuntimeBits(zcu)) {
168 const name_cty: CType = .{ .@"fn" = ty };
169 try w.print("typedef void {f}; /* {f} */\n", .{
170 name_cty.fmtTypeName(zcu),
171 ty.fmt(pt),
172 });
173 } else {
174 const ip = &zcu.intern_pool;
175 const func_type = ip.indexToKey(ty.toIntern()).func_type;
176
177 // While incomplete types are usually an acceptable substitute for "void", this is not
178 // true in function return types, where "void" is the only incomplete type permitted.
179 const actual_ret_ty: Type = .fromInterned(func_type.return_type);
180 const effective_ret_ty: Type = switch (actual_ret_ty.classify(zcu)) {
181 .no_possible_value => .noreturn,
182 .one_possible_value, .fully_comptime => .void, // no runtime bits
183 .partially_comptime, .runtime => actual_ret_ty, // yes runtime bits
184 };
185
186 const name_cty: CType = .{ .@"fn" = ty };
187 const ret_cty: CType = try .lower(effective_ret_ty, deps, arena, zcu);
188
189 try w.print("typedef {f}{f}(", .{
190 ret_cty.fmtDeclaratorPrefix(zcu),
191 name_cty.fmtTypeName(zcu),
192 });
193 var any_params = false;
194 for (func_type.param_types.get(ip)) |param_ty_ip| {
195 const param_ty: Type = .fromInterned(param_ty_ip);
196 if (!param_ty.hasRuntimeBits(zcu)) continue;
197 if (any_params) try w.writeAll(", ");
198 any_params = true;
199 const param_cty: CType = try .lower(param_ty, deps, arena, zcu);
200 try w.print("{f}", .{param_cty.fmtTypeName(zcu)});
201 }
202 if (func_type.is_var_args) {
203 if (any_params) try w.writeAll(", ");
204 try w.writeAll("...");
205 } else if (!any_params) {
206 try w.writeAll("void");
207 }
208 try w.print("){f}; /* {f} */\n", .{
209 ret_cty.fmtDeclaratorSuffixIgnoreNonstring(zcu),
210 ty.fmt(pt),
211 });
212 },
213 .@"enum" => {
214 const name_cty: CType = .{ .@"enum" = ty };
215 const cty: CType = try .lower(ty.intTagType(zcu), deps, arena, zcu);
216 try w.print("typedef {f}{f}{f}; /* {f} */\n", .{
217 cty.fmtDeclaratorPrefix(zcu),
218 name_cty.fmtTypeName(zcu),
219 cty.fmtDeclaratorSuffix(zcu),
220 ty.fmt(pt),
221 });
222 },
223 .@"struct" => if (ty.isTuple(zcu)) {
224 try defineTuple(ty, deps, arena, w, pt);
225 } else switch (ty.containerLayout(zcu)) {
226 .auto, .@"extern" => try defineStruct(ty, deps, arena, w, pt),
227 .@"packed" => try defineBitpack(ty, deps, arena, w, pt),
228 },
229 .@"union" => switch (ty.containerLayout(zcu)) {
230 .auto => try defineUnionAuto(ty, deps, arena, w, pt),
231 .@"extern" => try defineUnionExtern(ty, deps, arena, w, pt),
232 .@"packed" => try defineBitpack(ty, deps, arena, w, pt),
233 },
234 .pointer => if (ty.isSlice(zcu)) {
235 const name_cty: CType = .{ .slice = ty };
236 const ptr_cty: CType = try .lower(ty.slicePtrFieldType(zcu), deps, arena, zcu);
237 try w.print(
238 \\{f} {{ /* {f} */
239 \\ {f}ptr{f};
240 \\ size_t len;
241 \\}};
242 \\
243 , .{
244 name_cty.fmtTypeName(zcu),
245 ty.fmt(pt),
246 ptr_cty.fmtDeclaratorPrefix(zcu),
247 ptr_cty.fmtDeclaratorSuffix(zcu),
248 });
249 // Don't bother with `writeStaticAssertLayout`---there's not really any way we could mess
250 // slices up, and they're all obviously the same layout.
251 },
252 .optional => switch (CType.classifyOptional(ty, zcu)) {
253 .error_set,
254 .ptr_like,
255 .slice_like,
256 .npv_payload,
257 => {},
258
259 .opv_payload => {
260 const name_cty: CType = .{ .opt = ty };
261 try w.print("{f} {{ bool is_null; }}; /* {f} */\n", .{
262 name_cty.fmtTypeName(zcu),
263 ty.fmt(pt),
264 });
265 try writeStaticAssertLayout(ty, name_cty, w, zcu);
266 },
267
268 .@"struct" => {
269 const name_cty: CType = .{ .opt = ty };
270 const payload_cty: CType = try .lower(ty.optionalChild(zcu), deps, arena, zcu);
271 try w.print(
272 \\{f} {{ /* {f} */
273 \\ {f}payload{f};
274 \\ bool is_null;
275 \\}};
276 \\
277 , .{
278 name_cty.fmtTypeName(zcu),
279 ty.fmt(pt),
280 payload_cty.fmtDeclaratorPrefix(zcu),
281 payload_cty.fmtDeclaratorSuffix(zcu),
282 });
283 try writeStaticAssertLayout(ty, name_cty, w, zcu);
284 },
285 },
286 .array => if (ty.hasRuntimeBits(zcu)) {
287 const name_cty: CType = .{ .arr = ty };
288 const elem_cty: CType = try .lower(ty.childType(zcu), deps, arena, zcu);
289 const array_cty: CType = .{ .array = .{
290 .len = ty.arrayLenIncludingSentinel(zcu),
291 .elem_ty = &elem_cty,
292 .nonstring = nonstring: {
293 if (!elem_cty.isStringElem()) break :nonstring false;
294 const s = ty.sentinel(zcu) orelse break :nonstring true;
295 break :nonstring Value.compareHetero(s, .neq, .zero_comptime_int, zcu);
296 },
297 } };
298 try w.print("{f} {{ {f}array{f}; }}; /* {f} */\n", .{
299 name_cty.fmtTypeName(zcu),
300 array_cty.fmtDeclaratorPrefix(zcu),
301 array_cty.fmtDeclaratorSuffix(zcu),
302 ty.fmt(pt),
303 });
304 try writeStaticAssertLayout(ty, name_cty, w, zcu);
305 },
306 .vector => if (ty.hasRuntimeBits(zcu)) {
307 const name_cty: CType = .{ .vec = ty };
308 const elem_cty: CType = try .lower(ty.childType(zcu), deps, arena, zcu);
309 const array_cty: CType = .{ .array = .{
310 .len = ty.arrayLenIncludingSentinel(zcu),
311 .elem_ty = &elem_cty,
312 .nonstring = elem_cty.isStringElem(),
313 } };
314 try w.print("{f} {{ {f}array{f}; }}; /* {f} */\n", .{
315 name_cty.fmtTypeName(zcu),
316 array_cty.fmtDeclaratorPrefix(zcu),
317 array_cty.fmtDeclaratorSuffix(zcu),
318 ty.fmt(pt),
319 });
320 try writeStaticAssertLayout(ty, name_cty, w, zcu);
321 },
322 else => {},
323 }
324}
325fn defineBitpack(
326 ty: Type,
327 deps: *CType.Dependencies,
328 arena: Allocator,
329 w: *Writer,
330 pt: Zcu.PerThread,
331) (Allocator.Error || Writer.Error)!void {
332 const zcu = pt.zcu;
333 const name_cty: CType = .{ .bitpack = ty };
334 const cty: CType = try .lower(ty.bitpackBackingInt(zcu), deps, arena, zcu);
335 try w.print("typedef {f}{f}{f}; /* {f} */\n", .{
336 cty.fmtDeclaratorPrefix(zcu),
337 name_cty.fmtTypeName(zcu),
338 cty.fmtDeclaratorSuffix(zcu),
339 ty.fmt(pt),
340 });
341}
342fn defineTuple(
343 ty: Type,
344 deps: *CType.Dependencies,
345 arena: Allocator,
346 w: *Writer,
347 pt: Zcu.PerThread,
348) (Allocator.Error || Writer.Error)!void {
349 const zcu = pt.zcu;
350 if (!ty.hasRuntimeBits(zcu)) return;
351 const ip = &zcu.intern_pool;
352 const tuple = ip.indexToKey(ty.toIntern()).tuple_type;
353
354 // Fields cannot be underaligned, because tuple fields cannot have specified alignments.
355 // However, overaligned fields are possible thanks to intermediate zero-bit fields.
356
357 const tuple_align = ty.abiAlignment(zcu);
358
359 // If the alignment of other fields would not give the tuple sufficient alignment, we
360 // need to align the first field (which does not affect its offset, because 0 is always
361 // well-aligned) to indirectly specify the tuple alignment.
362 const overalign: bool = for (tuple.types.get(ip)) |field_ty_ip| {
363 const field_ty: Type = .fromInterned(field_ty_ip);
364 if (!field_ty.hasRuntimeBits(zcu)) continue;
365 const natural_align = field_ty.defaultStructFieldAlignment(.auto, zcu);
366 if (natural_align.compareStrict(.gte, tuple_align)) break false;
367 } else true;
368
369 const name_cty: CType = .{ .@"struct" = ty };
370 try w.print("{f} {{ /* {f} */\n", .{
371 name_cty.fmtTypeName(zcu),
372 ty.fmt(pt),
373 });
374 var zig_offset: u64 = 0;
375 var c_offset: u64 = 0;
376 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty_ip, field_val_ip, field_index| {
377 if (field_val_ip != .none) continue; // `comptime` field
378 const field_ty: Type = .fromInterned(field_ty_ip);
379 const field_align = field_ty.abiAlignment(zcu);
380 zig_offset = field_align.forward(zig_offset);
381 if (!field_ty.hasRuntimeBits(zcu)) continue;
382 c_offset = field_align.forward(c_offset);
383 try w.writeByte(' ');
384 if (zig_offset == 0 and overalign) {
385 // This is the first field; specify its alignment to align the tuple.
386 try writeFieldAlign(field_ty, tuple_align, w, zcu);
387 } else if (zig_offset > c_offset) {
388 // This field needs to be overaligned compared to what its offset would otherwise be.
389 const need_align: Alignment = .minStrict(
390 tuple_align, // don't make the struct more aligned than it should be
391 .fromLog2Units(@ctz(zig_offset)),
392 );
393 try writeFieldAlign(field_ty, need_align, w, zcu);
394 c_offset = need_align.forward(c_offset);
395 }
396 const field_cty: CType = try .lower(field_ty, deps, arena, zcu);
397 try w.print("{f}f{d}{f};\n", .{
398 field_cty.fmtDeclaratorPrefix(zcu),
399 field_index,
400 field_cty.fmtDeclaratorSuffix(zcu),
401 });
402 const field_size = field_ty.abiSize(zcu);
403 zig_offset += field_size;
404 c_offset += field_size;
405 }
406 try w.writeAll("};\n");
407
408 try writeStaticAssertLayout(ty, name_cty, w, zcu);
409}
410fn defineStruct(
411 ty: Type,
412 deps: *CType.Dependencies,
413 arena: Allocator,
414 w: *Writer,
415 pt: Zcu.PerThread,
416) (Allocator.Error || Writer.Error)!void {
417 const zcu = pt.zcu;
418 if (!ty.hasRuntimeBits(zcu)) return;
419 const ip = &zcu.intern_pool;
420
421 const struct_type = ip.loadStructType(ty.toIntern());
422
423 // If there are any underaligned fields, we need to byte-pack the struct.
424 const pack: bool = pack: {
425 var it = struct_type.iterateRuntimeOrder(ip);
426 var offset: u64 = 0;
427 while (it.next()) |field_index| {
428 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
429 if (!field_ty.hasRuntimeBits(zcu)) continue;
430 const natural_align = field_ty.defaultStructFieldAlignment(struct_type.layout, zcu);
431 const natural_offset = natural_align.forward(offset);
432 const actual_offset = struct_type.field_offsets.get(ip)[field_index];
433 if (actual_offset < natural_offset) break :pack true;
434 // Also pack if any field is more aligned than the struct should be.
435 if (natural_align.compareStrict(.gt, struct_type.alignment)) break :pack true;
436 offset = actual_offset + field_ty.abiSize(zcu);
437 }
438 break :pack false;
439 };
440
441 // If the alignment of other fields would not give the struct sufficient alignment, we
442 // need to align the first field (which does not affect its offset, because 0 is always
443 // well-aligned) to indirectly specify the struct alignment.
444 const overalign: bool = switch (pack) {
445 true => struct_type.alignment.compareStrict(.gt, .@"1"),
446 false => overalign: {
447 var it = struct_type.iterateRuntimeOrder(ip);
448 while (it.next()) |field_index| {
449 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
450 if (!field_ty.hasRuntimeBits(zcu)) continue;
451 const natural_align = field_ty.defaultStructFieldAlignment(struct_type.layout, zcu);
452 if (natural_align.compareStrict(.gte, struct_type.alignment)) break :overalign false;
453 }
454 break :overalign true;
455 },
456 };
457
458 if (pack) try w.writeAll("zig_packed(");
459 const name_cty: CType = .{ .@"struct" = ty };
460 try w.print("{f} {{ /* {f} */\n", .{
461 name_cty.fmtTypeName(zcu),
462 ty.fmt(pt),
463 });
464 var it = struct_type.iterateRuntimeOrder(ip);
465 var offset: u64 = 0;
466 while (it.next()) |field_index| {
467 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
468 if (!field_ty.hasRuntimeBits(zcu)) continue;
469 const natural_align = field_ty.defaultStructFieldAlignment(struct_type.layout, zcu);
470 const natural_offset = switch (pack) {
471 true => offset,
472 false => natural_align.forward(offset),
473 };
474 const actual_offset = struct_type.field_offsets.get(ip)[field_index];
475 try w.writeByte(' ');
476 if (actual_offset == 0 and overalign) {
477 // This is the first field; specify its alignment to align the struct.
478 try writeFieldAlign(field_ty, struct_type.alignment, w, zcu);
479 } else if (actual_offset > natural_offset) {
480 // This field needs to be underaligned or overaligned compared to what its
481 // offset would otherwise be.
482 const need_align: Alignment = .minStrict(
483 struct_type.alignment, // don't make the struct more aligned than it should be
484 .fromLog2Units(@ctz(actual_offset)),
485 );
486 try writeFieldAlign(field_ty, need_align, w, zcu);
487 }
488 const field_cty: CType = try .lower(field_ty, deps, arena, zcu);
489 const field_name = struct_type.field_names.get(ip)[field_index].toSlice(ip);
490 try w.print("{f}{f}{f};\n", .{
491 field_cty.fmtDeclaratorPrefix(zcu),
492 fmtIdentSolo(field_name),
493 field_cty.fmtDeclaratorSuffix(zcu),
494 });
495 offset = actual_offset + field_ty.abiSize(zcu);
496 }
497 assert(struct_type.alignment.forward(offset) == struct_type.size);
498 try w.writeByte('}');
499 if (pack) try w.writeByte(')');
500 try w.writeAll(";\n");
501
502 try writeStaticAssertLayout(ty, name_cty, w, zcu);
503}
504fn defineUnionAuto(
505 ty: Type,
506 deps: *CType.Dependencies,
507 arena: Allocator,
508 w: *Writer,
509 pt: Zcu.PerThread,
510) (Allocator.Error || Writer.Error)!void {
511 const zcu = pt.zcu;
512 if (!ty.hasRuntimeBits(zcu)) return;
513 const ip = &zcu.intern_pool;
514
515 const union_type = ip.loadUnionType(ty.toIntern());
516 const enum_tag_ty: Type = .fromInterned(union_type.enum_tag_type);
517
518 const layout = Type.getUnionLayout(union_type, zcu);
519
520 // If there are any underaligned fields, we need to byte-pack the union.
521 const pack: bool = for (union_type.field_types.get(ip)) |field_ty_ip| {
522 const field_ty: Type = .fromInterned(field_ty_ip);
523 if (!field_ty.hasRuntimeBits(zcu)) continue;
524 const natural_align = field_ty.abiAlignment(zcu);
525 if (natural_align.compareStrict(.gt, union_type.alignment)) break true;
526 // The tag will immediately follow the payload. This layout may put the tag in what would
527 // otherwise be padding on the payload union, because if the most-aligned union field is not
528 // the largest one, a larger field may make the payload "underaligned" overall. As such, we
529 // need to check whether this field is okay with the payload size, and if not then we must
530 // byte-pack.
531 if (!natural_align.check(layout.payload_size)) break true;
532 } else false;
533
534 // If the alignment of other fields would not give the union sufficient alignment, we
535 // need to align the first field (which does not affect its offset, because 0 is always
536 // well-aligned) to indirectly specify the union alignment.
537 const overalign: bool = switch (pack) {
538 true => union_type.alignment.compareStrict(.gt, .@"1"),
539 false => for (union_type.field_types.get(ip)) |field_ty_ip| {
540 const field_ty: Type = .fromInterned(field_ty_ip);
541 if (!field_ty.hasRuntimeBits(zcu)) continue;
542 const natural_align = field_ty.abiAlignment(zcu);
543 if (natural_align.compareStrict(.gte, union_type.alignment)) break false;
544 } else overalign: {
545 if (union_type.has_runtime_tag) {
546 const tag_align = enum_tag_ty.abiAlignment(zcu);
547 if (tag_align.compareStrict(.gte, union_type.alignment)) break :overalign false;
548 }
549 break :overalign true;
550 },
551 };
552
553 const payload_has_bits = !union_type.has_runtime_tag or union_type.size > enum_tag_ty.abiSize(zcu);
554
555 const name_cty: CType = .{ .union_auto = ty };
556 try w.print("{f} {{ /* {f} */\n", .{
557 name_cty.fmtTypeName(zcu),
558 ty.fmt(pt),
559 });
560 if (payload_has_bits) {
561 try w.writeByte(' ');
562 if (overalign) {
563 // Specify the alignment of `union { ... } payload;` to align the union's `struct`.
564 try w.print("zig_align({d}) ", .{union_type.alignment.toByteUnits().?});
565 }
566 if (pack) try w.writeAll("zig_packed(");
567 try w.writeAll("union {\n");
568 for (0..enum_tag_ty.enumFieldCount(zcu)) |field_index| {
569 const field_ty = ty.fieldType(field_index, zcu);
570 if (!field_ty.hasRuntimeBits(zcu)) continue;
571 const field_name = enum_tag_ty.enumFieldName(field_index, zcu).toSlice(ip);
572 const field_cty: CType = try .lower(field_ty, deps, arena, zcu);
573 try w.print(" {f}{f}{f};\n", .{
574 field_cty.fmtDeclaratorPrefix(zcu),
575 fmtIdentSolo(field_name),
576 field_cty.fmtDeclaratorSuffix(zcu),
577 });
578 }
579 try w.writeAll(" }");
580 if (pack) try w.writeByte(')');
581 try w.writeAll(" payload;\n");
582 }
583 if (union_type.has_runtime_tag) {
584 const tag_cty: CType = try .lower(enum_tag_ty, deps, arena, zcu);
585 try w.print(" {f}tag{f};\n", .{
586 tag_cty.fmtDeclaratorPrefix(zcu),
587 tag_cty.fmtDeclaratorSuffix(zcu),
588 });
589 }
590 try w.writeAll("};\n");
591
592 try writeStaticAssertLayout(ty, name_cty, w, zcu);
593}
594fn defineUnionExtern(
595 ty: Type,
596 deps: *CType.Dependencies,
597 arena: Allocator,
598 w: *Writer,
599 pt: Zcu.PerThread,
600) (Allocator.Error || Writer.Error)!void {
601 const zcu = pt.zcu;
602 if (!ty.hasRuntimeBits(zcu)) return;
603 const ip = &zcu.intern_pool;
604
605 const union_type = ip.loadUnionType(ty.toIntern());
606 assert(!union_type.has_runtime_tag);
607 const enum_tag_ty: Type = .fromInterned(union_type.enum_tag_type);
608
609 // If there are any underaligned fields, we need to byte-pack the union.
610 const pack: bool = for (union_type.field_types.get(ip)) |field_ty_ip| {
611 const field_ty: Type = .fromInterned(field_ty_ip);
612 if (!field_ty.hasRuntimeBits(zcu)) continue;
613 const natural_align = field_ty.abiAlignment(zcu);
614 if (natural_align.compareStrict(.gt, union_type.alignment)) break true;
615 } else false;
616
617 // If the alignment of other fields would not give the union sufficient alignment, we
618 // need to align the first field (which does not affect its offset, because 0 is always
619 // well-aligned) to indirectly specify the union alignment.
620 const overalign: bool = switch (pack) {
621 true => union_type.alignment.compareStrict(.gt, .@"1"),
622 false => for (union_type.field_types.get(ip)) |field_ty_ip| {
623 const field_ty: Type = .fromInterned(field_ty_ip);
624 if (!field_ty.hasRuntimeBits(zcu)) continue;
625 const natural_align = field_ty.abiAlignment(zcu);
626 if (natural_align.compareStrict(.gte, union_type.alignment)) break false;
627 } else overalign: {
628 if (union_type.has_runtime_tag) {
629 const tag_align = enum_tag_ty.abiAlignment(zcu);
630 if (tag_align.compareStrict(.gte, union_type.alignment)) break :overalign false;
631 }
632 break :overalign true;
633 },
634 };
635
636 if (pack) try w.writeAll("zig_packed(");
637
638 const name_cty: CType = .{ .union_extern = ty };
639 try w.print("{f} {{ /* {f} */\n", .{
640 name_cty.fmtTypeName(zcu),
641 ty.fmt(pt),
642 });
643
644 for (0..enum_tag_ty.enumFieldCount(zcu)) |field_index| {
645 const field_ty = ty.fieldType(field_index, zcu);
646 if (!field_ty.hasRuntimeBits(zcu)) continue;
647 const field_name = enum_tag_ty.enumFieldName(field_index, zcu).toSlice(ip);
648 const field_cty: CType = try .lower(field_ty, deps, arena, zcu);
649 try w.writeByte(' ');
650 if (overalign and field_index == 0) {
651 // This is the first field; specify its alignment to align the union.
652 try writeFieldAlign(field_ty, union_type.alignment, w, zcu);
653 }
654 try w.print("{f}{f}{f};\n", .{
655 field_cty.fmtDeclaratorPrefix(zcu),
656 fmtIdentSolo(field_name),
657 field_cty.fmtDeclaratorSuffix(zcu),
658 });
659 }
660 try w.writeByte('}');
661 if (pack) try w.writeByte(')');
662 try w.writeAll(";\n");
663
664 try writeStaticAssertLayout(ty, name_cty, w, zcu);
665}
666
667/// Writes an annotation which, placed before a struct/union field declaration with field type `ty`,
668/// will specify that field as having the given alignment.
669fn writeFieldAlign(
670 ty: Type,
671 alignment: Alignment,
672 w: *Writer,
673 zcu: *const Zcu,
674) Writer.Error!void {
675 if (alignment.compareStrict(.lt, ty.abiAlignment(zcu))) {
676 try w.print("zig_under_align({d}) ", .{alignment.toByteUnits().?});
677 } else {
678 try w.print("zig_align({d}) ", .{alignment.toByteUnits().?});
679 }
680}
681
682/// Emits static assertions that the size and alignment of `cty` match those of the Zig type `ty`.
683fn writeStaticAssertLayout(
684 ty: Type,
685 cty: CType,
686 w: *Writer,
687 zcu: *const Zcu,
688) Writer.Error!void {
689 try w.print(
690 \\zig_static_assert(sizeof ({f}) == {d}, "incorrect size");
691 \\zig_static_assert(_Alignof ({f}) == {d}, "incorrect alignment");
692 \\
693 , .{
694 cty.fmtTypeName(zcu), ty.abiSize(zcu),
695 cty.fmtTypeName(zcu), ty.abiAlignment(zcu).toByteUnits().?,
696 });
697}
698
699const std = @import("std");
700const assert = std.debug.assert;
701const Writer = std.Io.Writer;
702const Allocator = std.mem.Allocator;
703
704const Zcu = @import("../../../Zcu.zig");
705const Type = @import("../../../Type.zig");
706const Value = @import("../../../Value.zig");
707const CType = @import("../type.zig").CType;
708const Alignment = @import("../../../InternPool.zig").Alignment;
709
710const fmtIdentSolo = @import("../../c.zig").fmtIdentSolo;
src/codegen/llvm.zig+916-1146
......@@ -520,6 +520,21 @@ pub const Object = struct {
520520 gpa: Allocator,
521521 builder: Builder,
522522
523 /// This pool contains only types (and not `@as(type, undefined)`). It has two purposes:
524 ///
525 /// * Lazily tracking ABI alignment of types, so that `@"align"` attributes can be set to a
526 /// type's ABI alignment before that type is fully resolved. Each type in the pool has a
527 /// corresponding entry in `lazy_abi_aligns`.
528 ///
529 /// * If `!Object.builder.strip`, lazily tracking debug information types, so that debug
530 /// information can handle indirect self-reference (and so that debug information works
531 /// correctly across incremental updates). Each type has a corresponding entry in
532 /// `debug_types`, provided that `Object.builder.strip` is `false`.
533 type_pool: link.ConstPool,
534
535 /// Keyed on `link.ConstPool.Index`.
536 lazy_abi_aligns: std.ArrayList(Builder.Alignment.Lazy),
537
523538 debug_compile_unit: Builder.Metadata.Optional,
524539
525540 debug_enums_fwd_ref: Builder.Metadata.Optional,
......@@ -529,9 +544,13 @@ pub const Object = struct {
529544 debug_globals: std.ArrayList(Builder.Metadata),
530545
531546 debug_file_map: std.AutoHashMapUnmanaged(Zcu.File.Index, Builder.Metadata),
532 debug_type_map: std.AutoHashMapUnmanaged(InternPool.Index, Builder.Metadata),
533547
534 debug_unresolved_namespace_scopes: std.AutoArrayHashMapUnmanaged(InternPool.NamespaceIndex, Builder.Metadata),
548 /// Keyed on `link.ConstPool.Index`.
549 debug_types: std.ArrayList(Builder.Metadata),
550 /// Initially `.none`, set if the type `anyerror` is lowered to a debug type. The type will not
551 /// actually be created until `emit`, which must resolve this reference with an appropriate enum
552 /// type from the global error set.
553 debug_anyerror_fwd_ref: Builder.Metadata.Optional,
535554
536555 target: *const std.Target,
537556 /// Ideally we would use `llvm_module.getNamedFunction` to go from *Decl to LLVM function,
......@@ -654,35 +673,38 @@ pub const Object = struct {
654673 obj.* = .{
655674 .gpa = gpa,
656675 .builder = builder,
676 .type_pool = .empty,
677 .lazy_abi_aligns = .empty,
657678 .debug_compile_unit = debug_compile_unit,
658679 .debug_enums_fwd_ref = debug_enums_fwd_ref,
659680 .debug_globals_fwd_ref = debug_globals_fwd_ref,
660 .debug_enums = .{},
661 .debug_globals = .{},
662 .debug_file_map = .{},
663 .debug_type_map = .{},
664 .debug_unresolved_namespace_scopes = .{},
681 .debug_enums = .empty,
682 .debug_globals = .empty,
683 .debug_file_map = .empty,
684 .debug_types = .empty,
685 .debug_anyerror_fwd_ref = .none,
665686 .target = target,
666 .nav_map = .{},
667 .uav_map = .{},
668 .enum_tag_name_map = .{},
669 .named_enum_map = .{},
670 .type_map = .{},
687 .nav_map = .empty,
688 .uav_map = .empty,
689 .enum_tag_name_map = .empty,
690 .named_enum_map = .empty,
691 .type_map = .empty,
671692 .error_name_table = .none,
672693 .null_opt_usize = .no_init,
673 .struct_field_map = .{},
674 .used = .{},
694 .struct_field_map = .empty,
695 .used = .empty,
675696 };
676697 return obj;
677698 }
678699
679700 pub fn deinit(self: *Object) void {
680701 const gpa = self.gpa;
702 self.type_pool.deinit(gpa);
703 self.lazy_abi_aligns.deinit(gpa);
681704 self.debug_enums.deinit(gpa);
682705 self.debug_globals.deinit(gpa);
683706 self.debug_file_map.deinit(gpa);
684 self.debug_type_map.deinit(gpa);
685 self.debug_unresolved_namespace_scopes.deinit(gpa);
707 self.debug_types.deinit(gpa);
686708 self.nav_map.deinit(gpa);
687709 self.uav_map.deinit(gpa);
688710 self.enum_tag_name_map.deinit(gpa);
......@@ -824,19 +846,13 @@ pub const Object = struct {
824846 }
825847
826848 if (!o.builder.strip) {
827 {
828 var i: usize = 0;
829 while (i < o.debug_unresolved_namespace_scopes.count()) : (i += 1) {
830 const namespace_index = o.debug_unresolved_namespace_scopes.keys()[i];
831 const fwd_ref = o.debug_unresolved_namespace_scopes.values()[i];
832
833 const namespace = zcu.namespacePtr(namespace_index);
834 const debug_type = try o.lowerDebugType(pt, Type.fromInterned(namespace.owner_type));
835
836 o.builder.resolveDebugForwardReference(fwd_ref, debug_type);
837 }
849 if (o.debug_anyerror_fwd_ref.unwrap()) |fwd_ref| {
850 const debug_anyerror_type = try o.lowerDebugAnyerrorType(pt);
851 o.builder.resolveDebugForwardReference(fwd_ref, debug_anyerror_type);
838852 }
839853
854 try o.flushTypePool(pt);
855
840856 o.builder.resolveDebugForwardReference(
841857 o.debug_enums_fwd_ref.unwrap().?,
842858 try o.builder.metadataTuple(o.debug_enums.items),
......@@ -1395,10 +1411,10 @@ pub const Object = struct {
13951411 if (ptr_info.flags.is_const) {
13961412 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);
13971413 }
1398 const elem_align = (if (ptr_info.flags.alignment != .none)
1399 @as(InternPool.Alignment, ptr_info.flags.alignment)
1400 else
1401 Type.fromInterned(ptr_info.child).abiAlignment(zcu).max(.@"1")).toLlvm();
1414 const elem_align: Builder.Alignment.Lazy = switch (ptr_info.flags.alignment) {
1415 else => |a| .wrap(a.toLlvm()),
1416 .none => try o.lazyAbiAlignment(pt, .fromInterned(ptr_info.child)),
1417 };
14021418 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);
14031419 const ptr_param = wip.arg(llvm_arg_i);
14041420 llvm_arg_i += 1;
......@@ -1472,7 +1488,7 @@ pub const Object = struct {
14721488
14731489 const line_number = zcu.navSrcLine(func.owner_nav) + 1;
14741490 const is_internal_linkage = ip.indexToKey(nav.status.fully_resolved.val) != .@"extern";
1475 const debug_decl_type = try o.lowerDebugType(pt, fn_ty);
1491 const debug_decl_type = try o.getDebugType(pt, fn_ty);
14761492
14771493 const subprogram = try o.builder.debugSubprogram(
14781494 file,
......@@ -1522,7 +1538,7 @@ pub const Object = struct {
15221538
15231539 break :f .{
15241540 .counters_variable = counters_variable,
1525 .pcs = .{},
1541 .pcs = .empty,
15261542 };
15271543 };
15281544
......@@ -1538,10 +1554,10 @@ pub const Object = struct {
15381554 .args = args.items,
15391555 .arg_index = 0,
15401556 .arg_inline_index = 0,
1541 .func_inst_table = .{},
1542 .blocks = .{},
1543 .loops = .{},
1544 .switch_dispatch_info = .{},
1557 .func_inst_table = .empty,
1558 .blocks = .empty,
1559 .loops = .empty,
1560 .switch_dispatch_info = .empty,
15451561 .sync_scope = if (owner_mod.single_threaded) .singlethread else .system,
15461562 .file = file,
15471563 .scope = subprogram,
......@@ -1599,6 +1615,7 @@ pub const Object = struct {
15991615 }
16001616
16011617 try fg.wip.finish();
1618 try o.flushTypePool(pt);
16021619 }
16031620
16041621 pub fn updateNav(self: *Object, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
......@@ -1615,6 +1632,11 @@ pub const Object = struct {
16151632 },
16161633 else => |e| return e,
16171634 };
1635 try self.flushTypePool(pt);
1636 }
1637
1638 fn flushTypePool(o: *Object, pt: Zcu.PerThread) Allocator.Error!void {
1639 try o.type_pool.flushPending(pt, .{ .llvm = o });
16181640 }
16191641
16201642 pub fn updateExports(
......@@ -1810,6 +1832,84 @@ pub const Object = struct {
18101832 }
18111833 }
18121834
1835 pub fn updateContainerType(o: *Object, pt: Zcu.PerThread, ty: InternPool.Index, success: bool) Allocator.Error!void {
1836 try o.type_pool.updateContainerType(pt, .{ .llvm = o }, ty, success);
1837 }
1838
1839 /// Should only be called by the `link.ConstPool` implementation.
1840 ///
1841 /// `val` is always a type because `o.type_pool` only contains types.
1842 pub fn addConst(o: *Object, pt: Zcu.PerThread, index: link.ConstPool.Index, val: InternPool.Index) Allocator.Error!void {
1843 const zcu = pt.zcu;
1844 const gpa = zcu.comp.gpa;
1845 assert(zcu.intern_pool.typeOf(val) == .type_type);
1846
1847 {
1848 assert(@intFromEnum(index) == o.lazy_abi_aligns.items.len);
1849 try o.lazy_abi_aligns.ensureUnusedCapacity(gpa, 1);
1850 const fwd_ref = try o.builder.alignmentForwardReference();
1851 o.lazy_abi_aligns.appendAssumeCapacity(fwd_ref);
1852 }
1853
1854 if (!o.builder.strip) {
1855 assert(@intFromEnum(index) == o.debug_types.items.len);
1856 try o.debug_types.ensureUnusedCapacity(gpa, 1);
1857 const fwd_ref = try o.builder.debugForwardReference();
1858 o.debug_types.appendAssumeCapacity(fwd_ref);
1859 if (val == .anyerror_type) {
1860 assert(o.debug_anyerror_fwd_ref.is_none);
1861 o.debug_anyerror_fwd_ref = fwd_ref.toOptional();
1862 }
1863 }
1864 }
1865 /// Should only be called by the `link.ConstPool` implementation.
1866 ///
1867 /// `val` is always a type because `o.type_pool` only contains types.
1868 pub fn updateConstIncomplete(o: *Object, pt: Zcu.PerThread, index: link.ConstPool.Index, val: InternPool.Index) Allocator.Error!void {
1869 const zcu = pt.zcu;
1870 assert(zcu.intern_pool.typeOf(val) == .type_type);
1871
1872 const ty: Type = .fromInterned(val);
1873
1874 {
1875 const fwd_ref = o.lazy_abi_aligns.items[@intFromEnum(index)];
1876 o.builder.resolveAlignmentForwardReference(fwd_ref, .fromByteUnits(1));
1877 }
1878
1879 if (!o.builder.strip) {
1880 assert(val != .anyerror_type);
1881 const fwd_ref = o.debug_types.items[@intFromEnum(index)];
1882 const name_str = try o.builder.metadataStringFmt("{f}", .{ty.fmt(pt)});
1883 const debug_incomplete_type = try o.builder.debugSignedType(name_str, 0);
1884 o.builder.resolveDebugForwardReference(fwd_ref, debug_incomplete_type);
1885 }
1886 }
1887 /// Should only be called by the `link.ConstPool` implementation.
1888 ///
1889 /// `val` is always a type because `o.type_pool` only contains types.
1890 pub fn updateConst(o: *Object, pt: Zcu.PerThread, index: link.ConstPool.Index, val: InternPool.Index) Allocator.Error!void {
1891 const zcu = pt.zcu;
1892 assert(zcu.intern_pool.typeOf(val) == .type_type);
1893
1894 const ty: Type = .fromInterned(val);
1895
1896 {
1897 const fwd_ref = o.lazy_abi_aligns.items[@intFromEnum(index)];
1898 o.builder.resolveAlignmentForwardReference(fwd_ref, ty.abiAlignment(zcu).toLlvm());
1899 }
1900
1901 if (!o.builder.strip) {
1902 const fwd_ref = o.debug_types.items[@intFromEnum(index)];
1903 if (val == .anyerror_type) {
1904 // Don't lower this now; it will be populated in `emit` instead.
1905 assert(o.debug_anyerror_fwd_ref == fwd_ref.toOptional());
1906 } else {
1907 const debug_type = try o.lowerDebugType(pt, ty, fwd_ref);
1908 o.builder.resolveDebugForwardReference(fwd_ref, debug_type);
1909 }
1910 }
1911 }
1912
18131913 fn getDebugFile(o: *Object, pt: Zcu.PerThread, file_index: Zcu.File.Index) Allocator.Error!Builder.Metadata {
18141914 const gpa = o.gpa;
18151915 const gop = try o.debug_file_map.getOrPut(gpa, file_index);
......@@ -1826,10 +1926,19 @@ pub const Object = struct {
18261926 return gop.value_ptr.*;
18271927 }
18281928
1829 pub fn lowerDebugType(
1929 fn getDebugType(o: *Object, pt: Zcu.PerThread, ty: Type) Allocator.Error!Builder.Metadata {
1930 assert(!o.builder.strip);
1931 const index = try o.type_pool.get(pt, .{ .llvm = o }, ty.toIntern());
1932 return o.debug_types.items[@intFromEnum(index)];
1933 }
1934
1935 /// In codegen logic, instead of calling this directly, use `getDebugType` to get a forward
1936 /// reference which will be populated only when all necessary type resolution is complete.
1937 fn lowerDebugType(
18301938 o: *Object,
18311939 pt: Zcu.PerThread,
18321940 ty: Type,
1941 ty_fwd_ref: Builder.Metadata,
18331942 ) Allocator.Error!Builder.Metadata {
18341943 assert(!o.builder.strip);
18351944
......@@ -1838,312 +1947,137 @@ pub const Object = struct {
18381947 const zcu = pt.zcu;
18391948 const ip = &zcu.intern_pool;
18401949
1841 if (o.debug_type_map.get(ty.toIntern())) |debug_type| return debug_type;
1950 const name = try o.builder.metadataStringFmt("{f}", .{ty.fmt(pt)});
1951
1952 // lldb cannot handle non-byte-sized types, so in the logic below, bit sizes are padded up.
1953 // For instance, `bool` is considered to be 8 bits, and `u60` is considered to be 64 bits.
1954
1955 // I tried using variants (DW_TAG_variant_part + DW_TAG_variant) to encode error unions,
1956 // tagged unions, etc; this would have told debuggers which field was active, which could
1957 // improve UX significantly. GDB handles this perfectly fine, but unfortunately, LLDB has no
1958 // handling for variants at all, and will never print fields in them, so I opted not to use
1959 // them for now.
18421960
18431961 switch (ty.zigTypeTag(zcu)) {
18441962 .void,
18451963 .noreturn,
1846 => {
1847 const debug_void_type = try o.builder.debugSignedType(
1848 try o.builder.metadataString("void"),
1849 0,
1850 );
1851 try o.debug_type_map.put(gpa, ty.toIntern(), debug_void_type);
1852 return debug_void_type;
1853 },
1964 .comptime_int,
1965 .comptime_float,
1966 .type,
1967 .undefined,
1968 .null,
1969 .enum_literal,
1970 => return o.builder.debugSignedType(name, 0),
1971
1972 .float => return o.builder.debugFloatType(name, ty.floatBits(target)),
1973
1974 .bool => return o.builder.debugBoolType(name, 8),
1975
18541976 .int => {
18551977 const info = ty.intInfo(zcu);
1856 assert(info.bits != 0);
1857 const name = try o.allocTypeName(pt, ty);
1858 defer gpa.free(name);
1859 const builder_name = try o.builder.metadataString(name);
1860 const debug_bits = ty.abiSize(zcu) * 8; // lldb cannot handle non-byte sized types
1861 const debug_int_type = switch (info.signedness) {
1862 .signed => try o.builder.debugSignedType(builder_name, debug_bits),
1863 .unsigned => try o.builder.debugUnsignedType(builder_name, debug_bits),
1978 const bits = ty.abiSize(zcu) * 8;
1979 return switch (info.signedness) {
1980 .signed => try o.builder.debugSignedType(name, bits),
1981 .unsigned => try o.builder.debugUnsignedType(name, bits),
18641982 };
1865 try o.debug_type_map.put(gpa, ty.toIntern(), debug_int_type);
1866 return debug_int_type;
18671983 },
1868 .@"enum" => {
1869 if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) {
1870 const debug_enum_type = try o.makeEmptyNamespaceDebugType(pt, ty);
1871 try o.debug_type_map.put(gpa, ty.toIntern(), debug_enum_type);
1872 return debug_enum_type;
1873 }
1874
1875 const enum_type = ip.loadEnumType(ty.toIntern());
1876 const enumerators = try gpa.alloc(Builder.Metadata, enum_type.names.len);
1877 defer gpa.free(enumerators);
1878
1879 const int_ty = Type.fromInterned(enum_type.tag_ty);
1880 const int_info = ty.intInfo(zcu);
1881 assert(int_info.bits != 0);
1882
1883 for (enum_type.names.get(ip), 0..) |field_name_ip, i| {
1884 var bigint_space: Value.BigIntSpace = undefined;
1885 const bigint = if (enum_type.values.len != 0)
1886 Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, zcu)
1887 else
1888 std.math.big.int.Mutable.init(&bigint_space.limbs, i).toConst();
1889
1890 enumerators[i] = try o.builder.debugEnumerator(
1891 try o.builder.metadataString(field_name_ip.toSlice(ip)),
1892 int_info.signedness == .unsigned,
1893 int_info.bits,
1894 bigint,
1895 );
1896 }
1897
1898 const file = try o.getDebugFile(pt, ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip));
1899 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|
1900 try o.namespaceToDebugScope(pt, parent_namespace)
1901 else
1902 file;
1903
1904 const name = try o.allocTypeName(pt, ty);
1905 defer gpa.free(name);
1906
1907 const debug_enum_type = try o.builder.debugEnumerationType(
1908 try o.builder.metadataString(name),
1909 file,
1910 scope,
1911 ty.typeDeclSrcLine(zcu).? + 1, // Line
1912 try o.lowerDebugType(pt, int_ty),
1913 ty.abiSize(zcu) * 8,
1914 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,
1915 try o.builder.metadataTuple(enumerators),
1916 );
19171984
1918 try o.debug_type_map.put(gpa, ty.toIntern(), debug_enum_type);
1919 try o.debug_enums.append(gpa, debug_enum_type);
1920 return debug_enum_type;
1921 },
1922 .float => {
1923 const bits = ty.floatBits(target);
1924 const name = try o.allocTypeName(pt, ty);
1925 defer gpa.free(name);
1926 const debug_float_type = try o.builder.debugFloatType(
1927 try o.builder.metadataString(name),
1928 bits,
1929 );
1930 try o.debug_type_map.put(gpa, ty.toIntern(), debug_float_type);
1931 return debug_float_type;
1932 },
1933 .bool => {
1934 const debug_bool_type = try o.builder.debugBoolType(
1935 try o.builder.metadataString("bool"),
1936 8, // lldb cannot handle non-byte sized types
1937 );
1938 try o.debug_type_map.put(gpa, ty.toIntern(), debug_bool_type);
1939 return debug_bool_type;
1940 },
19411985 .pointer => {
1942 // Normalize everything that the debug info does not represent.
1943 const ptr_info = ty.ptrInfo(zcu);
1944
1945 if (ptr_info.sentinel != .none or
1946 ptr_info.flags.address_space != .generic or
1947 ptr_info.packed_offset.bit_offset != 0 or
1948 ptr_info.packed_offset.host_size != 0 or
1949 ptr_info.flags.vector_index != .none or
1950 ptr_info.flags.is_allowzero or
1951 ptr_info.flags.is_const or
1952 ptr_info.flags.is_volatile or
1953 ptr_info.flags.size == .many or ptr_info.flags.size == .c or
1954 !Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(zcu))
1955 {
1956 const bland_ptr_ty = try pt.ptrType(.{
1957 .child = if (!Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(zcu))
1958 .anyopaque_type
1959 else
1960 ptr_info.child,
1961 .flags = .{
1962 .alignment = ptr_info.flags.alignment,
1963 .size = switch (ptr_info.flags.size) {
1964 .many, .c, .one => .one,
1965 .slice => .slice,
1966 },
1967 },
1968 });
1969 const debug_ptr_type = try o.lowerDebugType(pt, bland_ptr_ty);
1970 try o.debug_type_map.put(gpa, ty.toIntern(), debug_ptr_type);
1971 return debug_ptr_type;
1972 }
1973
1974 const debug_fwd_ref = try o.builder.debugForwardReference();
1975
1976 // Set as forward reference while the type is lowered in case it references itself
1977 try o.debug_type_map.put(gpa, ty.toIntern(), debug_fwd_ref);
1986 const ptr_size = Type.ptrAbiSize(zcu.getTarget());
1987 const ptr_align = Type.ptrAbiAlignment(zcu.getTarget());
19781988
19791989 if (ty.isSlice(zcu)) {
1980 const ptr_ty = ty.slicePtrFieldType(zcu);
1981 const len_ty = Type.usize;
1982
1983 const name = try o.allocTypeName(pt, ty);
1984 defer gpa.free(name);
1985 const line = 0;
1986
1987 const ptr_size = ptr_ty.abiSize(zcu);
1988 const ptr_align = ptr_ty.abiAlignment(zcu);
1989 const len_size = len_ty.abiSize(zcu);
1990 const len_align = len_ty.abiAlignment(zcu);
1991
1992 const len_offset = len_align.forward(ptr_size);
1993
19941990 const debug_ptr_type = try o.builder.debugMemberType(
19951991 try o.builder.metadataString("ptr"),
1996 null, // File
1997 debug_fwd_ref,
1998 0, // Line
1999 try o.lowerDebugType(pt, ptr_ty),
1992 null, // file
1993 ty_fwd_ref,
1994 0, // line
1995 try o.getDebugType(pt, ty.slicePtrFieldType(zcu)),
20001996 ptr_size * 8,
2001 (ptr_align.toByteUnits() orelse 0) * 8,
2002 0, // Offset
1997 ptr_align.toByteUnits().? * 8,
1998 0, // offset
20031999 );
20042000
20052001 const debug_len_type = try o.builder.debugMemberType(
20062002 try o.builder.metadataString("len"),
2007 null, // File
2008 debug_fwd_ref,
2009 0, // Line
2010 try o.lowerDebugType(pt, len_ty),
2011 len_size * 8,
2012 (len_align.toByteUnits() orelse 0) * 8,
2013 len_offset * 8,
2003 null, // file
2004 ty_fwd_ref,
2005 0, // line
2006 try o.getDebugType(pt, .usize),
2007 ptr_size * 8,
2008 ptr_align.toByteUnits().? * 8,
2009 ptr_size * 8,
20142010 );
20152011
2016 const debug_slice_type = try o.builder.debugStructType(
2017 try o.builder.metadataString(name),
2018 null, // File
2019 o.debug_compile_unit.unwrap().?, // Scope
2020 line,
2021 null, // Underlying type
2022 ty.abiSize(zcu) * 8,
2023 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,
2012 return o.builder.debugStructType(
2013 name,
2014 null, // file
2015 o.debug_compile_unit.unwrap().?, // scope
2016 0, // line
2017 null, // underlying type
2018 ptr_size * 2 * 8,
2019 ptr_align.toByteUnits().? * 8,
20242020 try o.builder.metadataTuple(&.{
20252021 debug_ptr_type,
20262022 debug_len_type,
20272023 }),
20282024 );
2029
2030 o.builder.resolveDebugForwardReference(debug_fwd_ref, debug_slice_type);
2031
2032 // Set to real type now that it has been lowered fully
2033 const map_ptr = o.debug_type_map.getPtr(ty.toIntern()) orelse unreachable;
2034 map_ptr.* = debug_slice_type;
2035
2036 return debug_slice_type;
20372025 }
20382026
2039 const debug_elem_ty = try o.lowerDebugType(pt, Type.fromInterned(ptr_info.child));
2040
2041 const name = try o.allocTypeName(pt, ty);
2042 defer gpa.free(name);
2043
2044 const debug_ptr_type = try o.builder.debugPointerType(
2045 try o.builder.metadataString(name),
2046 null, // File
2047 null, // Scope
2048 0, // Line
2049 debug_elem_ty,
2050 target.ptrBitWidth(),
2051 (ty.ptrAlignment(zcu).toByteUnits() orelse 0) * 8,
2052 0, // Offset
2027 return o.builder.debugPointerType(
2028 name,
2029 null, // file
2030 o.debug_compile_unit.unwrap().?, // scope
2031 0, // line
2032 try o.getDebugType(pt, ty.childType(zcu)),
2033 ptr_size * 8,
2034 ptr_align.toByteUnits().? * 8,
2035 0, // offset
20532036 );
2054
2055 o.builder.resolveDebugForwardReference(debug_fwd_ref, debug_ptr_type);
2056
2057 // Set to real type now that it has been lowered fully
2058 const map_ptr = o.debug_type_map.getPtr(ty.toIntern()) orelse unreachable;
2059 map_ptr.* = debug_ptr_type;
2060
2061 return debug_ptr_type;
2062 },
2063 .@"opaque" => {
2064 if (ty.toIntern() == .anyopaque_type) {
2065 const debug_opaque_type = try o.builder.debugSignedType(
2066 try o.builder.metadataString("anyopaque"),
2067 0,
2068 );
2069 try o.debug_type_map.put(gpa, ty.toIntern(), debug_opaque_type);
2070 return debug_opaque_type;
2071 }
2072
2073 const name = try o.allocTypeName(pt, ty);
2074 defer gpa.free(name);
2075
2076 const file = try o.getDebugFile(pt, ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip));
2077 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|
2078 try o.namespaceToDebugScope(pt, parent_namespace)
2079 else
2080 file;
2081
2082 const debug_opaque_type = try o.builder.debugStructType(
2083 try o.builder.metadataString(name),
2084 file,
2085 scope,
2086 ty.typeDeclSrcLine(zcu).? + 1, // Line
2087 null, // Underlying type
2088 0, // Size
2089 0, // Align
2090 null, // Fields
2091 );
2092 try o.debug_type_map.put(gpa, ty.toIntern(), debug_opaque_type);
2093 return debug_opaque_type;
2094 },
2095 .array => {
2096 const debug_array_type = try o.builder.debugArrayType(
2097 null, // Name
2098 null, // File
2099 null, // Scope
2100 0, // Line
2101 try o.lowerDebugType(pt, ty.childType(zcu)),
2102 ty.abiSize(zcu) * 8,
2103 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,
2104 try o.builder.metadataTuple(&.{
2105 try o.builder.debugSubrange(
2106 try o.builder.metadataConstant(try o.builder.intConst(.i64, 0)),
2107 try o.builder.metadataConstant(try o.builder.intConst(.i64, ty.arrayLen(zcu))),
2108 ),
2109 }),
2110 );
2111 try o.debug_type_map.put(gpa, ty.toIntern(), debug_array_type);
2112 return debug_array_type;
21132037 },
2038 .array => return o.builder.debugArrayType(
2039 name,
2040 null, // file
2041 o.debug_compile_unit.unwrap().?, // scope
2042 0, // line
2043 try o.getDebugType(pt, ty.childType(zcu)),
2044 ty.abiSize(zcu) * 8,
2045 ty.abiAlignment(zcu).toByteUnits().? * 8,
2046 try o.builder.metadataTuple(&.{
2047 try o.builder.debugSubrange(
2048 try o.builder.metadataConstant(try o.builder.intConst(.i64, 0)),
2049 try o.builder.metadataConstant(try o.builder.intConst(.i64, ty.arrayLen(zcu))),
2050 ),
2051 }),
2052 ),
21142053 .vector => {
2115 const elem_ty = ty.elemType2(zcu);
2054 const elem_ty = ty.childType(zcu);
21162055 // Vector elements cannot be padded since that would make
2117 // @bitSizOf(elem) * len > @bitSizOf(vec).
2056 // @bitSizeOf(elem) * len > @bitSizOf(vec).
21182057 // Neither gdb nor lldb seem to be able to display non-byte sized
21192058 // vectors properly.
21202059 const debug_elem_type = switch (elem_ty.zigTypeTag(zcu)) {
21212060 .int => blk: {
21222061 const info = elem_ty.intInfo(zcu);
2123 assert(info.bits != 0);
2124 const name = try o.allocTypeName(pt, ty);
2125 defer gpa.free(name);
2126 const builder_name = try o.builder.metadataString(name);
21272062 break :blk switch (info.signedness) {
2128 .signed => try o.builder.debugSignedType(builder_name, info.bits),
2129 .unsigned => try o.builder.debugUnsignedType(builder_name, info.bits),
2063 .signed => try o.builder.debugSignedType(name, info.bits),
2064 .unsigned => try o.builder.debugUnsignedType(name, info.bits),
21302065 };
21312066 },
2132 .bool => try o.builder.debugBoolType(
2133 try o.builder.metadataString("bool"),
2134 1,
2135 ),
2136 else => try o.lowerDebugType(pt, ty.childType(zcu)),
2067 .bool => try o.builder.debugBoolType(try o.builder.metadataString("bool"), 1),
2068 // We don't pad pointers or floats, so we can lower those normally.
2069 .pointer, .optional, .float => try o.getDebugType(pt, elem_ty),
2070 else => unreachable,
21372071 };
21382072
2139 const debug_vector_type = try o.builder.debugVectorType(
2140 null, // Name
2141 null, // File
2142 null, // Scope
2143 0, // Line
2073 return o.builder.debugVectorType(
2074 name,
2075 null, // file
2076 o.debug_compile_unit.unwrap().?, // scope
2077 0, // line
21442078 debug_elem_type,
21452079 ty.abiSize(zcu) * 8,
2146 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,
2080 ty.abiAlignment(zcu).toByteUnits().? * 8,
21472081 try o.builder.metadataTuple(&.{
21482082 try o.builder.debugSubrange(
21492083 try o.builder.metadataConstant(try o.builder.intConst(.i64, 0)),
......@@ -2151,566 +2085,574 @@ pub const Object = struct {
21512085 ),
21522086 }),
21532087 );
2154
2155 try o.debug_type_map.put(gpa, ty.toIntern(), debug_vector_type);
2156 return debug_vector_type;
21572088 },
21582089 .optional => {
2159 const name = try o.allocTypeName(pt, ty);
2160 defer gpa.free(name);
2161 const child_ty = ty.optionalChild(zcu);
2162 if (!child_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
2163 const debug_bool_type = try o.builder.debugBoolType(
2164 try o.builder.metadataString(name),
2165 8,
2090 const payload_ty = ty.optionalChild(zcu);
2091 if (ty.optionalReprIsPayload(zcu)) {
2092 return o.builder.debugTypedefType(
2093 name,
2094 null, // file
2095 o.debug_compile_unit.unwrap().?, // scope
2096 0, // line
2097 try o.getDebugType(pt, payload_ty),
2098 ty.abiSize(zcu) * 8,
2099 ty.abiAlignment(zcu).toByteUnits().? * 8,
2100 0, // offset
21662101 );
2167 try o.debug_type_map.put(gpa, ty.toIntern(), debug_bool_type);
2168 return debug_bool_type;
21692102 }
21702103
2171 const debug_fwd_ref = try o.builder.debugForwardReference();
2172
2173 // Set as forward reference while the type is lowered in case it references itself
2174 try o.debug_type_map.put(gpa, ty.toIntern(), debug_fwd_ref);
2175
2176 if (ty.optionalReprIsPayload(zcu)) {
2177 const debug_optional_type = try o.lowerDebugType(pt, child_ty);
2178
2179 o.builder.resolveDebugForwardReference(debug_fwd_ref, debug_optional_type);
2180
2181 // Set to real type now that it has been lowered fully
2182 const map_ptr = o.debug_type_map.getPtr(ty.toIntern()) orelse unreachable;
2183 map_ptr.* = debug_optional_type;
2184
2185 return debug_optional_type;
2186 }
2104 const payload_size = payload_ty.abiSize(zcu);
21872105
21882106 const non_null_ty = Type.u8;
2189 const payload_size = child_ty.abiSize(zcu);
2190 const payload_align = child_ty.abiAlignment(zcu);
21912107 const non_null_size = non_null_ty.abiSize(zcu);
21922108 const non_null_align = non_null_ty.abiAlignment(zcu);
21932109 const non_null_offset = non_null_align.forward(payload_size);
21942110
2195 const debug_data_type = try o.builder.debugMemberType(
2196 try o.builder.metadataString("data"),
2197 null, // File
2198 debug_fwd_ref,
2199 0, // Line
2200 try o.lowerDebugType(pt, child_ty),
2111 const debug_payload_type = try o.builder.debugMemberType(
2112 try o.builder.metadataString("payload"),
2113 null, // file
2114 ty_fwd_ref, // scope
2115 0, // line
2116 try o.getDebugType(pt, payload_ty),
22012117 payload_size * 8,
2202 (payload_align.toByteUnits() orelse 0) * 8,
2203 0, // Offset
2118 payload_ty.abiAlignment(zcu).toByteUnits().? * 8,
2119 0, // offset
22042120 );
22052121
22062122 const debug_some_type = try o.builder.debugMemberType(
22072123 try o.builder.metadataString("some"),
22082124 null,
2209 debug_fwd_ref,
2125 ty_fwd_ref,
22102126 0,
2211 try o.lowerDebugType(pt, non_null_ty),
2127 try o.getDebugType(pt, non_null_ty),
22122128 non_null_size * 8,
2213 (non_null_align.toByteUnits() orelse 0) * 8,
2129 non_null_align.toByteUnits().? * 8,
22142130 non_null_offset * 8,
22152131 );
22162132
2217 const debug_optional_type = try o.builder.debugStructType(
2218 try o.builder.metadataString(name),
2219 null, // File
2220 o.debug_compile_unit.unwrap().?, // Scope
2221 0, // Line
2222 null, // Underlying type
2133 return o.builder.debugStructType(
2134 name,
2135 null, // file
2136 o.debug_compile_unit.unwrap().?, // scope
2137 0, // line
2138 null, // underlying type
22232139 ty.abiSize(zcu) * 8,
2224 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,
2140 ty.abiAlignment(zcu).toByteUnits().? * 8,
22252141 try o.builder.metadataTuple(&.{
2226 debug_data_type,
2142 debug_payload_type,
22272143 debug_some_type,
22282144 }),
22292145 );
2230
2231 o.builder.resolveDebugForwardReference(debug_fwd_ref, debug_optional_type);
2232
2233 // Set to real type now that it has been lowered fully
2234 const map_ptr = o.debug_type_map.getPtr(ty.toIntern()) orelse unreachable;
2235 map_ptr.* = debug_optional_type;
2236
2237 return debug_optional_type;
22382146 },
22392147 .error_union => {
2148 const error_ty = ty.errorUnionSet(zcu);
22402149 const payload_ty = ty.errorUnionPayload(zcu);
2241 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
2242 // TODO: Maybe remove?
2243 const debug_error_union_type = try o.lowerDebugType(pt, Type.anyerror);
2244 try o.debug_type_map.put(gpa, ty.toIntern(), debug_error_union_type);
2245 return debug_error_union_type;
2246 }
2247
2248 const name = try o.allocTypeName(pt, ty);
2249 defer gpa.free(name);
22502150
2251 const error_size = Type.anyerror.abiSize(zcu);
2252 const error_align = Type.anyerror.abiAlignment(zcu);
2151 const error_size = error_ty.abiSize(zcu);
2152 const error_align = error_ty.abiAlignment(zcu);
22532153 const payload_size = payload_ty.abiSize(zcu);
22542154 const payload_align = payload_ty.abiAlignment(zcu);
22552155
2256 var error_index: u32 = undefined;
2257 var payload_index: u32 = undefined;
2258 var error_offset: u64 = undefined;
2259 var payload_offset: u64 = undefined;
2260 if (error_align.compare(.gt, payload_align)) {
2261 error_index = 0;
2262 payload_index = 1;
2263 error_offset = 0;
2264 payload_offset = payload_align.forward(error_size);
2265 } else {
2266 payload_index = 0;
2267 error_index = 1;
2268 payload_offset = 0;
2269 error_offset = error_align.forward(payload_size);
2270 }
2271
2272 const debug_fwd_ref = try o.builder.debugForwardReference();
2156 const error_offset: u64, const payload_offset: u64 = offsets: {
2157 if (error_align.compare(.gt, payload_align)) {
2158 break :offsets .{ 0, payload_align.forward(error_size) };
2159 } else {
2160 break :offsets .{ error_align.forward(payload_size), 0 };
2161 }
2162 };
22732163
2274 var fields: [2]Builder.Metadata = undefined;
2275 fields[error_index] = try o.builder.debugMemberType(
2276 try o.builder.metadataString("tag"),
2277 null, // File
2278 debug_fwd_ref,
2279 0, // Line
2280 try o.lowerDebugType(pt, Type.anyerror),
2164 const error_field = try o.builder.debugMemberType(
2165 try o.builder.metadataString("error"),
2166 null, // file
2167 ty_fwd_ref,
2168 0, // line
2169 try o.getDebugType(pt, error_ty),
22812170 error_size * 8,
2282 (error_align.toByteUnits() orelse 0) * 8,
2171 error_align.toByteUnits().? * 8,
22832172 error_offset * 8,
22842173 );
2285 fields[payload_index] = try o.builder.debugMemberType(
2286 try o.builder.metadataString("value"),
2287 null, // File
2288 debug_fwd_ref,
2289 0, // Line
2290 try o.lowerDebugType(pt, payload_ty),
2174 const payload_field = try o.builder.debugMemberType(
2175 try o.builder.metadataString("payload"),
2176 null, // file
2177 ty_fwd_ref, // scope
2178 0, // line
2179 try o.getDebugType(pt, payload_ty),
22912180 payload_size * 8,
2292 (payload_align.toByteUnits() orelse 0) * 8,
2181 payload_align.toByteUnits().? * 8,
22932182 payload_offset * 8,
22942183 );
22952184
2296 const debug_error_union_type = try o.builder.debugStructType(
2297 try o.builder.metadataString(name),
2185 return try o.builder.debugStructType(
2186 name,
22982187 null, // File
2299 o.debug_compile_unit.unwrap().?, // Sope
2188 o.debug_compile_unit.unwrap().?, // Scope
23002189 0, // Line
23012190 null, // Underlying type
23022191 ty.abiSize(zcu) * 8,
2303 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,
2304 try o.builder.metadataTuple(&fields),
2192 ty.abiAlignment(zcu).toByteUnits().? * 8,
2193 try o.builder.metadataTuple(&.{ error_field, payload_field }),
23052194 );
2306
2307 o.builder.resolveDebugForwardReference(debug_fwd_ref, debug_error_union_type);
2308
2309 try o.debug_type_map.put(gpa, ty.toIntern(), debug_error_union_type);
2310 return debug_error_union_type;
23112195 },
23122196 .error_set => {
2313 const debug_error_set = try o.builder.debugUnsignedType(
2314 try o.builder.metadataString("anyerror"),
2315 16,
2197 assert(ty.toIntern() != .anyerror_type); // handled specially in `updateConst`; will be populated by `emit` instead
2198 // Error sets are just named wrappers around `anyerror`.
2199 return o.builder.debugTypedefType(
2200 name,
2201 null, // file
2202 o.debug_compile_unit.unwrap().?, // scope
2203 0, // line
2204 try o.getDebugType(pt, .anyerror),
2205 ty.abiSize(zcu) * 8,
2206 ty.abiAlignment(zcu).toByteUnits().? * 8,
2207 0, // offset
23162208 );
2317 try o.debug_type_map.put(gpa, ty.toIntern(), debug_error_set);
2318 return debug_error_set;
23192209 },
2320 .@"struct" => {
2321 const name = try o.allocTypeName(pt, ty);
2322 defer gpa.free(name);
2323
2324 if (zcu.typeToPackedStruct(ty)) |struct_type| {
2325 const backing_int_ty = struct_type.backingIntTypeUnordered(ip);
2326 if (backing_int_ty != .none) {
2327 const info = Type.fromInterned(backing_int_ty).intInfo(zcu);
2328 const builder_name = try o.builder.metadataString(name);
2329 const debug_int_type = switch (info.signedness) {
2330 .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(zcu) * 8),
2331 .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(zcu) * 8),
2332 };
2333 try o.debug_type_map.put(gpa, ty.toIntern(), debug_int_type);
2334 return debug_int_type;
2335 }
2210 .@"fn" => {
2211 if (!ty.fnHasRuntimeBits(zcu)) {
2212 return o.builder.debugSignedType(name, 0);
23362213 }
23372214
2338 switch (ip.indexToKey(ty.toIntern())) {
2339 .tuple_type => |tuple| {
2340 var fields: std.ArrayList(Builder.Metadata) = .empty;
2341 defer fields.deinit(gpa);
2342
2343 try fields.ensureUnusedCapacity(gpa, tuple.types.len);
2215 const fn_info = zcu.typeToFunc(ty).?;
23442216
2345 comptime assert(struct_layout_version == 2);
2346 var offset: u64 = 0;
2217 var debug_param_types: std.ArrayList(Builder.Metadata) = try .initCapacity(gpa, 3 + fn_info.param_types.len);
2218 defer debug_param_types.deinit(gpa);
23472219
2348 const debug_fwd_ref = try o.builder.debugForwardReference();
2220 // Return type goes first.
2221 const sret = firstParamSRet(fn_info, zcu, target);
2222 const ret_ty: Type = if (sret) .void else .fromInterned(fn_info.return_type);
2223 debug_param_types.appendAssumeCapacity(try o.getDebugType(pt, ret_ty));
23492224
2350 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
2351 if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue;
2225 if (sret) {
2226 const ptr_ty = try pt.singleMutPtrType(Type.fromInterned(fn_info.return_type));
2227 debug_param_types.appendAssumeCapacity(try o.getDebugType(pt, ptr_ty));
2228 }
23522229
2353 const field_size = Type.fromInterned(field_ty).abiSize(zcu);
2354 const field_align = Type.fromInterned(field_ty).abiAlignment(zcu);
2355 const field_offset = field_align.forward(offset);
2356 offset = field_offset + field_size;
2230 if (fn_info.cc == .auto and zcu.comp.config.any_error_tracing) {
2231 // Stack trace pointer.
2232 debug_param_types.appendAssumeCapacity(try o.getDebugType(pt, .ptr_usize));
2233 }
23572234
2358 var name_buf: [32]u8 = undefined;
2359 const field_name = std.fmt.bufPrint(&name_buf, "{d}", .{i}) catch unreachable;
2235 for (fn_info.param_types.get(ip)) |param_ty_ip| {
2236 const param_ty: Type = .fromInterned(param_ty_ip);
2237 if (!param_ty.hasRuntimeBits(zcu)) continue;
2238 if (isByRef(param_ty, zcu)) {
2239 const ptr_ty = try pt.singleConstPtrType(param_ty);
2240 debug_param_types.appendAssumeCapacity(try o.getDebugType(pt, ptr_ty));
2241 } else {
2242 debug_param_types.appendAssumeCapacity(try o.getDebugType(pt, param_ty));
2243 }
2244 }
23602245
2361 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2362 try o.builder.metadataString(field_name),
2363 null, // File
2364 debug_fwd_ref,
2365 0,
2366 try o.lowerDebugType(pt, Type.fromInterned(field_ty)),
2367 field_size * 8,
2368 (field_align.toByteUnits() orelse 0) * 8,
2369 field_offset * 8,
2370 ));
2371 }
2246 return o.builder.debugSubroutineType(
2247 try o.builder.metadataTuple(debug_param_types.items),
2248 );
2249 },
2250 .@"struct" => {
2251 if (ty.isTuple(zcu)) {
2252 const tuple = ip.indexToKey(ty.toIntern()).tuple_type;
2253 var fields: std.ArrayList(Builder.Metadata) = .empty;
2254 defer fields.deinit(gpa);
23722255
2373 const debug_struct_type = try o.builder.debugStructType(
2374 try o.builder.metadataString(name),
2375 null, // File
2376 o.debug_compile_unit.unwrap().?, // Scope
2377 0, // Line
2378 null, // Underlying type
2379 ty.abiSize(zcu) * 8,
2380 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,
2381 try o.builder.metadataTuple(fields.items),
2382 );
2256 try fields.ensureUnusedCapacity(gpa, tuple.types.len);
23832257
2384 o.builder.resolveDebugForwardReference(debug_fwd_ref, debug_struct_type);
2258 comptime assert(struct_layout_version == 2);
2259 var offset: u64 = 0;
23852260
2386 try o.debug_type_map.put(gpa, ty.toIntern(), debug_struct_type);
2387 return debug_struct_type;
2388 },
2389 .struct_type => {
2390 if (!ip.loadStructType(ty.toIntern()).haveFieldTypes(ip)) {
2391 // This can happen if a struct type makes it all the way to
2392 // flush() without ever being instantiated or referenced (even
2393 // via pointer). The only reason we are hearing about it now is
2394 // that it is being used as a namespace to put other debug types
2395 // into. Therefore we can satisfy this by making an empty namespace,
2396 // rather than changing the frontend to unnecessarily resolve the
2397 // struct field types.
2398 const debug_struct_type = try o.makeEmptyNamespaceDebugType(pt, ty);
2399 try o.debug_type_map.put(gpa, ty.toIntern(), debug_struct_type);
2400 return debug_struct_type;
2401 }
2402 },
2403 else => {},
2404 }
2261 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty_ip, field_val, i| {
2262 const field_ty: Type = .fromInterned(field_ty_ip);
2263 if (field_val != .none or !field_ty.hasRuntimeBits(zcu)) continue;
2264
2265 const field_size = field_ty.abiSize(zcu);
2266 const field_align = field_ty.abiAlignment(zcu);
2267 const field_offset = field_align.forward(offset);
2268 offset = field_offset + field_size;
2269
2270 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2271 try o.builder.metadataStringFmt("{d}", .{i}),
2272 null, // file
2273 ty_fwd_ref,
2274 0, // line
2275 try o.getDebugType(pt, field_ty),
2276 field_size * 8,
2277 field_align.toByteUnits().? * 8,
2278 field_offset * 8,
2279 ));
2280 }
24052281
2406 if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) {
2407 const debug_struct_type = try o.makeEmptyNamespaceDebugType(pt, ty);
2408 try o.debug_type_map.put(gpa, ty.toIntern(), debug_struct_type);
2409 return debug_struct_type;
2282 return o.builder.debugStructType(
2283 name,
2284 null, // file
2285 o.debug_compile_unit.unwrap().?,
2286 0, // line
2287 null, // underlying type
2288 ty.abiSize(zcu) * 8,
2289 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,
2290 try o.builder.metadataTuple(fields.items),
2291 );
24102292 }
24112293
24122294 const struct_type = zcu.typeToStruct(ty).?;
24132295
2414 var fields: std.ArrayList(Builder.Metadata) = .empty;
2415 defer fields.deinit(gpa);
2416
2417 try fields.ensureUnusedCapacity(gpa, struct_type.field_types.len);
2296 const file = try o.getDebugFile(pt, struct_type.zir_index.resolveFile(ip));
2297 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|
2298 try o.namespaceToDebugScope(pt, parent_namespace)
2299 else
2300 file;
24182301
2419 const debug_fwd_ref = try o.builder.debugForwardReference();
2302 const line = ty.typeDeclSrcLine(zcu).? + 1;
24202303
2421 // Set as forward reference while the type is lowered in case it references itself
2422 try o.debug_type_map.put(gpa, ty.toIntern(), debug_fwd_ref);
2304 var fields: std.ArrayList(Builder.Metadata) = .empty;
2305 defer fields.deinit(gpa);
24232306
2424 comptime assert(struct_layout_version == 2);
2425 var it = struct_type.iterateRuntimeOrder(ip);
2426 while (it.next()) |field_index| {
2427 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
2428 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
2429 const field_size = field_ty.abiSize(zcu);
2430 const field_align = ty.fieldAlignment(field_index, zcu);
2431 const field_offset = ty.structFieldOffset(field_index, zcu);
2432 const field_name = struct_type.fieldName(ip, field_index);
2433 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2434 try o.builder.metadataString(field_name.toSlice(ip)),
2435 null, // File
2436 debug_fwd_ref,
2437 0, // Line
2438 try o.lowerDebugType(pt, field_ty),
2439 field_size * 8,
2440 (field_align.toByteUnits() orelse 0) * 8,
2441 field_offset * 8,
2442 ));
2307 switch (struct_type.layout) {
2308 .@"packed" => {
2309 try fields.ensureTotalCapacityPrecise(gpa, 1);
2310 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2311 try o.builder.metadataString("bits"),
2312 null, // file
2313 ty_fwd_ref,
2314 0, // line
2315 try o.getDebugType(pt, .fromInterned(struct_type.packed_backing_int_type)),
2316 ty.abiSize(zcu) * 8,
2317 ty.abiAlignment(zcu).toByteUnits().? * 8,
2318 0, // offset
2319 ));
2320 },
2321 .auto, .@"extern" => {
2322 comptime assert(struct_layout_version == 2);
2323 try fields.ensureTotalCapacityPrecise(gpa, struct_type.field_types.len);
2324 var it = struct_type.iterateRuntimeOrder(ip);
2325 while (it.next()) |field_index| {
2326 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
2327 if (!field_ty.hasRuntimeBits(zcu)) continue;
2328 const field_size = field_ty.abiSize(zcu);
2329 const field_align = switch (ty.explicitFieldAlignment(field_index, zcu)) {
2330 .none => field_ty.abiAlignment(zcu),
2331 else => |a| a,
2332 };
2333 const field_offset = struct_type.field_offsets.get(ip)[field_index];
2334 const field_name = struct_type.field_names.get(ip)[field_index];
2335 fields.appendAssumeCapacity(try o.builder.debugMemberType(
2336 try o.builder.metadataString(field_name.toSlice(ip)),
2337 null, // file
2338 ty_fwd_ref,
2339 0, // line
2340 try o.getDebugType(pt, field_ty),
2341 field_size * 8,
2342 field_align.toByteUnits().? * 8,
2343 field_offset * 8,
2344 ));
2345 }
2346 },
24432347 }
24442348
2445 const debug_struct_type = try o.builder.debugStructType(
2446 try o.builder.metadataString(name),
2447 null, // File
2448 o.debug_compile_unit.unwrap().?, // Scope
2449 0, // Line
2450 null, // Underlying type
2349 return o.builder.debugStructType(
2350 name,
2351 file,
2352 scope,
2353 line,
2354 null, // underlying type
24512355 ty.abiSize(zcu) * 8,
2452 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,
2356 ty.abiAlignment(zcu).toByteUnits().? * 8,
24532357 try o.builder.metadataTuple(fields.items),
24542358 );
2455
2456 o.builder.resolveDebugForwardReference(debug_fwd_ref, debug_struct_type);
2457
2458 // Set to real type now that it has been lowered fully
2459 const map_ptr = o.debug_type_map.getPtr(ty.toIntern()) orelse unreachable;
2460 map_ptr.* = debug_struct_type;
2461
2462 return debug_struct_type;
24632359 },
24642360 .@"union" => {
2465 const name = try o.allocTypeName(pt, ty);
2466 defer gpa.free(name);
2467
24682361 const union_type = ip.loadUnionType(ty.toIntern());
2469 if (!union_type.haveFieldTypes(ip) or
2470 !ty.hasRuntimeBitsIgnoreComptime(zcu) or
2471 !union_type.haveLayout(ip))
2472 {
2473 const debug_union_type = try o.makeEmptyNamespaceDebugType(pt, ty);
2474 try o.debug_type_map.put(gpa, ty.toIntern(), debug_union_type);
2475 return debug_union_type;
2476 }
24772362
2478 const layout = Type.getUnionLayout(union_type, zcu);
2363 const file = try o.getDebugFile(pt, union_type.zir_index.resolveFile(ip));
2364 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|
2365 try o.namespaceToDebugScope(pt, parent_namespace)
2366 else
2367 file;
24792368
2480 const debug_fwd_ref = try o.builder.debugForwardReference();
2369 const line = ty.typeDeclSrcLine(zcu).? + 1;
24812370
2482 // Set as forward reference while the type is lowered in case it references itself
2483 try o.debug_type_map.put(gpa, ty.toIntern(), debug_fwd_ref);
2371 const enum_tag_ty: Type = .fromInterned(union_type.enum_tag_type);
24842372
2485 if (layout.payload_size == 0) {
2486 const debug_union_type = try o.builder.debugStructType(
2487 try o.builder.metadataString(name),
2488 null, // File
2489 o.debug_compile_unit.unwrap().?, // Scope
2490 0, // Line
2491 null, // Underlying type
2373 if (union_type.layout == .@"packed") {
2374 const bitpack_field = try o.builder.debugMemberType(
2375 try o.builder.metadataString("bits"),
2376 null, // file
2377 ty_fwd_ref,
2378 0, // line
2379 try o.getDebugType(pt, .fromInterned(union_type.packed_backing_int_type)),
24922380 ty.abiSize(zcu) * 8,
2493 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,
2494 try o.builder.metadataTuple(
2495 &.{try o.lowerDebugType(pt, Type.fromInterned(union_type.enum_tag_ty))},
2496 ),
2381 ty.abiAlignment(zcu).toByteUnits().? * 8,
2382 0, // offset
24972383 );
2384 return o.builder.debugStructType(
2385 name,
2386 file,
2387 scope,
2388 line,
2389 null, // underlying type
2390 ty.abiSize(zcu) * 8,
2391 ty.abiAlignment(zcu).toByteUnits().? * 8,
2392 try o.builder.metadataTuple(&.{bitpack_field}),
2393 );
2394 }
24982395
2499 // Set to real type now that it has been lowered fully
2500 const map_ptr = o.debug_type_map.getPtr(ty.toIntern()) orelse unreachable;
2501 map_ptr.* = debug_union_type;
2396 const layout = Type.getUnionLayout(union_type, zcu);
25022397
2503 return debug_union_type;
2398 if (layout.payload_size == 0) {
2399 const fields_tuple: ?Builder.Metadata = fields: {
2400 if (layout.tag_size == 0) break :fields null;
2401 break :fields try o.builder.metadataTuple(&.{
2402 try o.builder.debugMemberType(
2403 try o.builder.metadataString("tag"),
2404 null, // file
2405 ty_fwd_ref,
2406 0, // line
2407 try o.getDebugType(pt, enum_tag_ty),
2408 layout.tag_size * 8,
2409 layout.tag_align.toByteUnits().? * 8,
2410 0, // offset
2411 ),
2412 });
2413 };
2414 return o.builder.debugStructType(
2415 name,
2416 file,
2417 scope,
2418 line,
2419 null, // underlying type
2420 ty.abiSize(zcu) * 8,
2421 ty.abiAlignment(zcu).toByteUnits().? * 8,
2422 fields_tuple,
2423 );
25042424 }
25052425
2506 var fields: std.ArrayList(Builder.Metadata) = .empty;
2426 var fields: std.ArrayList(Builder.Metadata) = try .initCapacity(gpa, union_type.field_types.len);
25072427 defer fields.deinit(gpa);
25082428
2509 try fields.ensureUnusedCapacity(gpa, union_type.loadTagType(ip).names.len);
2510
2511 const debug_union_fwd_ref = if (layout.tag_size == 0)
2512 debug_fwd_ref
2429 const payload_fwd_ref = if (layout.tag_size == 0)
2430 ty_fwd_ref
25132431 else
25142432 try o.builder.debugForwardReference();
25152433
2516 const tag_type = union_type.loadTagType(ip);
2517
2518 for (0..tag_type.names.len) |field_index| {
2434 for (0..union_type.field_types.len) |field_index| {
25192435 const field_ty = union_type.field_types.get(ip)[field_index];
2520 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) continue;
25212436
25222437 const field_size = Type.fromInterned(field_ty).abiSize(zcu);
2523 const field_align: InternPool.Alignment = switch (union_type.flagsUnordered(ip).layout) {
2524 .@"packed" => .none,
2525 .auto, .@"extern" => ty.fieldAlignment(field_index, zcu),
2526 };
2438 const field_align: InternPool.Alignment = ty.explicitFieldAlignment(field_index, zcu);
25272439
2528 const field_name = tag_type.names.get(ip)[field_index];
2440 const field_name = enum_tag_ty.enumFieldName(field_index, zcu);
25292441 fields.appendAssumeCapacity(try o.builder.debugMemberType(
25302442 try o.builder.metadataString(field_name.toSlice(ip)),
2531 null, // File
2532 debug_union_fwd_ref,
2533 0, // Line
2534 try o.lowerDebugType(pt, Type.fromInterned(field_ty)),
2443 null, // file
2444 payload_fwd_ref,
2445 0, // line
2446 try o.getDebugType(pt, .fromInterned(field_ty)),
25352447 field_size * 8,
25362448 (field_align.toByteUnits() orelse 0) * 8,
2537 0, // Offset
2449 0, // offset
25382450 ));
25392451 }
25402452
2541 var union_name_buf: ?[:0]const u8 = null;
2542 defer if (union_name_buf) |buf| gpa.free(buf);
2543 const union_name = if (layout.tag_size == 0) name else name: {
2544 union_name_buf = try std.fmt.allocPrintSentinel(gpa, "{s}:Payload", .{name}, 0);
2545 break :name union_name_buf.?;
2546 };
2547
2548 const debug_union_type = try o.builder.debugUnionType(
2549 try o.builder.metadataString(union_name),
2550 null, // File
2551 o.debug_compile_unit.unwrap().?, // Scope
2552 0, // Line
2553 null, // Underlying type
2453 const debug_payload_type = try o.builder.debugUnionType(
2454 payload_name: {
2455 if (layout.tag_size == 0) break :payload_name name;
2456 break :payload_name try o.builder.metadataStringFmt("{f}:Payload", .{ty.fmt(pt)});
2457 },
2458 file,
2459 scope,
2460 line,
2461 null, // underlying type
25542462 layout.payload_size * 8,
2555 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,
2463 ty.abiAlignment(zcu).toByteUnits().? * 8,
25562464 try o.builder.metadataTuple(fields.items),
25572465 );
25582466
2559 o.builder.resolveDebugForwardReference(debug_union_fwd_ref, debug_union_type);
2560
25612467 if (layout.tag_size == 0) {
2562 // Set to real type now that it has been lowered fully
2563 const map_ptr = o.debug_type_map.getPtr(ty.toIntern()) orelse unreachable;
2564 map_ptr.* = debug_union_type;
2565
2566 return debug_union_type;
2468 return debug_payload_type;
25672469 }
25682470
2569 var tag_offset: u64 = undefined;
2570 var payload_offset: u64 = undefined;
2571 if (layout.tag_align.compare(.gte, layout.payload_align)) {
2572 tag_offset = 0;
2573 payload_offset = layout.payload_align.forward(layout.tag_size);
2574 } else {
2575 payload_offset = 0;
2576 tag_offset = layout.tag_align.forward(layout.payload_size);
2577 }
2471 o.builder.resolveDebugForwardReference(payload_fwd_ref, debug_payload_type);
25782472
2579 const debug_tag_type = try o.builder.debugMemberType(
2473 const tag_offset: u64, const payload_offset: u64 = offsets: {
2474 if (layout.tag_align.compare(.gte, layout.payload_align)) {
2475 break :offsets .{ 0, layout.payload_align.forward(layout.tag_size) };
2476 } else {
2477 break :offsets .{ layout.tag_align.forward(layout.payload_size), 0 };
2478 }
2479 };
2480
2481 const tag_member_type = try o.builder.debugMemberType(
25802482 try o.builder.metadataString("tag"),
2581 null, // File
2582 debug_fwd_ref,
2583 0, // Line
2584 try o.lowerDebugType(pt, Type.fromInterned(union_type.enum_tag_ty)),
2483 null, // file
2484 ty_fwd_ref,
2485 0, // line
2486 try o.getDebugType(pt, enum_tag_ty),
25852487 layout.tag_size * 8,
2586 (layout.tag_align.toByteUnits() orelse 0) * 8,
2488 layout.tag_align.toByteUnits().? * 8,
25872489 tag_offset * 8,
25882490 );
25892491
2590 const debug_payload_type = try o.builder.debugMemberType(
2492 const payload_member_type = try o.builder.debugMemberType(
25912493 try o.builder.metadataString("payload"),
2592 null, // File
2593 debug_fwd_ref,
2594 0, // Line
2595 debug_union_type,
2494 null, // file
2495 ty_fwd_ref,
2496 0, // line
2497 debug_payload_type,
25962498 layout.payload_size * 8,
2597 (layout.payload_align.toByteUnits() orelse 0) * 8,
2499 layout.payload_align.toByteUnits().? * 8,
25982500 payload_offset * 8,
25992501 );
26002502
26012503 const full_fields: [2]Builder.Metadata =
26022504 if (layout.tag_align.compare(.gte, layout.payload_align))
2603 .{ debug_tag_type, debug_payload_type }
2505 .{ tag_member_type, payload_member_type }
26042506 else
2605 .{ debug_payload_type, debug_tag_type };
2507 .{ payload_member_type, tag_member_type };
26062508
2607 const debug_tagged_union_type = try o.builder.debugStructType(
2608 try o.builder.metadataString(name),
2609 null, // File
2610 o.debug_compile_unit.unwrap().?, // Scope
2611 0, // Line
2612 null, // Underlying type
2509 return o.builder.debugStructType(
2510 name,
2511 file,
2512 scope,
2513 line,
2514 null, // underlying type
26132515 ty.abiSize(zcu) * 8,
2614 (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8,
2516 ty.abiAlignment(zcu).toByteUnits().? * 8,
26152517 try o.builder.metadataTuple(&full_fields),
26162518 );
2519 },
2520 .@"enum" => {
2521 const file = try o.getDebugFile(pt, ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip));
2522 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|
2523 try o.namespaceToDebugScope(pt, parent_namespace)
2524 else
2525 file;
26172526
2618 o.builder.resolveDebugForwardReference(debug_fwd_ref, debug_tagged_union_type);
2619
2620 // Set to real type now that it has been lowered fully
2621 const map_ptr = o.debug_type_map.getPtr(ty.toIntern()) orelse unreachable;
2622 map_ptr.* = debug_tagged_union_type;
2527 const line = ty.typeDeclSrcLine(zcu).? + 1;
26232528
2624 return debug_tagged_union_type;
2625 },
2626 .@"fn" => {
2627 const fn_info = zcu.typeToFunc(ty).?;
2529 if (!ty.hasRuntimeBits(zcu)) {
2530 return o.builder.debugStructType(
2531 name,
2532 file,
2533 scope,
2534 line,
2535 null, // underlying type
2536 ty.abiSize(zcu) * 8,
2537 ty.abiAlignment(zcu).toByteUnits().? * 8,
2538 null, // fields
2539 );
2540 }
26282541
2629 var debug_param_types = std.array_list.Managed(Builder.Metadata).init(gpa);
2630 defer debug_param_types.deinit();
2542 const enum_type = ip.loadEnumType(ty.toIntern());
2543 const enumerators = try gpa.alloc(Builder.Metadata, enum_type.field_names.len);
2544 defer gpa.free(enumerators);
26312545
2632 try debug_param_types.ensureUnusedCapacity(3 + fn_info.param_types.len);
2546 const int_ty: Type = .fromInterned(enum_type.int_tag_type);
2547 const int_info = ty.intInfo(zcu);
2548 assert(int_info.bits != 0);
26332549
2634 // Return type goes first.
2635 if (Type.fromInterned(fn_info.return_type).hasRuntimeBitsIgnoreComptime(zcu)) {
2636 const sret = firstParamSRet(fn_info, zcu, target);
2637 const ret_ty = if (sret) Type.void else Type.fromInterned(fn_info.return_type);
2638 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(pt, ret_ty));
2639
2640 if (sret) {
2641 const ptr_ty = try pt.singleMutPtrType(Type.fromInterned(fn_info.return_type));
2642 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(pt, ptr_ty));
2643 }
2644 } else {
2645 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(pt, Type.void));
2550 for (enumerators, enum_type.field_names.get(ip), 0..) |*out, field_name, field_index| {
2551 var space: Value.BigIntSpace = undefined;
2552 const field_val: std.math.big.int.Const = switch (enum_type.field_values.len) {
2553 0 => std.math.big.int.Mutable.init(&space.limbs, field_index).toConst(),
2554 else => Value.fromInterned(enum_type.field_values.get(ip)[field_index]).toBigInt(&space, zcu),
2555 };
2556 out.* = try o.builder.debugEnumerator(
2557 try o.builder.metadataString(field_name.toSlice(ip)),
2558 int_info.signedness == .unsigned,
2559 int_info.bits,
2560 field_val,
2561 );
26462562 }
26472563
2648 if (fn_info.cc == .auto and zcu.comp.config.any_error_tracing) {
2649 // Stack trace pointer.
2650 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(pt, .fromInterned(.ptr_usize_type)));
2564 const debug_enum_type = try o.builder.debugEnumerationType(
2565 name,
2566 file,
2567 scope,
2568 line,
2569 try o.getDebugType(pt, int_ty),
2570 ty.abiSize(zcu) * 8,
2571 ty.abiAlignment(zcu).toByteUnits().? * 8,
2572 try o.builder.metadataTuple(enumerators),
2573 );
2574 try o.debug_enums.append(gpa, debug_enum_type);
2575 return debug_enum_type;
2576 },
2577 .@"opaque" => {
2578 if (ty.toIntern() == .anyopaque_type) {
2579 return o.builder.debugSignedType(name, 0);
26512580 }
26522581
2653 for (0..fn_info.param_types.len) |i| {
2654 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[i]);
2655 if (!param_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
2582 const file = try o.getDebugFile(pt, ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip));
2583 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|
2584 try o.namespaceToDebugScope(pt, parent_namespace)
2585 else
2586 file;
26562587
2657 if (isByRef(param_ty, zcu)) {
2658 const ptr_ty = try pt.singleMutPtrType(param_ty);
2659 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(pt, ptr_ty));
2660 } else {
2661 debug_param_types.appendAssumeCapacity(try o.lowerDebugType(pt, param_ty));
2662 }
2663 }
2588 const line = ty.typeDeclSrcLine(zcu).? + 1;
26642589
2665 const debug_function_type = try o.builder.debugSubroutineType(
2666 try o.builder.metadataTuple(debug_param_types.items),
2590 return o.builder.debugStructType(
2591 name,
2592 file,
2593 scope,
2594 line,
2595 null, // underlying type
2596 0, // size
2597 ty.abiAlignment(zcu).toByteUnits().? * 8,
2598 null, // fields
26672599 );
2668
2669 try o.debug_type_map.put(gpa, ty.toIntern(), debug_function_type);
2670 return debug_function_type;
26712600 },
2672 .comptime_int => unreachable,
2673 .comptime_float => unreachable,
2674 .type => unreachable,
2675 .undefined => unreachable,
2676 .null => unreachable,
2677 .enum_literal => unreachable,
2678
26792601 .frame => @panic("TODO implement lowerDebugType for Frame types"),
26802602 .@"anyframe" => @panic("TODO implement lowerDebugType for AnyFrame types"),
26812603 }
26822604 }
26832605
2684 fn namespaceToDebugScope(o: *Object, pt: Zcu.PerThread, namespace_index: InternPool.NamespaceIndex) !Builder.Metadata {
2606 /// Called in `emit` so that the global error set is fully populated.
2607 fn lowerDebugAnyerrorType(o: *Object, pt: Zcu.PerThread) Allocator.Error!Builder.Metadata {
26852608 const zcu = pt.zcu;
2686 const namespace = zcu.namespacePtr(namespace_index);
2687 if (namespace.parent == .none) return try o.getDebugFile(pt, namespace.file_scope);
2609 const ip = &zcu.intern_pool;
2610 const gpa = zcu.comp.gpa;
26882611
2689 const gop = try o.debug_unresolved_namespace_scopes.getOrPut(o.gpa, namespace_index);
2612 const error_set_bits = zcu.errorSetBits();
2613 const error_names = ip.global_error_set.getNamesFromMainThread();
26902614
2691 if (!gop.found_existing) gop.value_ptr.* = try o.builder.debugForwardReference();
2615 const enumerators = try gpa.alloc(Builder.Metadata, error_names.len + 1);
2616 defer gpa.free(enumerators);
26922617
2693 return gop.value_ptr.*;
2618 // The value 0 means "no error" in optionals and error unions.
2619 enumerators[0] = try o.builder.debugEnumerator(
2620 try o.builder.metadataString("null"),
2621 true, // unsigned,
2622 error_set_bits,
2623 .{ .limbs = &.{0}, .positive = true }, // zero
2624 );
2625
2626 for (enumerators[1..], error_names, 1..) |*out, error_name, error_value| {
2627 var space: Value.BigIntSpace = undefined;
2628 var bigint: std.math.big.int.Mutable = .init(&space.limbs, error_value);
2629 out.* = try o.builder.debugEnumerator(
2630 try o.builder.metadataStringFmt("error.{f}", .{error_name.fmtId(ip)}),
2631 true, // unsigned
2632 error_set_bits,
2633 bigint.toConst(),
2634 );
2635 }
2636
2637 const debug_enum_type = try o.builder.debugEnumerationType(
2638 try o.builder.metadataString("anyerror"),
2639 null, // file
2640 o.debug_compile_unit.unwrap().?, // scope
2641 0, // line
2642 try o.getDebugType(pt, try pt.intType(.unsigned, error_set_bits)),
2643 Type.anyerror.abiSize(zcu) * 8,
2644 Type.anyerror.abiAlignment(zcu).toByteUnits().? * 8,
2645 try o.builder.metadataTuple(enumerators),
2646 );
2647 try o.debug_enums.append(gpa, debug_enum_type);
2648 return debug_enum_type;
26942649 }
26952650
2696 fn makeEmptyNamespaceDebugType(o: *Object, pt: Zcu.PerThread, ty: Type) !Builder.Metadata {
2651 fn namespaceToDebugScope(o: *Object, pt: Zcu.PerThread, namespace_index: InternPool.NamespaceIndex) !Builder.Metadata {
26972652 const zcu = pt.zcu;
2698 const ip = &zcu.intern_pool;
2699 const file = try o.getDebugFile(pt, ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip));
2700 const scope = if (ty.getParentNamespace(zcu).unwrap()) |parent_namespace|
2701 try o.namespaceToDebugScope(pt, parent_namespace)
2702 else
2703 file;
2704 return o.builder.debugStructType(
2705 try o.builder.metadataString(ty.containerTypeName(ip).toSlice(ip)), // TODO use fully qualified name
2706 file,
2707 scope,
2708 ty.typeDeclSrcLine(zcu).? + 1,
2709 null,
2710 0,
2711 0,
2712 null,
2713 );
2653 const namespace = zcu.namespacePtr(namespace_index);
2654 if (namespace.parent == .none) return try o.getDebugFile(pt, namespace.file_scope);
2655 return o.getDebugType(pt, .fromInterned(namespace.owner_type));
27142656 }
27152657
27162658 fn allocTypeName(o: *Object, pt: Zcu.PerThread, ty: Type) Allocator.Error![:0]const u8 {
......@@ -2804,7 +2746,7 @@ pub const Object = struct {
28042746 function_index.setCallConv(cc_info.llvm_cc, &o.builder);
28052747
28062748 if (cc_info.align_stack) {
2807 try attributes.addFnAttr(.{ .alignstack = .fromByteUnits(target.stackAlignment()) }, &o.builder);
2749 try attributes.addFnAttr(.{ .alignstack = .wrap(.fromByteUnits(target.stackAlignment())) }, &o.builder);
28082750 } else {
28092751 _ = try attributes.removeFnAttr(.alignstack);
28102752 }
......@@ -2885,40 +2827,6 @@ pub const Object = struct {
28852827
28862828 if (fn_info.return_type == .noreturn_type) try attributes.addFnAttr(.noreturn, &o.builder);
28872829
2888 // Add parameter attributes. We handle only the case of extern functions (no body)
2889 // because functions with bodies are handled in `updateFunc`.
2890 if (is_extern) {
2891 var it = iterateParamTypes(o, pt, fn_info);
2892 it.llvm_index = llvm_arg_i;
2893 while (try it.next()) |lowering| switch (lowering) {
2894 .byval => {
2895 const param_index = it.zig_index - 1;
2896 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);
2897 if (!isByRef(param_ty, zcu)) {
2898 try o.addByValParamAttrs(pt, &attributes, param_ty, param_index, fn_info, it.llvm_index - 1);
2899 }
2900 },
2901 .byref => {
2902 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
2903 const param_llvm_ty = try o.lowerType(pt, param_ty);
2904 const alignment = param_ty.abiAlignment(zcu);
2905 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment.toLlvm(), it.byval_attr, param_llvm_ty);
2906 },
2907 .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder),
2908 // No attributes needed for these.
2909 .no_bits,
2910 .abi_sized_int,
2911 .multiple_llvm_types,
2912 .float_array,
2913 .i32_array,
2914 .i64_array,
2915 => continue,
2916
2917 .slice => unreachable, // extern functions do not support slice types.
2918
2919 };
2920 }
2921
29222830 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);
29232831 return function_index;
29242832 }
......@@ -3223,7 +3131,7 @@ pub const Object = struct {
32233131 ),
32243132 .opt_type => |child_ty| {
32253133 // Must stay in sync with `opt_payload` logic in `lowerPtr`.
3226 if (!Type.fromInterned(child_ty).hasRuntimeBitsIgnoreComptime(zcu)) return .i8;
3134 if (!Type.fromInterned(child_ty).hasRuntimeBits(zcu)) return .i8;
32273135
32283136 const payload_ty = try o.lowerType(pt, Type.fromInterned(child_ty));
32293137 if (t.optionalReprIsPayload(zcu)) return payload_ty;
......@@ -3245,7 +3153,7 @@ pub const Object = struct {
32453153 // Must stay in sync with `codegen.errUnionPayloadOffset`.
32463154 // See logic in `lowerPtr`.
32473155 const error_type = try o.errorIntType(pt);
3248 if (!Type.fromInterned(error_union_type.payload_type).hasRuntimeBitsIgnoreComptime(zcu))
3156 if (!Type.fromInterned(error_union_type.payload_type).hasRuntimeBits(zcu))
32493157 return error_type;
32503158 const payload_type = try o.lowerType(pt, Type.fromInterned(error_union_type.payload_type));
32513159
......@@ -3287,7 +3195,7 @@ pub const Object = struct {
32873195 const struct_type = ip.loadStructType(t.toIntern());
32883196
32893197 if (struct_type.layout == .@"packed") {
3290 const int_ty = try o.lowerType(pt, Type.fromInterned(struct_type.backingIntTypeUnordered(ip)));
3198 const int_ty = try o.lowerType(pt, .fromInterned(struct_type.packed_backing_int_type));
32913199 try o.type_map.put(o.gpa, t.toIntern(), int_ty);
32923200 return int_ty;
32933201 }
......@@ -3301,18 +3209,20 @@ pub const Object = struct {
33013209
33023210 comptime assert(struct_layout_version == 2);
33033211 var offset: u64 = 0;
3304 var big_align: InternPool.Alignment = .@"1";
33053212 var struct_kind: Builder.Type.Structure.Kind = .normal;
33063213 // When we encounter a zero-bit field, we place it here so we know to map it to the next non-zero-bit field (if any).
33073214 var it = struct_type.iterateRuntimeOrder(ip);
3215 var max_field_ty_align: InternPool.Alignment = .@"1";
33083216 while (it.next()) |field_index| {
33093217 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
3310 const field_align = t.fieldAlignment(field_index, zcu);
33113218 const field_ty_align = field_ty.abiAlignment(zcu);
3312 if (field_align.compare(.lt, field_ty_align)) struct_kind = .@"packed";
3313 big_align = big_align.max(field_align);
3219 max_field_ty_align = max_field_ty_align.maxStrict(field_ty_align);
3220
33143221 const prev_offset = offset;
3315 offset = field_align.forward(offset);
3222 offset = struct_type.field_offsets.get(ip)[field_index];
3223 if (@ctz(offset) < field_ty_align.toLog2Units()) {
3224 struct_kind = .@"packed"; // prevent unexpected padding before this field
3225 }
33163226
33173227 const padding_len = offset - prev_offset;
33183228 if (padding_len > 0) try llvm_field_types.append(
......@@ -3320,11 +3230,11 @@ pub const Object = struct {
33203230 try o.builder.arrayType(padding_len, .i8),
33213231 );
33223232
3323 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
3233 if (!field_ty.hasRuntimeBits(zcu)) {
33243234 // This is a zero-bit field. If there are runtime bits after this field,
33253235 // map to the next LLVM field (which we know exists): otherwise, don't
33263236 // map the field, indicating it's at the end of the struct.
3327 if (offset != struct_type.sizeUnordered(ip)) {
3237 if (offset != struct_type.size) {
33283238 try o.struct_field_map.put(o.gpa, .{
33293239 .struct_ty = t.toIntern(),
33303240 .field_index = field_index,
......@@ -3343,12 +3253,15 @@ pub const Object = struct {
33433253 }
33443254 {
33453255 const prev_offset = offset;
3346 offset = big_align.forward(offset);
3256 offset = struct_type.alignment.forward(offset);
33473257 const padding_len = offset - prev_offset;
33483258 if (padding_len > 0) try llvm_field_types.append(
33493259 o.gpa,
33503260 try o.builder.arrayType(padding_len, .i8),
33513261 );
3262 if (@ctz(offset) < max_field_ty_align.toLog2Units()) {
3263 struct_kind = .@"packed"; // prevent unexpected trailing padding
3264 }
33523265 }
33533266
33543267 const ty = try o.builder.opaqueType(try o.builder.string(t.containerTypeName(ip).toSlice(ip)));
......@@ -3391,7 +3304,7 @@ pub const Object = struct {
33913304 o.gpa,
33923305 try o.builder.arrayType(padding_len, .i8),
33933306 );
3394 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) {
3307 if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) {
33953308 // This is a zero-bit field. If there are runtime bits after this field,
33963309 // map to the next LLVM field (which we know exists): otherwise, don't
33973310 // map the field, indicating it's at the end of the struct.
......@@ -3426,16 +3339,17 @@ pub const Object = struct {
34263339 if (o.type_map.get(t.toIntern())) |value| return value;
34273340
34283341 const union_obj = ip.loadUnionType(t.toIntern());
3429 const layout = Type.getUnionLayout(union_obj, zcu);
34303342
3431 if (union_obj.flagsUnordered(ip).layout == .@"packed") {
3432 const int_ty = try o.builder.intType(@intCast(t.bitSize(zcu)));
3343 if (union_obj.layout == .@"packed") {
3344 const int_ty = try o.lowerType(pt, .fromInterned(union_obj.packed_backing_int_type));
34333345 try o.type_map.put(o.gpa, t.toIntern(), int_ty);
34343346 return int_ty;
34353347 }
34363348
3349 const layout = Type.getUnionLayout(union_obj, zcu);
3350
34373351 if (layout.payload_size == 0) {
3438 const enum_tag_ty = try o.lowerType(pt, Type.fromInterned(union_obj.enum_tag_ty));
3352 const enum_tag_ty = try o.lowerType(pt, .fromInterned(union_obj.enum_tag_type));
34393353 try o.type_map.put(o.gpa, t.toIntern(), enum_tag_ty);
34403354 return enum_tag_ty;
34413355 }
......@@ -3467,7 +3381,7 @@ pub const Object = struct {
34673381 );
34683382 return ty;
34693383 }
3470 const enum_tag_ty = try o.lowerType(pt, Type.fromInterned(union_obj.enum_tag_ty));
3384 const enum_tag_ty = try o.lowerType(pt, .fromInterned(union_obj.enum_tag_type));
34713385
34723386 // Put the tag before or after the payload depending on which one's
34733387 // alignment is greater.
......@@ -3502,7 +3416,7 @@ pub const Object = struct {
35023416 }
35033417 return gop.value_ptr.*;
35043418 },
3505 .enum_type => try o.lowerType(pt, Type.fromInterned(ip.loadEnumType(t.toIntern()).tag_ty)),
3419 .enum_type => try o.lowerType(pt, t.intTagType(zcu)),
35063420 .func_type => |func_type| try o.lowerTypeFn(pt, func_type),
35073421 .error_set_type, .inferred_error_set_type => try o.errorIntType(pt),
35083422 // values, not types
......@@ -3516,13 +3430,13 @@ pub const Object = struct {
35163430 .error_union,
35173431 .enum_literal,
35183432 .enum_tag,
3519 .empty_enum_value,
35203433 .float,
35213434 .ptr,
35223435 .slice,
35233436 .opt,
35243437 .aggregate,
35253438 .un,
3439 .bitpack,
35263440 // memoization, not types
35273441 .memoized_call,
35283442 => unreachable,
......@@ -3530,20 +3444,6 @@ pub const Object = struct {
35303444 };
35313445 }
35323446
3533 /// Use this instead of lowerType when you want to handle correctly the case of elem_ty
3534 /// being a zero bit type, but it should still be lowered as an i8 in such case.
3535 /// There are other similar cases handled here as well.
3536 fn lowerPtrElemTy(o: *Object, pt: Zcu.PerThread, elem_ty: Type) Allocator.Error!Builder.Type {
3537 const zcu = pt.zcu;
3538 const lower_elem_ty = switch (elem_ty.zigTypeTag(zcu)) {
3539 .@"opaque" => true,
3540 .@"fn" => !zcu.typeToFunc(elem_ty).?.is_generic,
3541 .array => elem_ty.childType(zcu).hasRuntimeBitsIgnoreComptime(zcu),
3542 else => elem_ty.hasRuntimeBitsIgnoreComptime(zcu),
3543 };
3544 return if (lower_elem_ty) try o.lowerType(pt, elem_ty) else .i8;
3545 }
3546
35473447 fn lowerTypeFn(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {
35483448 const zcu = pt.zcu;
35493449 const ip = &zcu.intern_pool;
......@@ -3558,9 +3458,9 @@ pub const Object = struct {
35583458 }
35593459
35603460 if (fn_info.cc == .auto and zcu.comp.config.any_error_tracing) {
3561 const stack_trace_ty = zcu.builtin_decl_values.get(.StackTrace);
3562 const ptr_ty = try pt.ptrType(.{ .child = stack_trace_ty });
3563 try llvm_params.append(o.gpa, try o.lowerType(pt, ptr_ty));
3461 // First parameter is a pointer to `std.builtin.StackTrace`.
3462 const llvm_ptr_ty = try o.builder.ptrType(toLlvmAddressSpace(.generic, target));
3463 try llvm_params.append(o.gpa, llvm_ptr_ty);
35643464 }
35653465
35663466 var it = iterateParamTypes(o, pt, fn_info);
......@@ -3610,84 +3510,6 @@ pub const Object = struct {
36103510 );
36113511 }
36123512
3613 fn lowerValueToInt(o: *Object, pt: Zcu.PerThread, llvm_int_ty: Builder.Type, arg_val: InternPool.Index) Error!Builder.Constant {
3614 const zcu = pt.zcu;
3615 const ip = &zcu.intern_pool;
3616 const target = zcu.getTarget();
3617
3618 const val = Value.fromInterned(arg_val);
3619 const val_key = ip.indexToKey(val.toIntern());
3620
3621 if (val.isUndef(zcu)) return o.builder.undefConst(llvm_int_ty);
3622
3623 const ty = Type.fromInterned(val_key.typeOf());
3624 switch (val_key) {
3625 .@"extern" => |@"extern"| {
3626 const function_index = try o.resolveLlvmFunction(pt, @"extern".owner_nav);
3627 const ptr = function_index.ptrConst(&o.builder).global.toConst();
3628 return o.builder.convConst(ptr, llvm_int_ty);
3629 },
3630 .func => |func| {
3631 const function_index = try o.resolveLlvmFunction(pt, func.owner_nav);
3632 const ptr = function_index.ptrConst(&o.builder).global.toConst();
3633 return o.builder.convConst(ptr, llvm_int_ty);
3634 },
3635 .ptr => return o.builder.convConst(try o.lowerPtr(pt, arg_val, 0), llvm_int_ty),
3636 .aggregate => switch (ip.indexToKey(ty.toIntern())) {
3637 .struct_type, .vector_type => {},
3638 else => unreachable,
3639 },
3640 .un => |un| {
3641 const layout = ty.unionGetLayout(zcu);
3642 if (layout.payload_size == 0) return o.lowerValue(pt, un.tag);
3643
3644 const union_obj = zcu.typeToUnion(ty).?;
3645 const container_layout = union_obj.flagsUnordered(ip).layout;
3646
3647 assert(container_layout == .@"packed");
3648
3649 var need_unnamed = false;
3650 if (un.tag == .none) {
3651 assert(layout.tag_size == 0);
3652 const union_val = try o.lowerValueToInt(pt, llvm_int_ty, un.val);
3653
3654 need_unnamed = true;
3655 return union_val;
3656 }
3657 const field_index = zcu.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;
3658 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
3659 if (!field_ty.hasRuntimeBits(zcu)) return o.builder.intConst(llvm_int_ty, 0);
3660 return o.lowerValueToInt(pt, llvm_int_ty, un.val);
3661 },
3662 .simple_value => |simple_value| switch (simple_value) {
3663 .false, .true => {},
3664 else => unreachable,
3665 },
3666 .int,
3667 .float,
3668 .enum_tag,
3669 => {},
3670 .opt => {}, // pointer like optional expected
3671 else => unreachable,
3672 }
3673 var stack = std.heap.stackFallback(32, o.gpa);
3674 const allocator = stack.get();
3675
3676 const bits: usize = @intCast(ty.bitSize(zcu));
3677
3678 const buffer = try allocator.alloc(u8, (bits + 7) / 8);
3679 defer allocator.free(buffer);
3680 const limbs = try allocator.alloc(std.math.big.Limb, std.math.big.int.calcTwosCompLimbCount(bits));
3681 defer allocator.free(limbs);
3682
3683 val.writeToPackedMemory(ty, pt, buffer, 0) catch unreachable;
3684
3685 var big: std.math.big.int.Mutable = .init(limbs, 0);
3686 big.readTwosComplement(buffer, bits, target.cpu.arch.endian(), .unsigned);
3687
3688 return o.builder.bigIntConst(llvm_int_ty, big.toConst());
3689 }
3690
36913513 fn lowerValue(o: *Object, pt: Zcu.PerThread, arg_val: InternPool.Index) Error!Builder.Constant {
36923514 const zcu = pt.zcu;
36933515 const ip = &zcu.intern_pool;
......@@ -3700,7 +3522,9 @@ pub const Object = struct {
37003522 return o.builder.undefConst(try o.lowerType(pt, Type.fromInterned(val_key.typeOf())));
37013523 }
37023524
3703 const ty = Type.fromInterned(val_key.typeOf());
3525 const ty: Type = .fromInterned(val_key.typeOf());
3526 ty.assertHasLayout(zcu);
3527
37043528 return switch (val_key) {
37053529 .int_type,
37063530 .ptr_type,
......@@ -3722,10 +3546,8 @@ pub const Object = struct {
37223546
37233547 .undef => unreachable, // handled above
37243548 .simple_value => |simple_value| switch (simple_value) {
3725 .undefined => unreachable, // non-runtime value
37263549 .void => unreachable, // non-runtime value
37273550 .null => unreachable, // non-runtime value
3728 .empty_tuple => unreachable, // non-runtime value
37293551 .@"unreachable" => unreachable, // non-runtime value
37303552
37313553 .false => .false,
......@@ -3733,7 +3555,6 @@ pub const Object = struct {
37333555 },
37343556 .variable,
37353557 .enum_literal,
3736 .empty_enum_value,
37373558 => unreachable, // non-runtime values
37383559 .@"extern" => |@"extern"| {
37393560 const function_index = try o.resolveLlvmFunction(pt, @"extern".owner_nav);
......@@ -3763,7 +3584,7 @@ pub const Object = struct {
37633584 };
37643585 const err_int_ty = try pt.errorIntType();
37653586 const payload_type = ty.errorUnionPayload(zcu);
3766 if (!payload_type.hasRuntimeBitsIgnoreComptime(zcu)) {
3587 if (!payload_type.hasRuntimeBits(zcu)) {
37673588 // We use the error type directly as the type.
37683589 return o.lowerValue(pt, err_val);
37693590 }
......@@ -3825,7 +3646,7 @@ pub const Object = struct {
38253646 const payload_ty = ty.optionalChild(zcu);
38263647
38273648 const non_null_bit = try o.builder.intConst(.i8, @intFromBool(opt.val != .none));
3828 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
3649 if (!payload_ty.hasRuntimeBits(zcu)) {
38293650 return non_null_bit;
38303651 }
38313652 const llvm_ty = try o.lowerType(pt, ty);
......@@ -3861,6 +3682,7 @@ pub const Object = struct {
38613682 fields[0..llvm_ty_fields.len],
38623683 ), vals[0..llvm_ty_fields.len]);
38633684 },
3685 .bitpack => |bitpack| return o.lowerValue(pt, bitpack.backing_int_val),
38643686 .aggregate => |aggregate| switch (ip.indexToKey(ty.toIntern())) {
38653687 .array_type => |array_type| switch (aggregate.storage) {
38663688 .bytes => |bytes| try o.builder.stringConst(try o.builder.string(
......@@ -3992,7 +3814,7 @@ pub const Object = struct {
39923814 0..,
39933815 ) |field_ty, field_val, field_index| {
39943816 if (field_val != .none) continue;
3995 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) continue;
3817 if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue;
39963818
39973819 const field_align = Type.fromInterned(field_ty).abiAlignment(zcu);
39983820 big_align = big_align.max(field_align);
......@@ -4038,16 +3860,8 @@ pub const Object = struct {
40383860 },
40393861 .struct_type => {
40403862 const struct_type = ip.loadStructType(ty.toIntern());
4041 assert(struct_type.haveLayout(ip));
40423863 const struct_ty = try o.lowerType(pt, ty);
4043 if (struct_type.layout == .@"packed") {
4044 comptime assert(Type.packed_struct_layout_version == 2);
4045
4046 const bits = ty.bitSize(zcu);
4047 const llvm_int_ty = try o.builder.intType(@intCast(bits));
4048
4049 return o.lowerValueToInt(pt, llvm_int_ty, arg_val);
4050 }
3864 assert(struct_type.layout != .@"packed");
40513865 const llvm_len = struct_ty.aggregateLen(&o.builder);
40523866
40533867 const ExpectedContents = extern struct {
......@@ -4067,15 +3881,12 @@ pub const Object = struct {
40673881 comptime assert(struct_layout_version == 2);
40683882 var llvm_index: usize = 0;
40693883 var offset: u64 = 0;
4070 var big_align: InternPool.Alignment = .@"1";
40713884 var need_unnamed = false;
40723885 var field_it = struct_type.iterateRuntimeOrder(ip);
40733886 while (field_it.next()) |field_index| {
40743887 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
4075 const field_align = ty.fieldAlignment(field_index, zcu);
4076 big_align = big_align.max(field_align);
40773888 const prev_offset = offset;
4078 offset = field_align.forward(offset);
3889 offset = struct_type.field_offsets.get(ip)[field_index];
40793890
40803891 const padding_len = offset - prev_offset;
40813892 if (padding_len > 0) {
......@@ -4088,7 +3899,7 @@ pub const Object = struct {
40883899 llvm_index += 1;
40893900 }
40903901
4091 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
3902 if (!field_ty.hasRuntimeBits(zcu)) {
40923903 // This is a zero-bit field - we only needed it for the alignment.
40933904 continue;
40943905 }
......@@ -4106,7 +3917,7 @@ pub const Object = struct {
41063917 }
41073918 {
41083919 const prev_offset = offset;
4109 offset = big_align.forward(offset);
3920 offset = struct_type.alignment.forward(offset);
41103921 const padding_len = offset - prev_offset;
41113922 if (padding_len > 0) {
41123923 fields[llvm_index] = try o.builder.arrayType(padding_len, .i8);
......@@ -4130,19 +3941,13 @@ pub const Object = struct {
41303941 if (layout.payload_size == 0) return o.lowerValue(pt, un.tag);
41313942
41323943 const union_obj = zcu.typeToUnion(ty).?;
4133 const container_layout = union_obj.flagsUnordered(ip).layout;
3944 const container_layout = union_obj.layout;
3945 assert(container_layout != .@"packed");
41343946
41353947 var need_unnamed = false;
41363948 const payload = if (un.tag != .none) p: {
41373949 const field_index = zcu.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;
41383950 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
4139 if (container_layout == .@"packed") {
4140 if (!field_ty.hasRuntimeBits(zcu)) return o.builder.intConst(union_ty, 0);
4141 const bits = ty.bitSize(zcu);
4142 const llvm_int_ty = try o.builder.intType(@intCast(bits));
4143
4144 return o.lowerValueToInt(pt, llvm_int_ty, arg_val);
4145 }
41463951
41473952 // Sometimes we must make an unnamed struct because LLVM does
41483953 // not support bitcasting our payload struct to the true union payload type.
......@@ -4150,14 +3955,14 @@ pub const Object = struct {
41503955 // must pointer cast to the expected type before accessing the union.
41513956 need_unnamed = layout.most_aligned_field != field_index;
41523957
4153 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
3958 if (!field_ty.hasRuntimeBits(zcu)) {
41543959 const padding_len = layout.payload_size;
41553960 break :p try o.builder.undefConst(try o.builder.arrayType(padding_len, .i8));
41563961 }
41573962 const payload = try o.lowerValue(pt, un.val);
41583963 const payload_ty = payload.typeOf(&o.builder);
41593964 if (payload_ty != union_ty.structFields(&o.builder)[
4160 @intFromBool(layout.tag_align.compare(.gte, layout.payload_align))
3965 @intFromBool(layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align))
41613966 ]) need_unnamed = true;
41623967 const field_size = field_ty.abiSize(zcu);
41633968 if (field_size == layout.payload_size) break :p payload;
......@@ -4169,13 +3974,6 @@ pub const Object = struct {
41693974 );
41703975 } else p: {
41713976 assert(layout.tag_size == 0);
4172 if (container_layout == .@"packed") {
4173 const bits = ty.bitSize(zcu);
4174 const llvm_int_ty = try o.builder.intType(@intCast(bits));
4175
4176 return o.lowerValueToInt(pt, llvm_int_ty, arg_val);
4177 }
4178
41793977 const union_val = try o.lowerValue(pt, un.val);
41803978 need_unnamed = true;
41813979 break :p union_val;
......@@ -4277,7 +4075,14 @@ pub const Object = struct {
42774075 };
42784076 return o.lowerPtr(pt, field.base, offset + field_off);
42794077 },
4280 .arr_elem, .comptime_field, .comptime_alloc => unreachable,
4078 .arr_elem => |arr_elem| {
4079 const base_ptr_ty = Value.fromInterned(arr_elem.base).typeOf(zcu);
4080 assert(base_ptr_ty.ptrSize(zcu) == .many);
4081 const elem_size = base_ptr_ty.childType(zcu).abiSize(zcu);
4082 return o.lowerPtr(pt, arr_elem.base, offset + elem_size * arr_elem.index);
4083 },
4084 .comptime_field => unreachable,
4085 .comptime_alloc => unreachable,
42814086 };
42824087 }
42834088
......@@ -4302,12 +4107,11 @@ pub const Object = struct {
43024107
43034108 const ptr_ty = Type.fromInterned(uav.orig_ty);
43044109
4305 const is_fn_body = uav_ty.zigTypeTag(zcu) == .@"fn";
4306 if ((!is_fn_body and !uav_ty.hasRuntimeBits(zcu)) or
4307 (is_fn_body and zcu.typeToFunc(uav_ty).?.is_generic)) return o.lowerPtrToVoid(pt, ptr_ty);
4110 if (!uav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) {
4111 return o.lowerPtrToVoid(pt, ptr_ty);
4112 }
43084113
4309 if (is_fn_body)
4310 @panic("TODO");
4114 assert(uav_ty.zigTypeTag(zcu) != .@"fn"); // should be using a Nav ref
43114115
43124116 const llvm_addr_space = toLlvmAddressSpace(ptr_ty.ptrAddressSpace(zcu), target);
43134117 const alignment = ptr_ty.ptrAlignment(zcu);
......@@ -4330,14 +4134,11 @@ pub const Object = struct {
43304134 const nav_ty = Type.fromInterned(nav.typeOf(ip));
43314135 const ptr_ty = try pt.navPtrType(nav_index);
43324136
4333 const is_fn_body = nav_ty.zigTypeTag(zcu) == .@"fn";
4334 if ((!is_fn_body and !nav_ty.hasRuntimeBits(zcu)) or
4335 (is_fn_body and zcu.typeToFunc(nav_ty).?.is_generic))
4336 {
4137 if (nav.getExtern(ip) == null and !nav_ty.isRuntimeFnOrHasRuntimeBits(zcu)) {
43374138 return o.lowerPtrToVoid(pt, ptr_ty);
43384139 }
43394140
4340 const llvm_global = if (is_fn_body)
4141 const llvm_global = if (nav_ty.zigTypeTag(zcu) == .@"fn")
43414142 (try o.resolveLlvmFunction(pt, nav_index)).ptrConst(&o.builder).global
43424143 else
43434144 (try o.resolveGlobalNav(pt, nav_index)).ptrConst(&o.builder).global;
......@@ -4380,21 +4181,18 @@ pub const Object = struct {
43804181 /// types to work around a LLVM deficiency when targeting ARM/AArch64.
43814182 fn getAtomicAbiType(o: *Object, pt: Zcu.PerThread, ty: Type, is_rmw_xchg: bool) Allocator.Error!Builder.Type {
43824183 const zcu = pt.zcu;
4383 const ip = &zcu.intern_pool;
4384 const int_ty = switch (ty.zigTypeTag(zcu)) {
4385 .int => ty,
4386 .@"enum" => ty.intTagType(zcu),
4387 .@"struct" => Type.fromInterned(ip.loadStructType(ty.toIntern()).backingIntTypeUnordered(ip)),
4184 switch (ty.zigTypeTag(zcu)) {
4185 .int, .@"enum", .@"struct", .@"union" => {},
43884186 .float => {
43894187 if (!is_rmw_xchg) return .none;
43904188 return o.builder.intType(@intCast(ty.abiSize(zcu) * 8));
43914189 },
43924190 .bool => return .i8,
43934191 else => return .none,
4394 };
4395 const bit_count = int_ty.intInfo(zcu).bits;
4192 }
4193 const bit_count = ty.bitSize(zcu);
43964194 if (!std.math.isPowerOfTwo(bit_count) or (bit_count % 8) != 0) {
4397 return o.builder.intType(@intCast(int_ty.abiSize(zcu) * 8));
4195 return o.builder.intType(@intCast(ty.abiSize(zcu) * 8));
43984196 } else {
43994197 return .none;
44004198 }
......@@ -4435,11 +4233,11 @@ pub const Object = struct {
44354233 if (ptr_info.flags.is_const) {
44364234 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);
44374235 }
4438 const elem_align = if (ptr_info.flags.alignment != .none)
4439 ptr_info.flags.alignment
4440 else
4441 Type.fromInterned(ptr_info.child).abiAlignment(zcu).max(.@"1");
4442 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align.toLlvm() }, &o.builder);
4236 const elem_align: Builder.Alignment.Lazy = switch (ptr_info.flags.alignment) {
4237 else => |a| .wrap(a.toLlvm()),
4238 .none => try o.lazyAbiAlignment(pt, .fromInterned(ptr_info.child)),
4239 };
4240 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);
44434241 } else if (ccAbiPromoteInt(fn_info.cc, zcu, param_ty)) |s| switch (s) {
44444242 .signed => try attributes.addParamAttr(llvm_arg_i, .signext, &o.builder),
44454243 .unsigned => try attributes.addParamAttr(llvm_arg_i, .zeroext, &o.builder),
......@@ -4456,7 +4254,7 @@ pub const Object = struct {
44564254 ) Allocator.Error!void {
44574255 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);
44584256 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);
4459 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = alignment }, &o.builder);
4257 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = .wrap(alignment) }, &o.builder);
44604258 if (byval) try attributes.addParamAttr(llvm_arg_i, .{ .byval = param_llvm_ty }, &o.builder);
44614259 }
44624260
......@@ -4502,7 +4300,7 @@ pub const Object = struct {
45024300 const ret_ty = try o.lowerType(pt, Type.slice_const_u8_sentinel_0);
45034301 const target = &zcu.root_mod.resolved_target.result;
45044302 const function_index = try o.builder.addFunction(
4505 try o.builder.fnType(ret_ty, &.{try o.lowerType(pt, Type.fromInterned(enum_type.tag_ty))}, .normal),
4303 try o.builder.fnType(ret_ty, &.{try o.lowerType(pt, Type.fromInterned(enum_type.int_tag_type))}, .normal),
45064304 try o.builder.strtabStringFmt("__zig_tag_name_{f}", .{enum_type.name.fmt(ip)}),
45074305 toLlvmAddressSpace(.generic, target),
45084306 );
......@@ -4525,12 +4323,16 @@ pub const Object = struct {
45254323
45264324 const bad_value_block = try wip.block(1, "BadValue");
45274325 const tag_int_value = wip.arg(0);
4528 var wip_switch =
4529 try wip.@"switch"(tag_int_value, bad_value_block, @intCast(enum_type.names.len), .none);
4326 var wip_switch = try wip.@"switch"(
4327 tag_int_value,
4328 bad_value_block,
4329 @intCast(enum_type.field_names.len),
4330 .none,
4331 );
45304332 defer wip_switch.finish(&wip);
45314333
4532 for (0..enum_type.names.len) |field_index| {
4533 const name = try o.builder.stringNull(enum_type.names.get(ip)[field_index].toSlice(ip));
4334 for (0..enum_type.field_names.len) |field_index| {
4335 const name = try o.builder.stringNull(enum_type.field_names.get(ip)[field_index].toSlice(ip));
45344336 const name_init = try o.builder.stringConst(name);
45354337 const name_variable_index =
45364338 try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default);
......@@ -4562,6 +4364,11 @@ pub const Object = struct {
45624364 try wip.finish();
45634365 return function_index;
45644366 }
4367
4368 fn lazyAbiAlignment(o: *Object, pt: Zcu.PerThread, ty: Type) Allocator.Error!Builder.Alignment.Lazy {
4369 const index = try o.type_pool.get(pt, .{ .llvm = o }, ty.toIntern());
4370 return o.lazy_abi_aligns.items[@intFromEnum(index)];
4371 }
45654372};
45664373
45674374pub const NavGen = struct {
......@@ -4601,10 +4408,44 @@ pub const NavGen = struct {
46014408 const ty = Type.fromInterned(nav.typeOf(ip));
46024409
46034410 if (linkage != .internal and ip.isFunctionType(ty.toIntern())) {
4604 _ = try o.resolveLlvmFunction(pt, owner_nav);
4411 const function_index = try o.resolveLlvmFunction(pt, owner_nav);
4412 // Add parameter attributes which weren't set by `resolveLlvmFunction`
4413 const fn_info = zcu.typeToFunc(ty).?;
4414 var attributes = try function_index.ptrConst(&o.builder).attributes.toWip(&o.builder);
4415 defer attributes.deinit(&o.builder);
4416 var it = iterateParamTypes(o, pt, fn_info);
4417 if (firstParamSRet(fn_info, zcu, zcu.getTarget())) it.llvm_index += 1;
4418 if (fn_info.cc == .auto and zcu.comp.config.any_error_tracing) it.llvm_index += 1;
4419 while (try it.next()) |lowering| switch (lowering) {
4420 .byval => {
4421 const param_index = it.zig_index - 1;
4422 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);
4423 if (!isByRef(param_ty, zcu)) {
4424 try o.addByValParamAttrs(pt, &attributes, param_ty, param_index, fn_info, it.llvm_index - 1);
4425 }
4426 },
4427 .byref => {
4428 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
4429 const param_llvm_ty = try o.lowerType(pt, param_ty);
4430 const alignment = param_ty.abiAlignment(zcu);
4431 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment.toLlvm(), it.byval_attr, param_llvm_ty);
4432 },
4433 .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder),
4434 // No attributes needed for these.
4435 .no_bits,
4436 .abi_sized_int,
4437 .multiple_llvm_types,
4438 .float_array,
4439 .i32_array,
4440 .i64_array,
4441 => continue,
4442
4443 .slice => unreachable, // extern functions do not support slice types.
4444 };
4445 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);
46054446 } else {
46064447 const variable_index = try o.resolveGlobalNav(pt, nav_index);
4607 variable_index.setAlignment(pt.navAlignment(nav_index).toLlvm(), &o.builder);
4448 variable_index.setAlignment(zcu.navAlignment(nav_index).toLlvm(), &o.builder);
46084449 if (resolved.@"linksection".toSlice(ip)) |section|
46094450 variable_index.setSection(try o.builder.string(section), &o.builder);
46104451 if (is_const) variable_index.setMutability(.constant, &o.builder);
......@@ -4630,7 +4471,7 @@ pub const NavGen = struct {
46304471 debug_file, // File
46314472 debug_file, // Scope
46324473 line_number,
4633 try o.lowerDebugType(pt, ty),
4474 try o.getDebugType(pt, ty),
46344475 variable_index,
46354476 .{ .local = linkage == .internal },
46364477 );
......@@ -4752,7 +4593,7 @@ pub const FuncGen = struct {
47524593 /// Have we seen loads or stores involving `allowzero` pointers?
47534594 allowzero_access: bool = false,
47544595
4755 pub fn maybeMarkAllowZeroAccess(self: *FuncGen, info: InternPool.Key.PtrType) void {
4596 fn maybeMarkAllowZeroAccess(self: *FuncGen, info: InternPool.Key.PtrType) void {
47564597 // LLVM already considers null pointers to be valid in non-generic address spaces, so avoid
47574598 // pessimizing optimization for functions with accesses to such pointers.
47584599 if (info.flags.address_space == .generic and info.flags.is_allowzero) self.allowzero_access = true;
......@@ -5220,7 +5061,7 @@ pub const FuncGen = struct {
52205061 try o.builder.metadataString(nav.fqn.toSlice(&zcu.intern_pool)),
52215062 line_number,
52225063 line_number + func.lbrace_line,
5223 try o.lowerDebugType(pt, fn_ty),
5064 try o.getDebugType(pt, fn_ty),
52245065 .{
52255066 .di_flags = .{ .StaticMember = true },
52265067 .sp_flags = .{
......@@ -5490,10 +5331,10 @@ pub const FuncGen = struct {
54905331 if (ptr_info.flags.is_const) {
54915332 try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder);
54925333 }
5493 const elem_align = (if (ptr_info.flags.alignment != .none)
5494 @as(InternPool.Alignment, ptr_info.flags.alignment)
5495 else
5496 Type.fromInterned(ptr_info.child).abiAlignment(zcu).max(.@"1")).toLlvm();
5334 const elem_align: Builder.Alignment.Lazy = switch (ptr_info.flags.alignment) {
5335 else => |a| .wrap(a.toLlvm()),
5336 .none => try o.lazyAbiAlignment(pt, .fromInterned(ptr_info.child)),
5337 };
54975338 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);
54985339 },
54995340 };
......@@ -5518,7 +5359,7 @@ pub const FuncGen = struct {
55185359 return .none;
55195360 }
55205361
5521 if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBitsIgnoreComptime(zcu)) {
5362 if (self.liveness.isUnused(inst) or !return_type.hasRuntimeBits(zcu)) {
55225363 return .none;
55235364 }
55245365
......@@ -5637,7 +5478,7 @@ pub const FuncGen = struct {
56375478 return;
56385479 }
56395480 const fn_info = zcu.typeToFunc(Type.fromInterned(ip.getNav(self.ng.nav_index).typeOf(ip))).?;
5640 if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
5481 if (!ret_ty.hasRuntimeBits(zcu)) {
56415482 if (Type.fromInterned(fn_info.return_type).isError(zcu)) {
56425483 // Functions with an empty error set are emitted with an error code
56435484 // return type and return zero so they can be function pointers coerced
......@@ -5702,7 +5543,7 @@ pub const FuncGen = struct {
57025543 const ptr_ty = self.typeOf(un_op);
57035544 const ret_ty = ptr_ty.childType(zcu);
57045545 const fn_info = zcu.typeToFunc(Type.fromInterned(ip.getNav(self.ng.nav_index).typeOf(ip))).?;
5705 if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
5546 if (!ret_ty.hasRuntimeBits(zcu)) {
57065547 if (Type.fromInterned(fn_info.return_type).isError(zcu)) {
57075548 // Functions with an empty error set are emitted with an error code
57085549 // return type and return zero so they can be function pointers coerced
......@@ -5833,14 +5674,13 @@ pub const FuncGen = struct {
58335674 const o = self.ng.object;
58345675 const pt = self.ng.pt;
58355676 const zcu = pt.zcu;
5836 const ip = &zcu.intern_pool;
58375677 const scalar_ty = operand_ty.scalarType(zcu);
58385678 const int_ty = switch (scalar_ty.zigTypeTag(zcu)) {
58395679 .@"enum" => scalar_ty.intTagType(zcu),
58405680 .int, .bool, .pointer, .error_set => scalar_ty,
58415681 .optional => blk: {
58425682 const payload_ty = operand_ty.optionalChild(zcu);
5843 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu) or
5683 if (!payload_ty.hasRuntimeBits(zcu) or
58445684 operand_ty.optionalReprIsPayload(zcu))
58455685 {
58465686 break :blk operand_ty;
......@@ -5912,12 +5752,7 @@ pub const FuncGen = struct {
59125752 return phi.toValue();
59135753 },
59145754 .float => return self.buildFloatCmp(fast, op, operand_ty, .{ lhs, rhs }),
5915 .@"struct" => blk: {
5916 const struct_obj = ip.loadStructType(scalar_ty.toIntern());
5917 assert(struct_obj.layout == .@"packed");
5918 const backing_index = struct_obj.backingIntTypeUnordered(ip);
5919 break :blk Type.fromInterned(backing_index);
5920 },
5755 .@"struct" => scalar_ty.bitpackBackingInt(zcu),
59215756 else => unreachable,
59225757 };
59235758 const is_signed = int_ty.isSignedInt(zcu);
......@@ -5953,7 +5788,7 @@ pub const FuncGen = struct {
59535788 return .none;
59545789 }
59555790
5956 const have_block_result = inst_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu);
5791 const have_block_result = inst_ty.hasRuntimeBits(zcu);
59575792
59585793 var breaks: BreakList = if (have_block_result) .{ .list = .{} } else .{ .len = 0 };
59595794 defer if (have_block_result) breaks.list.deinit(self.gpa);
......@@ -6000,7 +5835,7 @@ pub const FuncGen = struct {
60005835
60015836 // Add the values to the lists only if the break provides a value.
60025837 const operand_ty = self.typeOf(branch.operand);
6003 if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {
5838 if (operand_ty.hasRuntimeBits(zcu)) {
60045839 const val = try self.resolveInst(branch.operand);
60055840
60065841 // For the phi node, we need the basic blocks and the values of the
......@@ -6309,7 +6144,7 @@ pub const FuncGen = struct {
63096144 const pt = fg.ng.pt;
63106145 const zcu = pt.zcu;
63116146 const payload_ty = err_union_ty.errorUnionPayload(zcu);
6312 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(zcu);
6147 const payload_has_bits = payload_ty.hasRuntimeBits(zcu);
63136148 const err_union_llvm_ty = try o.lowerType(pt, err_union_ty);
63146149 const error_type = try o.errorIntType(pt);
63156150
......@@ -6645,7 +6480,7 @@ pub const FuncGen = struct {
66456480 const len = try o.builder.intValue(llvm_usize, array_ty.arrayLen(zcu));
66466481 const slice_llvm_ty = try o.lowerType(pt, self.typeOfIndex(inst));
66476482 const operand = try self.resolveInst(ty_op.operand);
6648 if (!array_ty.hasRuntimeBitsIgnoreComptime(zcu))
6483 if (!array_ty.hasRuntimeBits(zcu))
66496484 return self.wip.buildAggregate(slice_llvm_ty, &.{ operand, len }, "");
66506485 const ptr = try self.wip.gep(.inbounds, try o.lowerType(pt, array_ty), operand, &.{
66516486 try o.builder.intValue(llvm_usize, 0), try o.builder.intValue(llvm_usize, 0),
......@@ -6828,7 +6663,7 @@ pub const FuncGen = struct {
68286663 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
68296664 const slice_ptr = try self.resolveInst(ty_op.operand);
68306665 const slice_ptr_ty = self.typeOf(ty_op.operand);
6831 const slice_llvm_ty = try o.lowerPtrElemTy(pt, slice_ptr_ty.childType(zcu));
6666 const slice_llvm_ty = try o.lowerType(pt, slice_ptr_ty.childType(zcu));
68326667
68336668 return self.wip.gepStruct(slice_llvm_ty, slice_ptr, index, "");
68346669 }
......@@ -6842,7 +6677,7 @@ pub const FuncGen = struct {
68426677 const slice = try self.resolveInst(bin_op.lhs);
68436678 const index = try self.resolveInst(bin_op.rhs);
68446679 const elem_ty = slice_ty.childType(zcu);
6845 const llvm_elem_ty = try o.lowerPtrElemTy(pt, elem_ty);
6680 const llvm_elem_ty = try o.lowerType(pt, elem_ty);
68466681 const base_ptr = try self.wip.extractValue(slice, &.{0}, "");
68476682 const ptr = try self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, "");
68486683 if (isByRef(elem_ty, zcu)) {
......@@ -6867,7 +6702,7 @@ pub const FuncGen = struct {
68676702
68686703 const slice = try self.resolveInst(bin_op.lhs);
68696704 const index = try self.resolveInst(bin_op.rhs);
6870 const llvm_elem_ty = try o.lowerPtrElemTy(pt, slice_ty.childType(zcu));
6705 const llvm_elem_ty = try o.lowerType(pt, slice_ty.childType(zcu));
68716706 const base_ptr = try self.wip.extractValue(slice, &.{0}, "");
68726707 return self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, "");
68736708 }
......@@ -6906,16 +6741,11 @@ pub const FuncGen = struct {
69066741 const zcu = pt.zcu;
69076742 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
69086743 const ptr_ty = self.typeOf(bin_op.lhs);
6909 const elem_ty = ptr_ty.childType(zcu);
6910 const llvm_elem_ty = try o.lowerPtrElemTy(pt, elem_ty);
6744 const elem_ty = ptr_ty.indexableElem(zcu);
6745 const llvm_elem_ty = try o.lowerType(pt, elem_ty);
69116746 const base_ptr = try self.resolveInst(bin_op.lhs);
69126747 const rhs = try self.resolveInst(bin_op.rhs);
6913 // TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch
6914 const ptr = try self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, if (ptr_ty.isSinglePointer(zcu))
6915 // If this is a single-item pointer to an array, we need another index in the GEP.
6916 &.{ try o.builder.intValue(try o.lowerType(pt, Type.usize), 0), rhs }
6917 else
6918 &.{rhs}, "");
6748 const ptr = try self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{rhs}, "");
69196749 if (isByRef(elem_ty, zcu)) {
69206750 self.maybeMarkAllowZeroAccess(ptr_ty.ptrInfo(zcu));
69216751 const ptr_align = (ptr_ty.ptrAlignment(zcu).min(elem_ty.abiAlignment(zcu))).toLlvm();
......@@ -6934,8 +6764,8 @@ pub const FuncGen = struct {
69346764 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
69356765 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
69366766 const ptr_ty = self.typeOf(bin_op.lhs);
6937 const elem_ty = ptr_ty.childType(zcu);
6938 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) return self.resolveInst(bin_op.lhs);
6767 const elem_ty = ptr_ty.indexableElem(zcu);
6768 assert(elem_ty.hasRuntimeBits(zcu));
69396769
69406770 const base_ptr = try self.resolveInst(bin_op.lhs);
69416771 const rhs = try self.resolveInst(bin_op.rhs);
......@@ -6943,12 +6773,8 @@ pub const FuncGen = struct {
69436773 const elem_ptr = ty_pl.ty.toType();
69446774 if (elem_ptr.ptrInfo(zcu).flags.vector_index != .none) return base_ptr;
69456775
6946 const llvm_elem_ty = try o.lowerPtrElemTy(pt, elem_ty);
6947 return self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, if (ptr_ty.isSinglePointer(zcu))
6948 // If this is a single-item pointer to an array, we need another index in the GEP.
6949 &.{ try o.builder.intValue(try o.lowerType(pt, Type.usize), 0), rhs }
6950 else
6951 &.{rhs}, "");
6776 const llvm_elem_ty = try o.lowerType(pt, elem_ty);
6777 return self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{rhs}, "");
69526778 }
69536779
69546780 fn airStructFieldPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
......@@ -6956,7 +6782,7 @@ pub const FuncGen = struct {
69566782 const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data;
69576783 const struct_ptr = try self.resolveInst(struct_field.struct_operand);
69586784 const struct_ptr_ty = self.typeOf(struct_field.struct_operand);
6959 return self.fieldPtr(inst, struct_ptr, struct_ptr_ty, struct_field.field_index);
6785 return self.fieldPtr(struct_ptr, struct_ptr_ty, struct_field.field_index);
69606786 }
69616787
69626788 fn airStructFieldPtrIndex(
......@@ -6967,7 +6793,7 @@ pub const FuncGen = struct {
69676793 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
69686794 const struct_ptr = try self.resolveInst(ty_op.operand);
69696795 const struct_ptr_ty = self.typeOf(ty_op.operand);
6970 return self.fieldPtr(inst, struct_ptr, struct_ptr_ty, field_index);
6796 return self.fieldPtr(struct_ptr, struct_ptr_ty, field_index);
69716797 }
69726798
69736799 fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
......@@ -6980,7 +6806,7 @@ pub const FuncGen = struct {
69806806 const struct_llvm_val = try self.resolveInst(struct_field.struct_operand);
69816807 const field_index = struct_field.field_index;
69826808 const field_ty = struct_ty.fieldType(field_index, zcu);
6983 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) return .none;
6809 if (!field_ty.hasRuntimeBits(zcu)) return .none;
69846810
69856811 if (!isByRef(struct_ty, zcu)) {
69866812 assert(!isByRef(field_ty, zcu));
......@@ -6999,11 +6825,6 @@ pub const FuncGen = struct {
69996825 const truncated_int =
70006826 try self.wip.cast(.trunc, shifted_value, same_size_int, "");
70016827 return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, "");
7002 } else if (field_ty.isPtrAtRuntime(zcu)) {
7003 const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(zcu)));
7004 const truncated_int =
7005 try self.wip.cast(.trunc, shifted_value, same_size_int, "");
7006 return self.wip.cast(.inttoptr, truncated_int, elem_llvm_ty, "");
70076828 }
70086829 return self.wip.cast(.trunc, shifted_value, elem_llvm_ty, "");
70096830 },
......@@ -7021,11 +6842,6 @@ pub const FuncGen = struct {
70216842 const truncated_int =
70226843 try self.wip.cast(.trunc, containing_int, same_size_int, "");
70236844 return self.wip.cast(.bitcast, truncated_int, elem_llvm_ty, "");
7024 } else if (field_ty.isPtrAtRuntime(zcu)) {
7025 const same_size_int = try o.builder.intType(@intCast(field_ty.bitSize(zcu)));
7026 const truncated_int =
7027 try self.wip.cast(.trunc, containing_int, same_size_int, "");
7028 return self.wip.cast(.inttoptr, truncated_int, elem_llvm_ty, "");
70296845 }
70306846 return self.wip.cast(.trunc, containing_int, elem_llvm_ty, "");
70316847 },
......@@ -7041,15 +6857,17 @@ pub const FuncGen = struct {
70416857 const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?;
70426858 const field_ptr =
70436859 try self.wip.gepStruct(struct_llvm_ty, struct_llvm_val, llvm_field_index, "");
7044 const alignment = struct_ty.fieldAlignment(field_index, zcu);
6860 const explicit_alignment = struct_ty.explicitFieldAlignment(field_index, zcu);
70456861 const field_ptr_ty = try pt.ptrType(.{
70466862 .child = field_ty.toIntern(),
7047 .flags = .{ .alignment = alignment },
6863 .flags = .{ .alignment = explicit_alignment },
70486864 });
70496865 if (isByRef(field_ty, zcu)) {
7050 assert(alignment != .none);
7051 const field_alignment = alignment.toLlvm();
7052 return self.loadByRef(field_ptr, field_ty, field_alignment, .normal);
6866 const alignment = switch (explicit_alignment) {
6867 .none => field_ty.abiAlignment(zcu),
6868 else => |a| a,
6869 };
6870 return self.loadByRef(field_ptr, field_ty, alignment.toLlvm(), .normal);
70536871 } else {
70546872 return self.load(field_ptr, field_ptr_ty);
70556873 }
......@@ -7057,7 +6875,7 @@ pub const FuncGen = struct {
70576875 .@"union" => {
70586876 const union_llvm_ty = try o.lowerType(pt, struct_ty);
70596877 const layout = struct_ty.unionGetLayout(zcu);
7060 const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align));
6878 const payload_index = @intFromBool(layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align));
70616879 const field_ptr =
70626880 try self.wip.gepStruct(union_llvm_ty, struct_llvm_val, payload_index, "");
70636881 const payload_alignment = layout.payload_align.toLlvm();
......@@ -7150,7 +6968,7 @@ pub const FuncGen = struct {
71506968 self.file,
71516969 self.scope,
71526970 self.prev_dbg_line,
7153 try o.lowerDebugType(pt, ptr_ty.childType(zcu)),
6971 try o.getDebugType(pt, ptr_ty.childType(zcu)),
71546972 );
71556973
71566974 _ = try self.wip.callIntrinsic(
......@@ -7183,7 +7001,7 @@ pub const FuncGen = struct {
71837001 self.file,
71847002 self.scope,
71857003 self.prev_dbg_line,
7186 try o.lowerDebugType(pt, operand_ty),
7004 try o.getDebugType(pt, operand_ty),
71877005 arg_no: {
71887006 self.arg_inline_index += 1;
71897007 break :arg_no self.arg_inline_index;
......@@ -7193,7 +7011,7 @@ pub const FuncGen = struct {
71937011 self.file,
71947012 self.scope,
71957013 self.prev_dbg_line,
7196 try o.lowerDebugType(pt, operand_ty),
7014 try o.getDebugType(pt, operand_ty),
71977015 );
71987016
71997017 const zcu = pt.zcu;
......@@ -7284,6 +7102,7 @@ pub const FuncGen = struct {
72847102 const llvm_param_attrs = try arena.alloc(Builder.Type, max_param_count);
72857103 const pt = self.ng.pt;
72867104 const zcu = pt.zcu;
7105 const ip = &zcu.intern_pool;
72877106 const target = zcu.getTarget();
72887107
72897108 var llvm_ret_i: usize = 0;
......@@ -7308,7 +7127,7 @@ pub const FuncGen = struct {
73087127 const output_inst = try self.resolveInst(output.operand);
73097128 const output_ty = self.typeOf(output.operand);
73107129 assert(output_ty.zigTypeTag(zcu) == .pointer);
7311 const elem_llvm_ty = try o.lowerPtrElemTy(pt, output_ty.childType(zcu));
7130 const elem_llvm_ty = try o.lowerType(pt, output_ty.childType(zcu));
73127131
73137132 switch (constraint[0]) {
73147133 '=' => {},
......@@ -7426,7 +7245,7 @@ pub const FuncGen = struct {
74267245 llvm_param_attrs[llvm_param_i] = if (constraint[0] == '*') blk: {
74277246 if (!is_by_ref) self.maybeMarkAllowZeroAccess(arg_ty.ptrInfo(zcu));
74287247
7429 break :blk try o.lowerPtrElemTy(pt, if (is_by_ref) arg_ty else arg_ty.childType(zcu));
7248 break :blk try o.lowerType(pt, if (is_by_ref) arg_ty else arg_ty.childType(zcu));
74307249 } else .none;
74317250
74327251 llvm_param_i += 1;
......@@ -7440,7 +7259,7 @@ pub const FuncGen = struct {
74407259 if (constraint[0] != '+') continue;
74417260
74427261 const rw_ty = self.typeOf(output.operand);
7443 const llvm_elem_ty = try o.lowerPtrElemTy(pt, rw_ty.childType(zcu));
7262 const llvm_elem_ty = try o.lowerType(pt, rw_ty.childType(zcu));
74447263 if (llvm_ret_indirect[output.index]) {
74457264 llvm_param_values[llvm_param_i] = llvm_rw_vals[output.index];
74467265 llvm_param_types[llvm_param_i] = llvm_rw_vals[output.index].typeOfWip(&self.wip);
......@@ -7467,30 +7286,21 @@ pub const FuncGen = struct {
74677286 total_i += 1;
74687287 }
74697288
7470 const ip = &zcu.intern_pool;
7471 const aggregate = ip.indexToKey(unwrapped_asm.clobbers).aggregate;
7472 const struct_type: Type = .fromInterned(aggregate.ty);
74737289 if (total_i != 0) try llvm_constraints.append(gpa, ',');
7474 switch (aggregate.storage) {
7475 .elems => |elems| for (elems, 0..) |elem, i| {
7476 switch (elem) {
7477 .bool_true => {
7478 const name = struct_type.structFieldName(i, zcu).toSlice(ip).?;
7479 total_i += try appendConstraints(gpa, &llvm_constraints, name, target);
7480 },
7481 .bool_false => continue,
7482 else => unreachable,
7483 }
7484 },
7485 .repeated_elem => |elem| switch (elem) {
7486 .bool_true => for (0..struct_type.structFieldCount(zcu)) |i| {
7487 const name = struct_type.structFieldName(i, zcu).toSlice(ip).?;
7488 total_i += try appendConstraints(gpa, &llvm_constraints, name, target);
7489 },
7490 .bool_false => {},
7491 else => unreachable,
7492 },
7493 .bytes => @panic("TODO"),
7290 const clobbers_val: Value = .fromInterned(unwrapped_asm.clobbers);
7291 const clobbers_ty = clobbers_val.typeOf(zcu);
7292 var clobbers_bigint_buf: Value.BigIntSpace = undefined;
7293 const clobbers_bigint = clobbers_val.toBigInt(&clobbers_bigint_buf, zcu);
7294 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
7295 assert(clobbers_ty.fieldType(field_index, zcu).toIntern() == .bool_type);
7296 const limb_bits = @bitSizeOf(std.math.big.Limb);
7297 if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
7298 switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
7299 0 => continue, // field is false
7300 1 => {}, // field is true
7301 }
7302 const name = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;
7303 total_i += try appendConstraints(gpa, &llvm_constraints, name, target);
74947304 }
74957305
74967306 // We have finished scanning through all inputs/outputs, so the number of
......@@ -7676,7 +7486,7 @@ pub const FuncGen = struct {
76767486
76777487 comptime assert(optional_layout_version == 3);
76787488
7679 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
7489 if (!payload_ty.hasRuntimeBits(zcu)) {
76807490 const loaded = if (operand_is_ptr)
76817491 try self.wip.load(access_kind, optional_llvm_ty, operand, .default, "")
76827492 else
......@@ -7719,7 +7529,7 @@ pub const FuncGen = struct {
77197529
77207530 if (operand_is_ptr) self.maybeMarkAllowZeroAccess(operand_ty.ptrInfo(zcu));
77217531
7722 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
7532 if (!payload_ty.hasRuntimeBits(zcu)) {
77237533 const loaded = if (operand_is_ptr)
77247534 try self.wip.load(access_kind, try o.lowerType(pt, err_union_ty), operand, .default, "")
77257535 else
......@@ -7746,7 +7556,7 @@ pub const FuncGen = struct {
77467556 const operand = try self.resolveInst(ty_op.operand);
77477557 const optional_ty = self.typeOf(ty_op.operand).childType(zcu);
77487558 const payload_ty = optional_ty.optionalChild(zcu);
7749 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
7559 if (!payload_ty.hasRuntimeBits(zcu)) {
77507560 // We have a pointer to a zero-bit value and we need to return
77517561 // a pointer to a zero-bit value.
77527562 return operand;
......@@ -7774,7 +7584,7 @@ pub const FuncGen = struct {
77747584 const access_kind: Builder.MemoryAccessKind =
77757585 if (optional_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;
77767586
7777 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
7587 if (!payload_ty.hasRuntimeBits(zcu)) {
77787588 self.maybeMarkAllowZeroAccess(optional_ptr_ty.ptrInfo(zcu));
77797589
77807590 // We have a pointer to a i8. We need to set it to 1 and then return the same pointer.
......@@ -7810,7 +7620,7 @@ pub const FuncGen = struct {
78107620 const operand = try self.resolveInst(ty_op.operand);
78117621 const optional_ty = self.typeOf(ty_op.operand);
78127622 const payload_ty = self.typeOfIndex(inst);
7813 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return .none;
7623 if (!payload_ty.hasRuntimeBits(zcu)) return .none;
78147624
78157625 if (optional_ty.optionalReprIsPayload(zcu)) {
78167626 // Payload value is the same as the optional value.
......@@ -7832,7 +7642,7 @@ pub const FuncGen = struct {
78327642 const result_ty = self.typeOfIndex(inst);
78337643 const payload_ty = if (operand_is_ptr) result_ty.childType(zcu) else result_ty;
78347644
7835 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
7645 if (!payload_ty.hasRuntimeBits(zcu)) {
78367646 return if (operand_is_ptr) operand else .none;
78377647 }
78387648 const offset = try errUnionPayloadOffset(payload_ty, pt);
......@@ -7876,7 +7686,7 @@ pub const FuncGen = struct {
78767686 if (operand_is_ptr and operand_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;
78777687
78787688 const payload_ty = err_union_ty.errorUnionPayload(zcu);
7879 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
7689 if (!payload_ty.hasRuntimeBits(zcu)) {
78807690 if (!operand_is_ptr) return operand;
78817691
78827692 self.maybeMarkAllowZeroAccess(operand_ty.ptrInfo(zcu));
......@@ -7912,7 +7722,7 @@ pub const FuncGen = struct {
79127722 const access_kind: Builder.MemoryAccessKind =
79137723 if (err_union_ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal;
79147724
7915 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
7725 if (!payload_ty.hasRuntimeBits(zcu)) {
79167726 self.maybeMarkAllowZeroAccess(err_union_ptr_ty.ptrInfo(zcu));
79177727
79187728 _ = try self.wip.store(access_kind, non_error_val, operand, .default);
......@@ -7959,9 +7769,8 @@ pub const FuncGen = struct {
79597769 const struct_llvm_ty = try o.lowerType(pt, struct_ty);
79607770 const llvm_field_index = o.llvmFieldIndex(struct_ty, field_index).?;
79617771 assert(self.err_ret_trace != .none);
7962 const field_ptr =
7963 try self.wip.gepStruct(struct_llvm_ty, self.err_ret_trace, llvm_field_index, "");
7964 const field_alignment = struct_ty.fieldAlignment(field_index, zcu);
7772 const field_ptr = try self.wip.gepStruct(struct_llvm_ty, self.err_ret_trace, llvm_field_index, "");
7773 const field_alignment = struct_ty.explicitFieldAlignment(field_index, zcu);
79657774 const field_ty = struct_ty.fieldType(field_index, zcu);
79667775 const field_ptr_ty = try pt.ptrType(.{
79677776 .child = field_ty.toIntern(),
......@@ -8002,7 +7811,7 @@ pub const FuncGen = struct {
80027811 const payload_ty = self.typeOf(ty_op.operand);
80037812 const non_null_bit = try o.builder.intValue(.i8, 1);
80047813 comptime assert(optional_layout_version == 3);
8005 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return non_null_bit;
7814 assert(payload_ty.hasRuntimeBits(zcu));
80067815 const operand = try self.resolveInst(ty_op.operand);
80077816 const optional_ty = self.typeOfIndex(inst);
80087817 if (optional_ty.optionalReprIsPayload(zcu)) return operand;
......@@ -8036,9 +7845,7 @@ pub const FuncGen = struct {
80367845 const err_un_ty = self.typeOfIndex(inst);
80377846 const operand = try self.resolveInst(ty_op.operand);
80387847 const payload_ty = self.typeOf(ty_op.operand);
8039 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
8040 return operand;
8041 }
7848 assert(payload_ty.hasRuntimeBits(zcu));
80427849 const ok_err_code = try o.builder.intValue(try o.errorIntType(pt), 0);
80437850 const err_un_llvm_ty = try o.lowerType(pt, err_un_ty);
80447851
......@@ -8078,7 +7885,7 @@ pub const FuncGen = struct {
80787885 const err_un_ty = self.typeOfIndex(inst);
80797886 const payload_ty = err_un_ty.errorUnionPayload(zcu);
80807887 const operand = try self.resolveInst(ty_op.operand);
8081 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return operand;
7888 if (!payload_ty.hasRuntimeBits(zcu)) return operand;
80827889 const err_un_llvm_ty = try o.lowerType(pt, err_un_ty);
80837890
80847891 const payload_offset = try errUnionPayloadOffset(payload_ty, pt);
......@@ -8530,7 +8337,7 @@ pub const FuncGen = struct {
85308337 const ptr = try self.resolveInst(bin_op.lhs);
85318338 const offset = try self.resolveInst(bin_op.rhs);
85328339 const ptr_ty = self.typeOf(bin_op.lhs);
8533 const llvm_elem_ty = try o.lowerPtrElemTy(pt, ptr_ty.childType(zcu));
8340 const llvm_elem_ty = try o.lowerType(pt, ptr_ty.childType(zcu));
85348341 switch (ptr_ty.ptrSize(zcu)) {
85358342 // It's a pointer to an array, so according to LLVM we need an extra GEP index.
85368343 .one => return self.wip.gep(.inbounds, llvm_elem_ty, ptr, &.{
......@@ -8554,7 +8361,7 @@ pub const FuncGen = struct {
85548361 const offset = try self.resolveInst(bin_op.rhs);
85558362 const negative_offset = try self.wip.neg(offset, "");
85568363 const ptr_ty = self.typeOf(bin_op.lhs);
8557 const llvm_elem_ty = try o.lowerPtrElemTy(pt, ptr_ty.childType(zcu));
8364 const llvm_elem_ty = try o.lowerType(pt, ptr_ty.childType(zcu));
85588365 switch (ptr_ty.ptrSize(zcu)) {
85598366 // It's a pointer to an array, so according to LLVM we need an extra GEP index.
85608367 .one => return self.wip.gep(.inbounds, llvm_elem_ty, ptr, &.{
......@@ -9515,7 +9322,7 @@ pub const FuncGen = struct {
95159322 self.file,
95169323 self.scope,
95179324 lbrace_line,
9518 try o.lowerDebugType(pt, inst_ty),
9325 try o.getDebugType(pt, inst_ty),
95199326 self.arg_index,
95209327 );
95219328
......@@ -9581,7 +9388,7 @@ pub const FuncGen = struct {
95819388 const zcu = pt.zcu;
95829389 const ptr_ty = self.typeOfIndex(inst);
95839390 const pointee_type = ptr_ty.childType(zcu);
9584 if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(zcu))
9391 if (!pointee_type.hasRuntimeBits(zcu))
95859392 return (try o.lowerPtrToVoid(pt, ptr_ty)).toValue();
95869393
95879394 const pointee_llvm_ty = try o.lowerType(pt, pointee_type);
......@@ -9595,7 +9402,7 @@ pub const FuncGen = struct {
95959402 const zcu = pt.zcu;
95969403 const ptr_ty = self.typeOfIndex(inst);
95979404 const ret_ty = ptr_ty.childType(zcu);
9598 if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu))
9405 if (!ret_ty.hasRuntimeBits(zcu))
95999406 return (try o.lowerPtrToVoid(pt, ptr_ty)).toValue();
96009407 if (self.ret_ptr != .none) return self.ret_ptr;
96019408 const ret_llvm_ty = try o.lowerType(pt, ret_ty);
......@@ -9849,7 +9656,7 @@ pub const FuncGen = struct {
98499656 const ptr_ty = self.typeOf(atomic_load.ptr);
98509657 const info = ptr_ty.ptrInfo(zcu);
98519658 const elem_ty = Type.fromInterned(info.child);
9852 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) return .none;
9659 if (!elem_ty.hasRuntimeBits(zcu)) return .none;
98539660 const ordering = toLlvmAtomicOrdering(atomic_load.order);
98549661 const llvm_abi_ty = try o.getAtomicAbiType(pt, elem_ty, false);
98559662 const ptr_alignment = (if (info.flags.alignment != .none)
......@@ -9897,7 +9704,7 @@ pub const FuncGen = struct {
98979704 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
98989705 const ptr_ty = self.typeOf(bin_op.lhs);
98999706 const operand_ty = ptr_ty.childType(zcu);
9900 if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) return .none;
9707 if (!operand_ty.hasRuntimeBits(zcu)) return .none;
99019708 const ptr = try self.resolveInst(bin_op.lhs);
99029709 var element = try self.resolveInst(bin_op.rhs);
99039710 const llvm_abi_ty = try o.getAtomicAbiType(pt, operand_ty, false);
......@@ -10310,14 +10117,14 @@ pub const FuncGen = struct {
1031010117 const ip = &zcu.intern_pool;
1031110118 const enum_type = ip.loadEnumType(enum_ty.toIntern());
1031210119
10313 // TODO: detect when the type changes and re-emit this function.
10120 // TODO: detect when the type changes (`updateContainerType` will be called) and re-emit this function
1031410121 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_ty.toIntern());
1031510122 if (gop.found_existing) return gop.value_ptr.*;
1031610123 errdefer assert(o.named_enum_map.remove(enum_ty.toIntern()));
1031710124
1031810125 const target = &zcu.root_mod.resolved_target.result;
1031910126 const function_index = try o.builder.addFunction(
10320 try o.builder.fnType(.i1, &.{try o.lowerType(pt, Type.fromInterned(enum_type.tag_ty))}, .normal),
10127 try o.builder.fnType(.i1, &.{try o.lowerType(pt, Type.fromInterned(enum_type.int_tag_type))}, .normal),
1032110128 try o.builder.strtabStringFmt("__zig_is_named_enum_value_{f}", .{enum_type.name.fmt(ip)}),
1032210129 toLlvmAddressSpace(.generic, target),
1032310130 );
......@@ -10338,13 +10145,13 @@ pub const FuncGen = struct {
1033810145 defer wip.deinit();
1033910146 wip.cursor = .{ .block = try wip.block(0, "Entry") };
1034010147
10341 const named_block = try wip.block(@intCast(enum_type.names.len), "Named");
10148 const named_block = try wip.block(@intCast(enum_type.field_names.len), "Named");
1034210149 const unnamed_block = try wip.block(1, "Unnamed");
1034310150 const tag_int_value = wip.arg(0);
10344 var wip_switch = try wip.@"switch"(tag_int_value, unnamed_block, @intCast(enum_type.names.len), .none);
10151 var wip_switch = try wip.@"switch"(tag_int_value, unnamed_block, @intCast(enum_type.field_names.len), .none);
1034510152 defer wip_switch.finish(&wip);
1034610153
10347 for (0..enum_type.names.len) |field_index| {
10154 for (0..enum_type.field_names.len) |field_index| {
1034810155 const this_tag_int_value = try o.lowerValue(
1034910156 pt,
1035010157 (try pt.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),
......@@ -10813,15 +10620,14 @@ pub const FuncGen = struct {
1081310620 },
1081410621 .@"struct" => {
1081510622 if (zcu.typeToPackedStruct(result_ty)) |struct_type| {
10816 const backing_int_ty = struct_type.backingIntTypeUnordered(ip);
10817 assert(backing_int_ty != .none);
10818 const big_bits = Type.fromInterned(backing_int_ty).bitSize(zcu);
10623 const backing_int_ty: Type = .fromInterned(struct_type.packed_backing_int_type);
10624 const big_bits = backing_int_ty.bitSize(zcu);
1081910625 const int_ty = try o.builder.intType(@intCast(big_bits));
1082010626 comptime assert(Type.packed_struct_layout_version == 2);
1082110627 var running_int = try o.builder.intValue(int_ty, 0);
1082210628 var running_bits: u16 = 0;
1082310629 for (elements, struct_type.field_types.get(ip)) |elem, field_ty| {
10824 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) continue;
10630 if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue;
1082510631
1082610632 const non_int_val = try self.resolveInst(elem);
1082710633 const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(zcu));
......@@ -10853,12 +10659,12 @@ pub const FuncGen = struct {
1085310659
1085410660 const llvm_elem = try self.resolveInst(elem);
1085510661 const llvm_i = o.llvmFieldIndex(result_ty, i).?;
10856 const field_ptr =
10857 try self.wip.gepStruct(llvm_result_ty, alloca_inst, llvm_i, "");
10662 const field_ptr = try self.wip.gepStruct(llvm_result_ty, alloca_inst, llvm_i, "");
10663
1085810664 const field_ptr_ty = try pt.ptrType(.{
1085910665 .child = self.typeOf(elem).toIntern(),
1086010666 .flags = .{
10861 .alignment = result_ty.fieldAlignment(i, zcu),
10667 .alignment = result_ty.explicitFieldAlignment(i, zcu),
1086210668 },
1086310669 });
1086410670 try self.store(field_ptr, field_ptr_ty, llvm_elem, .none);
......@@ -10920,28 +10726,16 @@ pub const FuncGen = struct {
1092010726 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
1092110727 const union_ty = self.typeOfIndex(inst);
1092210728 const union_llvm_ty = try o.lowerType(pt, union_ty);
10923 const layout = union_ty.unionGetLayout(zcu);
1092410729 const union_obj = zcu.typeToUnion(union_ty).?;
1092510730
10926 if (union_obj.flagsUnordered(ip).layout == .@"packed") {
10927 const big_bits = union_ty.bitSize(zcu);
10928 const int_llvm_ty = try o.builder.intType(@intCast(big_bits));
10929 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);
10930 const non_int_val = try self.resolveInst(extra.init);
10931 const small_int_ty = try o.builder.intType(@intCast(field_ty.bitSize(zcu)));
10932 const small_int_val = if (field_ty.isPtrAtRuntime(zcu))
10933 try self.wip.cast(.ptrtoint, non_int_val, small_int_ty, "")
10934 else
10935 try self.wip.cast(.bitcast, non_int_val, small_int_ty, "");
10936 return self.wip.conv(.unsigned, small_int_val, int_llvm_ty, "");
10937 }
10731 assert(union_obj.layout != .@"packed");
10732
10733 const layout = Type.getUnionLayout(union_obj, zcu);
1093810734
1093910735 const tag_int_val = blk: {
1094010736 const tag_ty = union_ty.unionTagTypeHypothetical(zcu);
10941 const union_field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index];
10942 const enum_field_index = tag_ty.enumFieldIndex(union_field_name, zcu).?;
10943 const tag_val = try pt.enumValueFieldIndex(tag_ty, enum_field_index);
10944 break :blk try tag_val.intFromEnum(tag_ty, pt);
10737 const tag_val = try pt.enumValueFieldIndex(tag_ty, extra.field_index);
10738 break :blk tag_val.intFromEnum(zcu);
1094510739 };
1094610740 if (layout.payload_size == 0) {
1094710741 if (layout.tag_size == 0) {
......@@ -10963,16 +10757,14 @@ pub const FuncGen = struct {
1096310757 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);
1096410758 const field_llvm_ty = try o.lowerType(pt, field_ty);
1096510759 const field_size = field_ty.abiSize(zcu);
10966 const field_align = union_ty.fieldAlignment(extra.field_index, zcu);
10760 const field_align = union_ty.explicitFieldAlignment(extra.field_index, zcu);
1096710761 const llvm_usize = try o.lowerType(pt, Type.usize);
1096810762 const usize_zero = try o.builder.intValue(llvm_usize, 0);
1096910763
10764 assert(field_ty.hasRuntimeBits(zcu));
10765
1097010766 const llvm_union_ty = t: {
1097110767 const payload_ty = p: {
10972 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
10973 const padding_len = layout.payload_size;
10974 break :p try o.builder.arrayType(padding_len, .i8);
10975 }
1097610768 if (field_size == layout.payload_size) {
1097710769 break :p field_llvm_ty;
1097810770 }
......@@ -10982,7 +10774,7 @@ pub const FuncGen = struct {
1098210774 });
1098310775 };
1098410776 if (layout.tag_size == 0) break :t try o.builder.structType(.normal, &.{payload_ty});
10985 const tag_ty = try o.lowerType(pt, Type.fromInterned(union_obj.enum_tag_ty));
10777 const tag_ty = try o.lowerType(pt, .fromInterned(union_obj.enum_tag_type));
1098610778 var fields: [3]Builder.Type = undefined;
1098710779 var fields_len: usize = 2;
1098810780 if (layout.tag_align.compare(.gte, layout.payload_align)) {
......@@ -11023,11 +10815,11 @@ pub const FuncGen = struct {
1102310815 const tag_index = @intFromBool(layout.tag_align.compare(.lt, layout.payload_align));
1102410816 const indices: [2]Builder.Value = .{ usize_zero, try o.builder.intValue(.i32, tag_index) };
1102510817 const field_ptr = try self.wip.gep(.inbounds, llvm_union_ty, result_ptr, &indices, "");
11026 const tag_ty = try o.lowerType(pt, Type.fromInterned(union_obj.enum_tag_ty));
10818 const tag_ty = try o.lowerType(pt, .fromInterned(union_obj.enum_tag_type));
1102710819 var big_int_space: Value.BigIntSpace = undefined;
1102810820 const tag_big_int = tag_int_val.toBigInt(&big_int_space, zcu);
1102910821 const llvm_tag = try o.builder.bigIntValue(tag_ty, tag_big_int);
11030 const tag_alignment = Type.fromInterned(union_obj.enum_tag_ty).abiAlignment(zcu).toLlvm();
10822 const tag_alignment = Type.fromInterned(union_obj.enum_tag_type).abiAlignment(zcu).toLlvm();
1103110823 _ = try self.wip.store(.normal, llvm_tag, field_ptr, tag_alignment);
1103210824 }
1103310825
......@@ -11274,63 +11066,45 @@ pub const FuncGen = struct {
1127411066
1127511067 fn fieldPtr(
1127611068 self: *FuncGen,
11277 inst: Air.Inst.Index,
11278 struct_ptr: Builder.Value,
11279 struct_ptr_ty: Type,
11069 aggregate_ptr: Builder.Value,
11070 aggregate_ptr_ty: Type,
1128011071 field_index: u32,
1128111072 ) !Builder.Value {
1128211073 const o = self.ng.object;
1128311074 const pt = self.ng.pt;
1128411075 const zcu = pt.zcu;
11285 const struct_ty = struct_ptr_ty.childType(zcu);
11286 switch (struct_ty.zigTypeTag(zcu)) {
11287 .@"struct" => switch (struct_ty.containerLayout(zcu)) {
11288 .@"packed" => {
11289 const result_ty = self.typeOfIndex(inst);
11290 const result_ty_info = result_ty.ptrInfo(zcu);
11291 const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(zcu);
11292 const struct_type = zcu.typeToStruct(struct_ty).?;
11293
11294 if (result_ty_info.packed_offset.host_size != 0) {
11295 // From LLVM's perspective, a pointer to a packed struct and a pointer
11296 // to a field of a packed struct are the same. The difference is in the
11297 // Zig pointer type which provides information for how to mask and shift
11298 // out the relevant bits when accessing the pointee.
11299 return struct_ptr;
11300 }
11301
11302 // We have a pointer to a packed struct field that happens to be byte-aligned.
11303 // Offset our operand pointer by the correct number of bytes.
11304 const byte_offset = @divExact(zcu.structPackedFieldBitOffset(struct_type, field_index) + struct_ptr_ty_info.packed_offset.bit_offset, 8);
11305 if (byte_offset == 0) return struct_ptr;
11306 const usize_ty = try o.lowerType(pt, Type.usize);
11307 const llvm_index = try o.builder.intValue(usize_ty, byte_offset);
11308 return self.wip.gep(.inbounds, .i8, struct_ptr, &.{llvm_index}, "");
11309 },
11310 else => {
11311 const struct_llvm_ty = try o.lowerPtrElemTy(pt, struct_ty);
11312
11313 if (o.llvmFieldIndex(struct_ty, field_index)) |llvm_field_index| {
11314 return self.wip.gepStruct(struct_llvm_ty, struct_ptr, llvm_field_index, "");
11315 } else {
11316 // If we found no index then this means this is a zero sized field at the
11317 // end of the struct. Treat our struct pointer as an array of two and get
11318 // the index to the element at index `1` to get a pointer to the end of
11319 // the struct.
11320 const llvm_index = try o.builder.intValue(
11321 try o.lowerType(pt, Type.usize),
11322 @intFromBool(struct_ty.hasRuntimeBitsIgnoreComptime(zcu)),
11323 );
11324 return self.wip.gep(.inbounds, struct_llvm_ty, struct_ptr, &.{llvm_index}, "");
11325 }
11326 },
11076 const aggregate_ty = aggregate_ptr_ty.childType(zcu);
11077 if (aggregate_ty.containerLayout(zcu) == .@"packed") {
11078 // A pointer to a bitpack field is equivalent to a pointer to the whole bitpack; the
11079 // bit offset is represented in the pointer *type*.
11080 return aggregate_ptr;
11081 }
11082 switch (aggregate_ty.zigTypeTag(zcu)) {
11083 .@"struct" => {
11084 if (!aggregate_ty.hasRuntimeBits(zcu)) {
11085 return aggregate_ptr;
11086 }
11087 const struct_llvm_ty = try o.lowerType(pt, aggregate_ty);
11088 if (o.llvmFieldIndex(aggregate_ty, field_index)) |llvm_field_index| {
11089 return self.wip.gepStruct(struct_llvm_ty, aggregate_ptr, llvm_field_index, "");
11090 } else {
11091 // If we found no index then this means this is a zero sized field at the
11092 // end of the struct. Treat our struct pointer as an array of two and get
11093 // the index to the element at index `1` to get a pointer to the end of
11094 // the struct.
11095 const llvm_index = try o.builder.intValue(
11096 try o.lowerType(pt, Type.usize),
11097 @intFromBool(aggregate_ty.hasRuntimeBits(zcu)),
11098 );
11099 return self.wip.gep(.inbounds, struct_llvm_ty, aggregate_ptr, &.{llvm_index}, "");
11100 }
1132711101 },
1132811102 .@"union" => {
11329 const layout = struct_ty.unionGetLayout(zcu);
11330 if (layout.payload_size == 0 or struct_ty.containerLayout(zcu) == .@"packed") return struct_ptr;
11331 const payload_index = @intFromBool(layout.tag_align.compare(.gte, layout.payload_align));
11332 const union_llvm_ty = try o.lowerType(pt, struct_ty);
11333 return self.wip.gepStruct(union_llvm_ty, struct_ptr, payload_index, "");
11103 const layout = aggregate_ty.unionGetLayout(zcu);
11104 if (layout.payload_size == 0) return aggregate_ptr;
11105 const payload_index = @intFromBool(layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align));
11106 const union_llvm_ty = try o.lowerType(pt, aggregate_ty);
11107 return self.wip.gepStruct(union_llvm_ty, aggregate_ptr, payload_index, "");
1133411108 },
1133511109 else => unreachable,
1133611110 }
......@@ -11406,7 +11180,7 @@ pub const FuncGen = struct {
1140611180 const zcu = pt.zcu;
1140711181 const info = ptr_ty.ptrInfo(zcu);
1140811182 const elem_ty = Type.fromInterned(info.child);
11409 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) return .none;
11183 if (!elem_ty.hasRuntimeBits(zcu)) return .none;
1141011184
1141111185 const ptr_alignment = (if (info.flags.alignment != .none)
1141211186 @as(InternPool.Alignment, info.flags.alignment)
......@@ -11478,7 +11252,7 @@ pub const FuncGen = struct {
1147811252 const zcu = pt.zcu;
1147911253 const info = ptr_ty.ptrInfo(zcu);
1148011254 const elem_ty = Type.fromInterned(info.child);
11481 if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {
11255 if (!elem_ty.hasRuntimeBits(zcu)) {
1148211256 return;
1148311257 }
1148411258 const ptr_alignment = ptr_ty.ptrAlignment(zcu).toLlvm();
......@@ -12061,7 +11835,7 @@ fn returnTypeByRef(zcu: *Zcu, target: *const std.Target, ty: Type) bool {
1206111835
1206211836fn firstParamSRet(fn_info: InternPool.Key.FuncType, zcu: *Zcu, target: *const std.Target) bool {
1206311837 const return_type = Type.fromInterned(fn_info.return_type);
12064 if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) return false;
11838 if (!return_type.hasRuntimeBits(zcu)) return false;
1206511839
1206611840 return switch (fn_info.cc) {
1206711841 .auto => returnTypeByRef(zcu, target, return_type),
......@@ -12101,11 +11875,9 @@ fn firstParamSRetSystemV(ty: Type, zcu: *Zcu, target: *const std.Target) bool {
1210111875fn lowerFnRetTy(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {
1210211876 const zcu = pt.zcu;
1210311877 const return_type = Type.fromInterned(fn_info.return_type);
12104 if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) {
12105 // If the return type is an error set or an error union, then we make this
12106 // anyerror return type instead, so that it can be coerced into a function
12107 // pointer type which has anyerror as the return type.
12108 return if (return_type.isError(zcu)) try o.errorIntType(pt) else .void;
11878 if (!return_type.hasRuntimeBits(zcu)) {
11879 assert(!return_type.isError(zcu));
11880 return .void;
1210911881 }
1211011882 const target = zcu.getTarget();
1211111883 switch (fn_info.cc) {
......@@ -12149,7 +11921,7 @@ fn lowerFnRetTy(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.FuncType)
1214911921 var types: [8]Builder.Type = undefined;
1215011922 for (0..return_type.structFieldCount(zcu)) |field_index| {
1215111923 const field_ty = return_type.fieldType(field_index, zcu);
12152 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
11924 if (!field_ty.hasRuntimeBits(zcu)) continue;
1215311925 types[types_len] = try o.lowerType(pt, field_ty);
1215411926 types_len += 1;
1215511927 }
......@@ -12187,6 +11959,7 @@ fn lowerSystemVFnRetTy(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.Fu
1218711959 const zcu = pt.zcu;
1218811960 const ip = &zcu.intern_pool;
1218911961 const return_type = Type.fromInterned(fn_info.return_type);
11962 return_type.assertHasLayout(zcu);
1219011963 if (isScalar(zcu, return_type)) {
1219111964 return o.lowerType(pt, return_type);
1219211965 }
......@@ -12235,9 +12008,7 @@ fn lowerSystemVFnRetTy(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.Fu
1223512008 assert(first_non_integer orelse classes.len == types_index);
1223612009 switch (ip.indexToKey(return_type.toIntern())) {
1223712010 .struct_type => {
12238 const struct_type = ip.loadStructType(return_type.toIntern());
12239 assert(struct_type.haveLayout(ip));
12240 const size: u64 = struct_type.sizeUnordered(ip);
12011 const size = return_type.abiSize(zcu);
1224112012 assert((std.math.divCeil(u64, size, 8) catch unreachable) == types_index);
1224212013 if (size % 8 > 0) {
1224312014 types_buffer[types_index - 1] = try o.builder.intType(@intCast(size % 8 * 8));
......@@ -12273,7 +12044,7 @@ const ParamTypeIterator = struct {
1227312044 i64_array: u8,
1227412045 };
1227512046
12276 pub fn next(it: *ParamTypeIterator) Allocator.Error!?Lowering {
12047 fn next(it: *ParamTypeIterator) Allocator.Error!?Lowering {
1227712048 if (it.zig_index >= it.fn_info.param_types.len) return null;
1227812049 const ip = &it.pt.zcu.intern_pool;
1227912050 const ty = it.fn_info.param_types.get(ip)[it.zig_index];
......@@ -12282,7 +12053,7 @@ const ParamTypeIterator = struct {
1228212053 }
1228312054
1228412055 /// `airCall` uses this instead of `next` so that it can take into account variadic functions.
12285 pub fn nextCall(it: *ParamTypeIterator, fg: *FuncGen, args: []const Air.Inst.Ref) Allocator.Error!?Lowering {
12056 fn nextCall(it: *ParamTypeIterator, fg: *FuncGen, args: []const Air.Inst.Ref) Allocator.Error!?Lowering {
1228612057 assert(std.meta.eql(it.pt, fg.ng.pt));
1228712058 const ip = &it.pt.zcu.intern_pool;
1228812059 if (it.zig_index >= it.fn_info.param_types.len) {
......@@ -12301,7 +12072,7 @@ const ParamTypeIterator = struct {
1230112072 const zcu = pt.zcu;
1230212073 const target = zcu.getTarget();
1230312074
12304 if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) {
12075 if (!ty.hasRuntimeBits(zcu)) {
1230512076 it.zig_index += 1;
1230612077 return .no_bits;
1230712078 }
......@@ -12396,7 +12167,7 @@ const ParamTypeIterator = struct {
1239612167 it.types_len = 0;
1239712168 for (0..ty.structFieldCount(zcu)) |field_index| {
1239812169 const field_ty = ty.fieldType(field_index, zcu);
12399 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
12170 if (!field_ty.hasRuntimeBits(zcu)) continue;
1240012171 it.types_buffer[it.types_len] = try it.object.lowerType(pt, field_ty);
1240112172 it.types_len += 1;
1240212173 }
......@@ -12473,6 +12244,7 @@ const ParamTypeIterator = struct {
1247312244 fn nextSystemV(it: *ParamTypeIterator, ty: Type) Allocator.Error!?Lowering {
1247412245 const zcu = it.pt.zcu;
1247512246 const ip = &zcu.intern_pool;
12247 ty.assertHasLayout(zcu);
1247612248 const classes = x86_64_abi.classifySystemV(ty, zcu, zcu.getTarget(), .arg);
1247712249 if (classes[0] == .memory) {
1247812250 it.zig_index += 1;
......@@ -12544,9 +12316,7 @@ const ParamTypeIterator = struct {
1254412316 }
1254512317 switch (ip.indexToKey(ty.toIntern())) {
1254612318 .struct_type => {
12547 const struct_type = ip.loadStructType(ty.toIntern());
12548 assert(struct_type.haveLayout(ip));
12549 const size: u64 = struct_type.sizeUnordered(ip);
12319 const size = ty.abiSize(zcu);
1255012320 assert((std.math.divCeil(u64, size, 8) catch unreachable) == types_index);
1255112321 if (size % 8 > 0) {
1255212322 types_buffer[types_index - 1] =
......@@ -12720,14 +12490,14 @@ fn isByRef(ty: Type, zcu: *Zcu) bool {
1272012490 },
1272112491 .error_union => {
1272212492 const payload_ty = ty.errorUnionPayload(zcu);
12723 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
12493 if (!payload_ty.hasRuntimeBits(zcu)) {
1272412494 return false;
1272512495 }
1272612496 return true;
1272712497 },
1272812498 .optional => {
1272912499 const payload_ty = ty.optionalChild(zcu);
12730 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
12500 if (!payload_ty.hasRuntimeBits(zcu)) {
1273112501 return false;
1273212502 }
1273312503 if (ty.optionalReprIsPayload(zcu)) {
src/codegen/mips/abi.zig+2-2
......@@ -13,7 +13,7 @@ pub const Context = enum { ret, arg };
1313
1414pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
1515 const target = zcu.getTarget();
16 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(zcu));
16 std.debug.assert(ty.hasRuntimeBits(zcu));
1717
1818 const max_direct_size = target.ptrBitWidth() * 2;
1919 switch (ty.zigTypeTag(zcu)) {
......@@ -44,7 +44,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu, ctx: Context) Class {
4444 return .byval;
4545 },
4646 .vector => {
47 const elem_type = ty.elemType2(zcu);
47 const elem_type = ty.childType(zcu);
4848 switch (elem_type.zigTypeTag(zcu)) {
4949 .bool, .int => {
5050 const bit_size = ty.bitSize(zcu);
src/codegen/riscv64/CodeGen.zig+45-58
......@@ -2673,7 +2673,7 @@ fn genBinOp(
26732673 defer func.register_manager.unlockReg(tmp_lock);
26742674
26752675 // RISC-V has no immediate mul, so we copy the size to a temporary register
2676 const elem_size = lhs_ty.elemType2(zcu).abiSize(zcu);
2676 const elem_size = lhs_ty.indexableElem(zcu).abiSize(zcu);
26772677 const elem_size_reg = try func.copyToTmpRegister(Type.u64, .{ .immediate = elem_size });
26782678
26792679 try func.genBinOp(
......@@ -3257,7 +3257,7 @@ fn airOptionalPayload(func: *Func, inst: Air.Inst.Index) !void {
32573257 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
32583258 const result: MCValue = result: {
32593259 const pl_ty = func.typeOfIndex(inst);
3260 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
3260 if (!pl_ty.hasRuntimeBits(zcu)) break :result .none;
32613261
32623262 const opt_mcv = try func.resolveInst(ty_op.operand);
32633263 if (func.reuseOperand(inst, ty_op.operand, 0, opt_mcv)) {
......@@ -3331,7 +3331,7 @@ fn airUnwrapErrErr(func: *Func, inst: Air.Inst.Index) !void {
33313331 break :result .{ .immediate = 0 };
33323332 }
33333333
3334 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
3334 if (!payload_ty.hasRuntimeBits(zcu)) {
33353335 break :result operand;
33363336 }
33373337
......@@ -3384,7 +3384,7 @@ fn genUnwrapErrUnionPayloadMir(
33843384 const payload_ty = err_union_ty.errorUnionPayload(zcu);
33853385
33863386 const result: MCValue = result: {
3387 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
3387 if (!payload_ty.hasRuntimeBits(zcu)) break :result .none;
33883388
33893389 const payload_off: u31 = @intCast(errUnionPayloadOffset(payload_ty, zcu));
33903390 switch (err_union) {
......@@ -3547,7 +3547,7 @@ fn airWrapErrUnionPayload(func: *Func, inst: Air.Inst.Index) !void {
35473547 const operand = try func.resolveInst(ty_op.operand);
35483548
35493549 const result: MCValue = result: {
3550 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .{ .immediate = 0 };
3550 if (!pl_ty.hasRuntimeBits(zcu)) break :result .{ .immediate = 0 };
35513551
35523552 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu));
35533553 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu));
......@@ -3571,7 +3571,7 @@ fn airWrapErrUnionErr(func: *Func, inst: Air.Inst.Index) !void {
35713571 const err_ty = eu_ty.errorUnionSet(zcu);
35723572
35733573 const result: MCValue = result: {
3574 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result try func.resolveInst(ty_op.operand);
3574 if (!pl_ty.hasRuntimeBits(zcu)) break :result try func.resolveInst(ty_op.operand);
35753575
35763576 const frame_index = try func.allocFrameIndex(FrameAlloc.initSpill(eu_ty, zcu));
35773577 const pl_off: i32 = @intCast(errUnionPayloadOffset(pl_ty, zcu));
......@@ -3761,7 +3761,7 @@ fn airSliceElemVal(func: *Func, inst: Air.Inst.Index) !void {
37613761
37623762 const result: MCValue = result: {
37633763 const elem_ty = func.typeOfIndex(inst);
3764 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
3764 assert(elem_ty.hasRuntimeBits(zcu));
37653765
37663766 const slice_ty = func.typeOf(bin_op.lhs);
37673767 const slice_ptr_field_type = slice_ty.slicePtrFieldType(zcu);
......@@ -3913,9 +3913,8 @@ fn airPtrElemVal(func: *Func, inst: Air.Inst.Index) !void {
39133913 const base_ptr_ty = func.typeOf(bin_op.lhs);
39143914
39153915 const result: MCValue = if (!is_volatile and func.liveness.isUnused(inst)) .unreach else result: {
3916 const elem_ty = base_ptr_ty.elemType2(zcu);
3917 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
3918
3916 const elem_ty = base_ptr_ty.indexableElem(zcu);
3917 assert(elem_ty.hasRuntimeBits(zcu));
39193918 const base_ptr_mcv = try func.resolveInst(bin_op.lhs);
39203919 const base_ptr_lock: ?RegisterLock = switch (base_ptr_mcv) {
39213920 .register => |reg| func.register_manager.lockRegAssumeUnused(reg),
......@@ -4618,7 +4617,7 @@ fn airStructFieldVal(func: *Func, inst: Air.Inst.Index) !void {
46184617 const src_mcv = try func.resolveInst(operand);
46194618 const struct_ty = func.typeOf(operand);
46204619 const field_ty = struct_ty.fieldType(index, zcu);
4621 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
4620 assert(field_ty.hasRuntimeBits(zcu));
46224621
46234622 const field_off: u32 = switch (struct_ty.containerLayout(zcu)) {
46244623 .auto, .@"extern" => @intCast(struct_ty.structFieldOffset(index, zcu) * 8),
......@@ -5127,7 +5126,6 @@ fn airCmp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
51275126 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
51285127 const pt = func.pt;
51295128 const zcu = pt.zcu;
5130 const ip = &zcu.intern_pool;
51315129
51325130 const result: MCValue = if (func.liveness.isUnused(inst)) .unreach else result: {
51335131 const lhs_ty = func.typeOf(bin_op.lhs);
......@@ -5141,28 +5139,23 @@ fn airCmp(func: *Func, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
51415139 .optional,
51425140 .@"struct",
51435141 => {
5144 const int_ty = switch (lhs_ty.zigTypeTag(zcu)) {
5142 const int_ty: Type = switch (lhs_ty.zigTypeTag(zcu)) {
51455143 .@"enum" => lhs_ty.intTagType(zcu),
51465144 .int => lhs_ty,
5147 .bool => Type.u1,
5148 .pointer => Type.u64,
5149 .error_set => Type.anyerror,
5145 .bool => .u1,
5146 .pointer => .u64,
5147 .error_set => .anyerror,
51505148 .optional => blk: {
51515149 const payload_ty = lhs_ty.optionalChild(zcu);
5152 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
5153 break :blk Type.u1;
5150 if (!payload_ty.hasRuntimeBits(zcu)) {
5151 break :blk .u1;
51545152 } else if (lhs_ty.isPtrLikeOptional(zcu)) {
5155 break :blk Type.u64;
5153 break :blk .u64;
51565154 } else {
51575155 return func.fail("TODO riscv cmp non-pointer optionals", .{});
51585156 }
51595157 },
5160 .@"struct" => blk: {
5161 const struct_obj = ip.loadStructType(lhs_ty.toIntern());
5162 assert(struct_obj.layout == .@"packed");
5163 const backing_index = struct_obj.backingIntTypeUnordered(ip);
5164 break :blk Type.fromInterned(backing_index);
5165 },
5158 .@"struct", .@"union" => lhs_ty.bitpackBackingInt(zcu),
51665159 else => unreachable,
51675160 };
51685161
......@@ -5926,8 +5919,7 @@ fn airBr(func: *Func, inst: Air.Inst.Index) !void {
59265919 const br = func.air.instructions.items(.data)[@intFromEnum(inst)].br;
59275920
59285921 const block_ty = func.typeOfIndex(br.block_inst);
5929 const block_unused =
5930 !block_ty.hasRuntimeBitsIgnoreComptime(zcu) or func.liveness.isUnused(br.block_inst);
5922 const block_unused = !block_ty.hasRuntimeBits(zcu) or func.liveness.isUnused(br.block_inst);
59315923 const block_tracking = func.inst_tracking.getPtr(br.block_inst).?;
59325924 const block_data = func.blocks.getPtr(br.block_inst).?;
59335925 const first_br = block_data.relocs.items.len == 0;
......@@ -6150,31 +6142,26 @@ fn airAsm(func: *Func, inst: Air.Inst.Index) !void {
61506142
61516143 const zcu = func.pt.zcu;
61526144 const ip = &zcu.intern_pool;
6153 const aggregate = ip.indexToKey(unwrapped_asm.clobbers).aggregate;
6154 const struct_type: Type = .fromInterned(aggregate.ty);
6155 switch (aggregate.storage) {
6156 .elems => |elems| for (elems, 0..) |elem, i| {
6157 switch (elem) {
6158 .bool_true => {
6159 const clobber = struct_type.structFieldName(i, zcu).toSlice(ip).?;
6160 assert(clobber.len != 0);
6161 if (std.mem.eql(u8, clobber, "memory")) {
6162 // nothing really to do
6163 } else {
6164 try func.register_manager.getReg(parseRegName(clobber) orelse
6165 return func.fail("invalid clobber: '{s}'", .{clobber}), null);
6166 }
6167 },
6168 .bool_false => continue,
6169 else => unreachable,
6170 }
6171 },
6172 .repeated_elem => |elem| switch (elem) {
6173 .bool_true => @panic("TODO"),
6174 .bool_false => {},
6175 else => unreachable,
6176 },
6177 .bytes => @panic("TODO"),
6145 const clobbers_val: Value = .fromInterned(unwrapped_asm.clobbers);
6146 const clobbers_ty = clobbers_val.typeOf(zcu);
6147 var clobbers_bigint_buf: Value.BigIntSpace = undefined;
6148 const clobbers_bigint = clobbers_val.toBigInt(&clobbers_bigint_buf, zcu);
6149 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
6150 assert(clobbers_ty.fieldType(field_index, zcu).toIntern() == .bool_type);
6151 const limb_bits = @bitSizeOf(std.math.big.Limb);
6152 if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
6153 switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
6154 0 => continue, // field is false
6155 1 => {}, // field is true
6156 }
6157 const clobber = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;
6158 assert(clobber.len != 0);
6159 if (std.mem.eql(u8, clobber, "memory")) {
6160 // nothing really to do
6161 } else {
6162 try func.register_manager.getReg(parseRegName(clobber) orelse
6163 return func.fail("invalid clobber: '{s}'", .{clobber}), null);
6164 }
61786165 }
61796166
61806167 const Label = struct {
......@@ -8255,7 +8242,7 @@ fn resolveCallingConventionValues(
82558242 // Return values
82568243 if (ret_ty.zigTypeTag(zcu) == .noreturn) {
82578244 result.return_value = InstTracking.init(.unreach);
8258 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
8245 } else if (!ret_ty.hasRuntimeBits(zcu)) {
82598246 result.return_value = InstTracking.init(.none);
82608247 } else {
82618248 var ret_tracking: [2]InstTracking = undefined;
......@@ -8306,7 +8293,7 @@ fn resolveCallingConventionValues(
83068293 var param_float_reg_i: usize = 0;
83078294
83088295 for (param_types, result.args) |ty, *arg| {
8309 if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) {
8296 if (!ty.hasRuntimeBits(zcu)) {
83108297 assert(cc == .auto);
83118298 arg.* = .none;
83128299 continue;
......@@ -8421,10 +8408,10 @@ fn hasFeature(func: *Func, feature: Target.riscv.Feature) bool {
84218408}
84228409
84238410pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {
8424 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0;
8411 if (!payload_ty.hasRuntimeBits(zcu)) return 0;
84258412 const payload_align = payload_ty.abiAlignment(zcu);
84268413 const error_align = Type.anyerror.abiAlignment(zcu);
8427 if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
8414 if (payload_align.compare(.gte, error_align) or !payload_ty.hasRuntimeBits(zcu)) {
84288415 return 0;
84298416 } else {
84308417 return payload_align.forward(Type.anyerror.abiSize(zcu));
......@@ -8432,10 +8419,10 @@ pub fn errUnionPayloadOffset(payload_ty: Type, zcu: *Zcu) u64 {
84328419}
84338420
84348421pub fn errUnionErrorOffset(payload_ty: Type, zcu: *Zcu) u64 {
8435 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return 0;
8422 if (!payload_ty.hasRuntimeBits(zcu)) return 0;
84368423 const payload_align = payload_ty.abiAlignment(zcu);
84378424 const error_align = Type.anyerror.abiAlignment(zcu);
8438 if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
8425 if (payload_align.compare(.gte, error_align) and payload_ty.hasRuntimeBits(zcu)) {
84398426 return error_align.forward(payload_ty.abiSize(zcu));
84408427 } else {
84418428 return 0;
src/codegen/riscv64/abi.zig+2-2
......@@ -11,7 +11,7 @@ pub const Class = enum { memory, byval, integer, double_integer, fields };
1111
1212pub fn classifyType(ty: Type, zcu: *Zcu) Class {
1313 const target = zcu.getTarget();
14 std.debug.assert(ty.hasRuntimeBitsIgnoreComptime(zcu));
14 std.debug.assert(ty.hasRuntimeBits(zcu));
1515
1616 const max_byval_size = target.ptrBitWidth() * 2;
1717 switch (ty.zigTypeTag(zcu)) {
......@@ -27,7 +27,7 @@ pub fn classifyType(ty: Type, zcu: *Zcu) Class {
2727 var field_count: usize = 0;
2828 for (0..ty.structFieldCount(zcu)) |field_index| {
2929 const field_ty = ty.fieldType(field_index, zcu);
30 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
30 if (!field_ty.hasRuntimeBits(zcu)) continue;
3131 if (field_ty.isRuntimeFloat())
3232 any_fp = true
3333 else if (!field_ty.isAbiInt(zcu))
src/codegen/sparc64/CodeGen.zig+11-11
......@@ -1102,7 +1102,7 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
11021102fn lowerBlock(self: *Self, inst: Air.Inst.Index, body: []const Air.Inst.Index) !void {
11031103 try self.blocks.putNoClobber(self.gpa, inst, .{
11041104 // A block is a setup to be able to jump to the end.
1105 .relocs = .{},
1105 .relocs = .empty,
11061106 // It also acts as a receptacle for break operands.
11071107 // Here we use `MCValue.none` to represent a null value so that the first
11081108 // break instruction will choose a MCValue for the block result and overwrite
......@@ -1376,19 +1376,19 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
13761376 const rhs = try self.resolveInst(bin_op.rhs);
13771377 const lhs_ty = self.typeOf(bin_op.lhs);
13781378
1379 const int_ty = switch (lhs_ty.zigTypeTag(zcu)) {
1379 const int_ty: Type = switch (lhs_ty.zigTypeTag(zcu)) {
13801380 .vector => unreachable, // Handled by cmp_vector.
13811381 .@"enum" => lhs_ty.intTagType(zcu),
13821382 .int => lhs_ty,
1383 .bool => Type.u1,
1384 .pointer => Type.usize,
1385 .error_set => Type.u16,
1383 .bool => .u1,
1384 .pointer => .usize,
1385 .error_set => .u16,
13861386 .optional => blk: {
13871387 const payload_ty = lhs_ty.optionalChild(zcu);
1388 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
1389 break :blk Type.u1;
1388 if (!payload_ty.hasRuntimeBits(zcu)) {
1389 break :blk .u1;
13901390 } else if (lhs_ty.isPtrLikeOptional(zcu)) {
1391 break :blk Type.usize;
1391 break :blk .usize;
13921392 } else {
13931393 return self.fail("TODO SPARCv9 cmp non-pointer optionals", .{});
13941394 }
......@@ -3452,8 +3452,8 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type)
34523452 if (err_ty.errorSetIsEmpty(zcu)) {
34533453 return error_union_mcv;
34543454 }
3455 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
3456 return MCValue.none;
3455 if (!payload_ty.hasRuntimeBits(zcu)) {
3456 return .none;
34573457 }
34583458
34593459 const payload_offset: u32 = @intCast(errUnionPayloadOffset(payload_ty, zcu));
......@@ -4481,7 +4481,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
44814481 const ty = self.typeOf(ref);
44824482
44834483 // If the type has no codegen bits, no need to store it.
4484 if (!ty.hasRuntimeBitsIgnoreComptime(pt.zcu)) return .none;
4484 if (!ty.hasRuntimeBits(pt.zcu)) return .none;
44854485
44864486 if (ref.toIndex()) |inst| {
44874487 return self.getResolvedInstValue(inst);
src/codegen/spirv/CodeGen.zig+84-122
......@@ -208,7 +208,7 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
208208 try cg.args.ensureUnusedCapacity(gpa, fn_info.param_types.len);
209209 for (fn_info.param_types.get(ip)) |param_ty_index| {
210210 const param_ty: Type = .fromInterned(param_ty_index);
211 if (!param_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
211 if (!param_ty.hasRuntimeBits(zcu)) continue;
212212
213213 const param_type_id = try cg.resolveType(param_ty, .direct);
214214 const arg_result_id = cg.module.allocId();
......@@ -689,7 +689,7 @@ fn constInt(cg: *CodeGen, ty: Type, value: anytype) !Id {
689689 .comptime_int => if (value < 0) .signed else .unsigned,
690690 else => unreachable,
691691 };
692 if (@sizeOf(@TypeOf(value)) >= 4 and big_int) {
692 if (@TypeOf(value) != comptime_int and @sizeOf(@TypeOf(value)) >= 4 and big_int) {
693693 const value64: u64 = switch (signedness) {
694694 .signed => @bitCast(@as(i64, @intCast(value))),
695695 .unsigned => @as(u64, @intCast(value)),
......@@ -814,14 +814,11 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
814814 .@"extern",
815815 .func,
816816 .enum_literal,
817 .empty_enum_value,
818817 => unreachable, // non-runtime values
819818
820819 .simple_value => |simple_value| switch (simple_value) {
821 .undefined,
822820 .void,
823821 .null,
824 .empty_tuple,
825822 .@"unreachable",
826823 => unreachable, // non-runtime values
827824
......@@ -887,7 +884,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
887884 return try cg.constructComposite(comp_ty_id, &constituents);
888885 },
889886 .enum_tag => {
890 const int_val = try val.intFromEnum(ty, pt);
887 const int_val = val.intFromEnum(zcu);
891888 const int_ty = ty.intTagType(zcu);
892889 break :cache try cg.constant(int_ty, int_val, repr);
893890 },
......@@ -962,18 +959,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
962959 },
963960 .struct_type => {
964961 const struct_type = zcu.typeToStruct(ty).?;
965
966 if (struct_type.layout == .@"packed") {
967 // TODO: composite int
968 // TODO: endianness
969 const bits: u16 = @intCast(ty.bitSize(zcu));
970 const bytes = std.mem.alignForward(u16, cg.module.backingIntBits(bits).@"0", 8) / 8;
971 var limbs: [8]u8 = undefined;
972 @memset(&limbs, 0);
973 val.writeToPackedMemory(ty, pt, limbs[0..bytes], 0) catch unreachable;
974 const backing_ty: Type = .fromInterned(struct_type.backingIntTypeUnordered(ip));
975 return try cg.constInt(backing_ty, @as(u64, @bitCast(limbs)));
976 }
962 assert(struct_type.layout != .@"packed"); // packed structs use `bitpack`
977963
978964 var types = std.array_list.Managed(Type).init(gpa);
979965 defer types.deinit();
......@@ -984,7 +970,7 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
984970 var it = struct_type.iterateRuntimeOrder(ip);
985971 while (it.next()) |field_index| {
986972 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
987 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
973 if (!field_ty.hasRuntimeBits(zcu)) {
988974 // This is a zero-bit field - we only needed it for the alignment.
989975 continue;
990976 }
......@@ -1004,20 +990,24 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
1004990 else => unreachable,
1005991 },
1006992 .un => |un| {
993 assert(ty.containerLayout(zcu) != .@"packed"); // packed unions use `bitpack`
1007994 if (un.tag == .none) {
1008 assert(ty.containerLayout(zcu) == .@"packed"); // TODO
1009 const int_ty = try pt.intType(.unsigned, @intCast(ty.bitSize(zcu)));
1010 return try cg.constInt(int_ty, Value.toUnsignedInt(.fromInterned(un.val), zcu));
995 @panic("TODO");
1011996 }
1012997 const active_field = ty.unionTagFieldIndex(.fromInterned(un.tag), zcu).?;
1013998 const union_obj = zcu.typeToUnion(ty).?;
1014999 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[active_field]);
1015 const payload = if (field_ty.hasRuntimeBitsIgnoreComptime(zcu))
1000 const payload = if (field_ty.hasRuntimeBits(zcu))
10161001 try cg.constant(field_ty, .fromInterned(un.val), .direct)
10171002 else
10181003 null;
10191004 return try cg.unionInit(ty, active_field, payload);
10201005 },
1006 .bitpack => |bitpack| {
1007 const int_val: Value = .fromInterned(bitpack.backing_int_val);
1008 break :cache try cg.constant(int_val.typeOf(zcu), int_val, repr);
1009 },
1010
10211011 .memoized_call => unreachable,
10221012 }
10231013 };
......@@ -1041,7 +1031,7 @@ fn constantPtr(cg: *CodeGen, ptr_val: Value) !Id {
10411031 var arena = std.heap.ArenaAllocator.init(gpa);
10421032 defer arena.deinit();
10431033
1044 const derivation = try ptr_val.pointerDerivation(arena.allocator(), pt);
1034 const derivation = try ptr_val.pointerDerivation(arena.allocator(), pt, null);
10451035 return cg.derivePtr(derivation);
10461036}
10471037
......@@ -1150,7 +1140,7 @@ fn constantUavRef(
11501140 }
11511141
11521142 // const is_fn_body = decl_ty.zigTypeTag(zcu) == .@"fn";
1153 if (!uav_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {
1143 if (!uav_ty.hasRuntimeBits(zcu)) {
11541144 // Pointer to nothing - return undefined
11551145 return cg.module.constUndef(ty_id);
11561146 }
......@@ -1196,7 +1186,7 @@ fn constantNavRef(cg: *CodeGen, ty: Type, nav_index: InternPool.Nav.Index) !Id {
11961186 },
11971187 }
11981188
1199 if (!nav_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {
1189 if (!nav_ty.hasRuntimeBits(zcu)) {
12001190 // Pointer to nothing - return undefined.
12011191 return cg.module.constUndef(ty_id);
12021192 }
......@@ -1258,17 +1248,16 @@ fn resolveTypeName(cg: *CodeGen, ty: Type) ![]const u8 {
12581248fn resolveUnionType(cg: *CodeGen, ty: Type) !Id {
12591249 const gpa = cg.module.gpa;
12601250 const zcu = cg.module.zcu;
1261 const ip = &zcu.intern_pool;
12621251 const union_obj = zcu.typeToUnion(ty).?;
12631252
1264 if (union_obj.flagsUnordered(ip).layout == .@"packed") {
1253 if (union_obj.layout == .@"packed") {
12651254 return try cg.module.intType(.unsigned, @intCast(ty.bitSize(zcu)));
12661255 }
12671256
12681257 const layout = cg.unionLayout(ty);
12691258 if (!layout.has_payload) {
12701259 // No payload, so represent this as just the tag type.
1271 return try cg.resolveType(.fromInterned(union_obj.enum_tag_ty), .indirect);
1260 return try cg.resolveType(.fromInterned(union_obj.enum_tag_type), .indirect);
12721261 }
12731262
12741263 var member_types: [4]Id = undefined;
......@@ -1277,7 +1266,7 @@ fn resolveUnionType(cg: *CodeGen, ty: Type) !Id {
12771266 const u8_ty_id = try cg.resolveType(.u8, .direct);
12781267
12791268 if (layout.tag_size != 0) {
1280 const tag_ty_id = try cg.resolveType(.fromInterned(union_obj.enum_tag_ty), .indirect);
1269 const tag_ty_id = try cg.resolveType(.fromInterned(union_obj.enum_tag_type), .indirect);
12811270 member_types[layout.tag_index] = tag_ty_id;
12821271 member_names[layout.tag_index] = "(tag)";
12831272 }
......@@ -1318,7 +1307,7 @@ fn resolveUnionType(cg: *CodeGen, ty: Type) !Id {
13181307
13191308fn resolveFnReturnType(cg: *CodeGen, ret_ty: Type) !Id {
13201309 const zcu = cg.module.zcu;
1321 if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
1310 if (!ret_ty.hasRuntimeBits(zcu)) {
13221311 // If the return type is an error set or an error union, then we make this
13231312 // anyerror return type instead, so that it can be coerced into a function
13241313 // pointer type which has anyerror as the return type.
......@@ -1392,7 +1381,7 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
13921381 return cg.fail("array type of {} elements is too large", .{ty.arrayLenIncludingSentinel(zcu)});
13931382 };
13941383
1395 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
1384 if (!elem_ty.hasRuntimeBits(zcu)) {
13961385 assert(repr == .indirect);
13971386 if (target.os.tag != .opencl) return cg.fail("cannot generate opaque type", .{});
13981387 return try cg.module.opaqueType("zero-sized-array");
......@@ -1456,7 +1445,7 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
14561445 var param_index: usize = 0;
14571446 for (fn_info.param_types.get(ip)) |param_ty_index| {
14581447 const param_ty: Type = .fromInterned(param_ty_index);
1459 if (!param_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
1448 if (!param_ty.hasRuntimeBits(zcu)) continue;
14601449
14611450 param_ty_ids[param_index] = try cg.resolveType(param_ty, .direct);
14621451 param_index += 1;
......@@ -1521,7 +1510,7 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
15211510 };
15221511
15231512 if (struct_type.layout == .@"packed") {
1524 return try cg.resolveType(.fromInterned(struct_type.backingIntTypeUnordered(ip)), .direct);
1513 return try cg.resolveType(.fromInterned(struct_type.packed_backing_int_type), .direct);
15251514 }
15261515
15271516 var member_types = std.array_list.Managed(Id).init(gpa);
......@@ -1536,9 +1525,9 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
15361525 var it = struct_type.iterateRuntimeOrder(ip);
15371526 while (it.next()) |field_index| {
15381527 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
1539 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
1528 if (!field_ty.hasRuntimeBits(zcu)) continue;
15401529
1541 const field_name = struct_type.fieldName(ip, field_index);
1530 const field_name = struct_type.field_names.get(ip)[field_index];
15421531 try member_types.append(try cg.resolveType(field_ty, .indirect));
15431532 try member_names.append(field_name.toSlice(ip));
15441533 try member_offsets.append(@intCast(ty.structFieldOffset(field_index, zcu)));
......@@ -1559,7 +1548,7 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
15591548 },
15601549 .optional => {
15611550 const payload_ty = ty.optionalChild(zcu);
1562 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
1551 if (!payload_ty.hasRuntimeBits(zcu)) {
15631552 // Just use a bool.
15641553 // Note: Always generate the bool with indirect format, to save on some sanity
15651554 // Perform the conversion to a direct bool when the field is extracted.
......@@ -1656,7 +1645,7 @@ fn errorUnionLayout(cg: *CodeGen, payload_ty: Type) ErrorUnionLayout {
16561645
16571646 const error_first = error_align.compare(.gt, payload_align);
16581647 return .{
1659 .payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(zcu),
1648 .payload_has_bits = payload_ty.hasRuntimeBits(zcu),
16601649 .error_first = error_first,
16611650 };
16621651}
......@@ -3727,7 +3716,6 @@ fn cmp(
37273716 const gpa = cg.module.gpa;
37283717 const pt = cg.pt;
37293718 const zcu = cg.module.zcu;
3730 const ip = &zcu.intern_pool;
37313719 const scalar_ty = lhs.ty.scalarType(zcu);
37323720 const is_vector = lhs.ty.isVector(zcu);
37333721
......@@ -3740,7 +3728,7 @@ fn cmp(
37403728 },
37413729 .@"struct" => {
37423730 const struct_ty = zcu.typeToPackedStruct(scalar_ty).?;
3743 const ty: Type = .fromInterned(struct_ty.backingIntTypeUnordered(ip));
3731 const ty: Type = .fromInterned(struct_ty.packed_backing_int_type);
37443732 return try cg.cmp(op, lhs.pun(ty), rhs.pun(ty));
37453733 },
37463734 .error_set => {
......@@ -3781,7 +3769,7 @@ fn cmp(
37813769
37823770 const payload_ty = ty.optionalChild(zcu);
37833771 if (ty.optionalReprIsPayload(zcu)) {
3784 assert(payload_ty.hasRuntimeBitsIgnoreComptime(zcu));
3772 assert(payload_ty.hasRuntimeBits(zcu));
37853773 assert(!payload_ty.isSlice(zcu));
37863774
37873775 return try cg.cmp(op, lhs.pun(payload_ty), rhs.pun(payload_ty));
......@@ -3790,12 +3778,12 @@ fn cmp(
37903778 const lhs_id = try lhs.materialize(cg);
37913779 const rhs_id = try rhs.materialize(cg);
37923780
3793 const lhs_valid_id = if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu))
3781 const lhs_valid_id = if (payload_ty.hasRuntimeBits(zcu))
37943782 try cg.extractField(.bool, lhs_id, 1)
37953783 else
37963784 try cg.convertToDirect(.bool, lhs_id);
37973785
3798 const rhs_valid_id = if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu))
3786 const rhs_valid_id = if (payload_ty.hasRuntimeBits(zcu))
37993787 try cg.extractField(.bool, rhs_id, 1)
38003788 else
38013789 try cg.convertToDirect(.bool, rhs_id);
......@@ -3803,7 +3791,7 @@ fn cmp(
38033791 const lhs_valid: Temporary = .init(.bool, lhs_valid_id);
38043792 const rhs_valid: Temporary = .init(.bool, rhs_valid_id);
38053793
3806 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
3794 if (!payload_ty.hasRuntimeBits(zcu)) {
38073795 return try cg.cmp(op, lhs_valid, rhs_valid);
38083796 }
38093797
......@@ -4141,7 +4129,7 @@ fn airArrayToSlice(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
41414129 const array_ptr_id = try cg.resolve(ty_op.operand);
41424130 const len_id = try cg.constInt(.usize, array_ty.arrayLen(zcu));
41434131
4144 const elem_ptr_id = if (!array_ty.hasRuntimeBitsIgnoreComptime(zcu))
4132 const elem_ptr_id = if (!array_ty.hasRuntimeBits(zcu))
41454133 // Note: The pointer is something like *opaque{}, so we need to bitcast it to the element type.
41464134 try cg.bitCast(elem_ptr_ty, array_ptr_ty, array_ptr_id)
41474135 else
......@@ -4177,12 +4165,12 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
41774165 .@"struct" => {
41784166 if (zcu.typeToPackedStruct(result_ty)) |struct_type| {
41794167 comptime assert(Type.packed_struct_layout_version == 2);
4180 const backing_int_ty: Type = .fromInterned(struct_type.backingIntTypeUnordered(ip));
4168 const backing_int_ty: Type = .fromInterned(struct_type.packed_backing_int_type);
41814169 var running_int_id = try cg.constInt(backing_int_ty, 0);
41824170 var running_bits: u16 = 0;
41834171 for (struct_type.field_types.get(ip), elements) |field_ty_ip, element| {
41844172 const field_ty: Type = .fromInterned(field_ty_ip);
4185 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
4173 if (!field_ty.hasRuntimeBits(zcu)) continue;
41864174 const field_id = try cg.resolve(element);
41874175 const ty_bit_size: u16 = @intCast(field_ty.bitSize(zcu));
41884176 const field_int_ty = try cg.pt.intType(.unsigned, ty_bit_size);
......@@ -4242,7 +4230,7 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
42424230 const field_index = it.next().?;
42434231 if ((try result_ty.structFieldValueComptime(pt, i)) != null) continue;
42444232 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]);
4245 assert(field_ty.hasRuntimeBitsIgnoreComptime(zcu));
4233 assert(field_ty.hasRuntimeBits(zcu));
42464234
42474235 const id = try cg.resolve(element);
42484236 types[index] = field_ty;
......@@ -4381,7 +4369,7 @@ fn airSliceElemVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
43814369fn ptrElemPtr(cg: *CodeGen, ptr_ty: Type, ptr_id: Id, index_id: Id) !Id {
43824370 const zcu = cg.module.zcu;
43834371 // Construct new pointer type for the resulting pointer
4384 const elem_ty = ptr_ty.elemType2(zcu); // use elemType() so that we get T for *[N]T.
4372 const elem_ty = ptr_ty.indexableElem(zcu);
43854373 const elem_ty_id = try cg.resolveType(elem_ty, .indirect);
43864374 const elem_ptr_ty_id = try cg.module.ptrType(elem_ty_id, cg.module.storageClass(ptr_ty.ptrAddressSpace(zcu)));
43874375 if (ptr_ty.isSinglePointer(zcu)) {
......@@ -4402,10 +4390,7 @@ fn airPtrElemPtr(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
44024390 const elem_ty = src_ptr_ty.childType(zcu);
44034391 const ptr_id = try cg.resolve(bin_op.lhs);
44044392
4405 if (!elem_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
4406 const dst_ptr_ty = cg.typeOfIndex(inst);
4407 return try cg.bitCast(dst_ptr_ty, src_ptr_ty, ptr_id);
4408 }
4393 assert(elem_ty.hasRuntimeBits(zcu));
44094394
44104395 const index_id = try cg.resolve(bin_op.rhs);
44114396 return try cg.ptrElemPtr(src_ptr_ty, ptr_id, index_id);
......@@ -4483,7 +4468,7 @@ fn airSetUnionTag(cg: *CodeGen, inst: Air.Inst.Index) !void {
44834468
44844469 if (layout.tag_size == 0) return;
44854470
4486 const tag_ty = un_ty.unionTagTypeSafety(zcu).?;
4471 const tag_ty = un_ty.unionTagTypeRuntime(zcu).?;
44874472 const tag_ty_id = try cg.resolveType(tag_ty, .indirect);
44884473 const tag_ptr_ty_id = try cg.module.ptrType(tag_ty_id, cg.module.storageClass(un_ptr_ty.ptrAddressSpace(zcu)));
44894474
......@@ -4509,7 +4494,7 @@ fn airGetUnionTag(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
45094494 const union_handle = try cg.resolve(ty_op.operand);
45104495 if (!layout.has_payload) return union_handle;
45114496
4512 const tag_ty = un_ty.unionTagTypeSafety(zcu).?;
4497 const tag_ty = un_ty.unionTagTypeRuntime(zcu).?;
45134498 return try cg.extractField(tag_ty, union_handle, layout.tag_index);
45144499}
45154500
......@@ -4529,39 +4514,16 @@ fn unionInit(
45294514 const zcu = cg.module.zcu;
45304515 const ip = &zcu.intern_pool;
45314516 const union_ty = zcu.typeToUnion(ty).?;
4532 const tag_ty: Type = .fromInterned(union_ty.enum_tag_ty);
4517 const tag_ty: Type = .fromInterned(union_ty.enum_tag_type);
45334518
45344519 const layout = cg.unionLayout(ty);
45354520 const payload_ty: Type = .fromInterned(union_ty.field_types.get(ip)[active_field]);
45364521
4537 if (union_ty.flagsUnordered(ip).layout == .@"packed") {
4538 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
4539 const int_ty = try pt.intType(.unsigned, @intCast(ty.bitSize(zcu)));
4540 return cg.constInt(int_ty, 0);
4541 }
4542
4543 assert(payload != null);
4544 if (payload_ty.isInt(zcu)) {
4545 if (ty.bitSize(zcu) == payload_ty.bitSize(zcu)) {
4546 return cg.bitCast(ty, payload_ty, payload.?);
4547 }
4548
4549 const trunc = try cg.buildConvert(ty, .{ .ty = payload_ty, .value = .{ .singleton = payload.? } });
4550 return try trunc.materialize(cg);
4551 }
4552
4553 const payload_int_ty = try pt.intType(.unsigned, @intCast(payload_ty.bitSize(zcu)));
4554 const payload_int = if (payload_ty.ip_index == .bool_type)
4555 try cg.convertToIndirect(payload_ty, payload.?)
4556 else
4557 try cg.bitCast(payload_int_ty, payload_ty, payload.?);
4558 const trunc = try cg.buildConvert(ty, .{ .ty = payload_int_ty, .value = .{ .singleton = payload_int } });
4559 return try trunc.materialize(cg);
4560 }
4522 assert(union_ty.layout != .@"packed");
45614523
45624524 const tag_int = if (layout.tag_size != 0) blk: {
45634525 const tag_val = try pt.enumValueFieldIndex(tag_ty, active_field);
4564 const tag_int_val = try tag_val.intFromEnum(tag_ty, pt);
4526 const tag_int_val = tag_val.intFromEnum(zcu);
45654527 break :blk tag_int_val.toUnsignedInt(zcu);
45664528 } else 0;
45674529
......@@ -4580,7 +4542,7 @@ fn unionInit(
45804542 try cg.store(tag_ty, ptr_id, tag_id, .{});
45814543 }
45824544
4583 if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
4545 if (payload_ty.hasRuntimeBits(zcu)) {
45844546 const layout_payload_ty_id = try cg.resolveType(layout.payload_ty, .indirect);
45854547 const pl_ptr_ty_id = try cg.module.ptrType(layout_payload_ty_id, .function);
45864548 const pl_ptr_id = try cg.accessChain(pl_ptr_ty_id, tmp_id, &.{layout.payload_index});
......@@ -4616,7 +4578,7 @@ fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
46164578
46174579 const union_obj = zcu.typeToUnion(ty).?;
46184580 const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[extra.field_index]);
4619 const payload = if (field_ty.hasRuntimeBitsIgnoreComptime(zcu))
4581 const payload = if (field_ty.hasRuntimeBits(zcu))
46204582 try cg.resolve(extra.init)
46214583 else
46224584 null;
......@@ -4634,7 +4596,7 @@ fn airStructFieldVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
46344596 const field_index = struct_field.field_index;
46354597 const field_ty = object_ty.fieldType(field_index, zcu);
46364598
4637 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) return null;
4599 assert(field_ty.hasRuntimeBits(zcu));
46384600
46394601 switch (object_ty.zigTypeTag(zcu)) {
46404602 .@"struct" => switch (object_ty.containerLayout(zcu)) {
......@@ -4776,33 +4738,36 @@ fn structFieldPtr(
47764738 },
47774739 .@"struct" => switch (object_ty.containerLayout(zcu)) {
47784740 .@"packed" => return cg.todo("implement field access for packed structs", .{}),
4779 else => {
4741 .auto, .@"extern" => {
47804742 return try cg.accessChain(result_ty_id, object_ptr, &.{field_index});
47814743 },
47824744 },
4783 .@"union" => {
4784 const layout = cg.unionLayout(object_ty);
4785 if (!layout.has_payload) {
4786 // Asked to get a pointer to a zero-sized field. Just lower this
4787 // to undefined, there is no reason to make it be a valid pointer.
4788 return try cg.module.constUndef(result_ty_id);
4789 }
4745 .@"union" => switch (object_ty.containerLayout(zcu)) {
4746 .@"packed" => return cg.todo("implement field access for packed unions", .{}),
4747 .auto, .@"extern" => {
4748 const layout = cg.unionLayout(object_ty);
4749 if (!layout.has_payload) {
4750 // Asked to get a pointer to a zero-sized field. Just lower this
4751 // to undefined, there is no reason to make it be a valid pointer.
4752 return try cg.module.constUndef(result_ty_id);
4753 }
47904754
4791 const storage_class = cg.module.storageClass(object_ptr_ty.ptrAddressSpace(zcu));
4792 const layout_payload_ty_id = try cg.resolveType(layout.payload_ty, .indirect);
4793 const pl_ptr_ty_id = try cg.module.ptrType(layout_payload_ty_id, storage_class);
4794 const pl_ptr_id = blk: {
4795 if (object_ty.containerLayout(zcu) == .@"packed") break :blk object_ptr;
4796 break :blk try cg.accessChain(pl_ptr_ty_id, object_ptr, &.{layout.payload_index});
4797 };
4755 const storage_class = cg.module.storageClass(object_ptr_ty.ptrAddressSpace(zcu));
4756 const layout_payload_ty_id = try cg.resolveType(layout.payload_ty, .indirect);
4757 const pl_ptr_ty_id = try cg.module.ptrType(layout_payload_ty_id, storage_class);
4758 const pl_ptr_id = blk: {
4759 if (object_ty.containerLayout(zcu) == .@"packed") break :blk object_ptr;
4760 break :blk try cg.accessChain(pl_ptr_ty_id, object_ptr, &.{layout.payload_index});
4761 };
47984762
4799 const active_pl_ptr_id = cg.module.allocId();
4800 try cg.body.emit(cg.module.gpa, .OpBitcast, .{
4801 .id_result_type = result_ty_id,
4802 .id_result = active_pl_ptr_id,
4803 .operand = pl_ptr_id,
4804 });
4805 return active_pl_ptr_id;
4763 const active_pl_ptr_id = cg.module.allocId();
4764 try cg.body.emit(cg.module.gpa, .OpBitcast, .{
4765 .id_result_type = result_ty_id,
4766 .id_result = active_pl_ptr_id,
4767 .operand = pl_ptr_id,
4768 });
4769 return active_pl_ptr_id;
4770 },
48064771 },
48074772 else => unreachable,
48084773 }
......@@ -5028,7 +4993,7 @@ fn lowerBlock(cg: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index)
50284993 const gpa = cg.module.gpa;
50294994 const zcu = cg.module.zcu;
50304995 const ty = cg.typeOfIndex(inst);
5031 const have_block_result = ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu);
4996 const have_block_result = ty.hasRuntimeBits(zcu);
50324997
50334998 const cf = switch (cg.control_flow) {
50344999 .structured => |*cf| cf,
......@@ -5166,7 +5131,7 @@ fn airBr(cg: *CodeGen, inst: Air.Inst.Index) !void {
51665131
51675132 switch (cg.control_flow) {
51685133 .structured => |*cf| {
5169 if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {
5134 if (operand_ty.hasRuntimeBits(zcu)) {
51705135 const operand_id = try cg.resolve(br.operand);
51715136 const block_result_var_id = cf.block_results.get(br.block_inst).?;
51725137 try cg.store(operand_ty, block_result_var_id, operand_id, .{});
......@@ -5177,7 +5142,7 @@ fn airBr(cg: *CodeGen, inst: Air.Inst.Index) !void {
51775142 },
51785143 .unstructured => |cf| {
51795144 const block = cf.blocks.get(br.block_inst).?;
5180 if (operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {
5145 if (operand_ty.hasRuntimeBits(zcu)) {
51815146 const operand_id = try cg.resolve(br.operand);
51825147 // block_label should not be undefined here, lest there
51835148 // is a br or br_void in the function's body.
......@@ -5335,7 +5300,7 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) !void {
53355300 const zcu = cg.module.zcu;
53365301 const operand = cg.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
53375302 const ret_ty = cg.typeOf(operand);
5338 if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
5303 if (!ret_ty.hasRuntimeBits(zcu)) {
53395304 const fn_info = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?;
53405305 if (Type.fromInterned(fn_info.return_type).isError(zcu)) {
53415306 // Functions with an empty error set are emitted with an error code
......@@ -5359,7 +5324,7 @@ fn airRetLoad(cg: *CodeGen, inst: Air.Inst.Index) !void {
53595324 const ptr_ty = cg.typeOf(un_op);
53605325 const ret_ty = ptr_ty.childType(zcu);
53615326
5362 if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
5327 if (!ret_ty.hasRuntimeBits(zcu)) {
53635328 const fn_info = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?;
53645329 if (Type.fromInterned(fn_info.return_type).isError(zcu)) {
53655330 // Functions with an empty error set are emitted with an error code
......@@ -5576,7 +5541,7 @@ fn airIsNull(cg: *CodeGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum {
55765541
55775542 const is_non_null_id = blk: {
55785543 if (is_pointer) {
5579 if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
5544 if (payload_ty.hasRuntimeBits(zcu)) {
55805545 const storage_class = cg.module.storageClass(operand_ty.ptrAddressSpace(zcu));
55815546 const bool_indirect_ty_id = try cg.resolveType(.bool, .indirect);
55825547 const bool_ptr_ty_id = try cg.module.ptrType(bool_indirect_ty_id, storage_class);
......@@ -5587,7 +5552,7 @@ fn airIsNull(cg: *CodeGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum {
55875552 break :blk try cg.load(.bool, operand_id, .{});
55885553 }
55895554
5590 break :blk if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu))
5555 break :blk if (payload_ty.hasRuntimeBits(zcu))
55915556 try cg.extractField(.bool, operand_id, 1)
55925557 else
55935558 // Optional representation is bool indicating whether the optional is set
......@@ -5656,7 +5621,7 @@ fn airUnwrapOptional(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
56565621 const optional_ty = cg.typeOf(ty_op.operand);
56575622 const payload_ty = cg.typeOfIndex(inst);
56585623
5659 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) return null;
5624 if (!payload_ty.hasRuntimeBits(zcu)) return null;
56605625
56615626 if (optional_ty.optionalReprIsPayload(zcu)) {
56625627 return operand_id;
......@@ -5675,7 +5640,7 @@ fn airUnwrapOptionalPtr(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
56755640 const result_ty = cg.typeOfIndex(inst);
56765641 const result_ty_id = try cg.resolveType(result_ty, .direct);
56775642
5678 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
5643 if (!payload_ty.hasRuntimeBits(zcu)) {
56795644 // There is no payload, but we still need to return a valid pointer.
56805645 // We can just return anything here, so just return a pointer to the operand.
56815646 return try cg.bitCast(result_ty, operand_ty, operand_id);
......@@ -5694,9 +5659,7 @@ fn airWrapOptional(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
56945659 const ty_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
56955660 const payload_ty = cg.typeOf(ty_op.operand);
56965661
5697 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
5698 return try cg.constBool(true, .indirect);
5699 }
5662 assert(payload_ty.hasRuntimeBits(zcu));
57005663
57015664 const operand_id = try cg.resolve(ty_op.operand);
57025665
......@@ -5792,8 +5755,7 @@ fn airSwitchBr(cg: *CodeGen, inst: Air.Inst.Index) !void {
57925755 const int_val: u64 = switch (cond_ty.zigTypeTag(zcu)) {
57935756 .bool, .int => if (cond_ty.isSignedInt(zcu)) @bitCast(value.toSignedInt(zcu)) else value.toUnsignedInt(zcu),
57945757 .@"enum" => blk: {
5795 // TODO: figure out of cond_ty is correct (something with enum literals)
5796 break :blk (try value.intFromEnum(cond_ty, pt)).toUnsignedInt(zcu); // TODO: composite integer constants
5758 break :blk value.intFromEnum(zcu).toUnsignedInt(zcu); // TODO: composite integer constants
57975759 },
57985760 .error_set => value.getErrorInt(zcu),
57995761 .pointer => value.toUnsignedInt(zcu),
......@@ -6070,7 +6032,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie
60706032 // before starting to emit OpFunctionCall instructions. Hence the
60716033 // temporary params buffer.
60726034 const arg_ty = cg.typeOf(arg);
6073 if (!arg_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
6035 if (!arg_ty.hasRuntimeBits(zcu)) continue;
60746036 const arg_id = try cg.resolve(arg);
60756037
60766038 params[n_params] = arg_id;
......@@ -6084,7 +6046,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie
60846046 .id_ref_3 = params[0..n_params],
60856047 });
60866048
6087 if (cg.liveness.isUnused(inst) or !Type.fromInterned(return_type).hasRuntimeBitsIgnoreComptime(zcu)) {
6049 if (cg.liveness.isUnused(inst) or !Type.fromInterned(return_type).hasRuntimeBits(zcu)) {
60886050 return null;
60896051 }
60906052
src/codegen/wasm/CodeGen.zig+77-151
......@@ -759,7 +759,7 @@ fn resolveInst(cg: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
759759 const zcu = pt.zcu;
760760 const val = (try cg.air.value(ref, pt)).?;
761761 const ty = cg.typeOf(ref);
762 if (!ty.hasRuntimeBitsIgnoreComptime(zcu) and !ty.isInt(zcu) and !ty.isError(zcu)) {
762 if (!ty.hasRuntimeBits(zcu) and !ty.isInt(zcu) and !ty.isError(zcu)) {
763763 gop.value_ptr.* = .none;
764764 return .none;
765765 }
......@@ -773,7 +773,7 @@ fn resolveInst(cg: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
773773 const result: WValue = if (isByRef(ty, zcu, cg.target))
774774 .{ .uav_ref = .{ .ip_index = val.toIntern() } }
775775 else
776 try cg.lowerConstant(val, ty);
776 try cg.lowerConstant(val);
777777
778778 gop.value_ptr.* = result;
779779 return result;
......@@ -786,7 +786,7 @@ fn resolveValue(cg: *CodeGen, val: Value) InnerError!WValue {
786786 return if (isByRef(ty, zcu, cg.target))
787787 .{ .uav_ref = .{ .ip_index = val.toIntern() } }
788788 else
789 try cg.lowerConstant(val, ty);
789 try cg.lowerConstant(val);
790790}
791791
792792/// NOTE: if result == .stack, it will be stored in .local
......@@ -980,7 +980,6 @@ fn addExtraAssumeCapacity(cg: *CodeGen, extra: anytype) error{OutOfMemory}!u32 {
980980
981981/// For `std.builtin.CallingConvention.auto`.
982982pub fn typeToValtype(ty: Type, zcu: *const Zcu, target: *const std.Target) std.wasm.Valtype {
983 const ip = &zcu.intern_pool;
984983 return switch (ty.zigTypeTag(zcu)) {
985984 .float => switch (ty.floatBits(target)) {
986985 16 => .i32, // stored/loaded as u16
......@@ -994,25 +993,13 @@ pub fn typeToValtype(ty: Type, zcu: *const Zcu, target: *const std.Target) std.w
994993 33...64 => .i64,
995994 else => .i32,
996995 },
997 .@"struct" => blk: {
998 if (zcu.typeToPackedStruct(ty)) |packed_struct| {
999 const backing_int_ty = Type.fromInterned(packed_struct.backingIntTypeUnordered(ip));
1000 break :blk typeToValtype(backing_int_ty, zcu, target);
1001 } else {
1002 break :blk .i32;
1003 }
1004 },
1005996 .vector => switch (CodeGen.determineSimdStoreStrategy(ty, zcu, target)) {
1006997 .direct => .v128,
1007998 .unrolled => .i32,
1008999 },
1009 .@"union" => switch (ty.containerLayout(zcu)) {
1010 .@"packed" => switch (ty.bitSize(zcu)) {
1011 0...32 => .i32,
1012 33...64 => .i64,
1013 else => .i32,
1014 },
1015 else => .i32,
1000 .@"union", .@"struct" => switch (ty.containerLayout(zcu)) {
1001 .@"packed" => typeToValtype(ty.bitpackBackingInt(zcu), zcu, target),
1002 .auto, .@"extern" => .i32,
10161003 },
10171004 else => .i32, // all represented as reference/immediate
10181005 };
......@@ -1185,7 +1172,7 @@ pub fn generate(
11851172 const fn_ty = zcu.navValue(cg.owner_nav).typeOf(zcu);
11861173 const fn_info = zcu.typeToFunc(fn_ty).?;
11871174 const ret_ty: Type = .fromInterned(fn_info.return_type);
1188 const any_returns = !firstParamSRet(fn_info.cc, ret_ty, zcu, target) and ret_ty.hasRuntimeBitsIgnoreComptime(zcu);
1175 const any_returns = !firstParamSRet(fn_info.cc, ret_ty, zcu, target) and ret_ty.hasRuntimeBits(zcu);
11891176
11901177 var cc_result = try resolveCallingConventionValues(zcu, fn_ty, target);
11911178 defer cc_result.deinit(gpa);
......@@ -1244,7 +1231,7 @@ fn generateInner(cg: *CodeGen, any_returns: bool) InnerError!Mir {
12441231 if (any_returns and cg.air.instructions.len > 0) {
12451232 const inst: Air.Inst.Index = @enumFromInt(cg.air.instructions.len - 1);
12461233 const last_inst_ty = cg.typeOfIndex(inst);
1247 if (!last_inst_ty.hasRuntimeBitsIgnoreComptime(zcu) or last_inst_ty.isNoReturn(zcu)) {
1234 if (!last_inst_ty.hasRuntimeBits(zcu)) {
12481235 try cg.addTag(.@"unreachable");
12491236 }
12501237 }
......@@ -1316,7 +1303,7 @@ fn resolveCallingConventionValues(
13161303 switch (cc) {
13171304 .auto => {
13181305 for (fn_info.param_types.get(ip)) |ty| {
1319 if (!Type.fromInterned(ty).hasRuntimeBitsIgnoreComptime(zcu)) {
1306 if (!Type.fromInterned(ty).hasRuntimeBits(zcu)) {
13201307 continue;
13211308 }
13221309
......@@ -1326,7 +1313,7 @@ fn resolveCallingConventionValues(
13261313 },
13271314 .wasm_mvp => {
13281315 for (fn_info.param_types.get(ip)) |ty| {
1329 if (!Type.fromInterned(ty).hasRuntimeBitsIgnoreComptime(zcu)) {
1316 if (!Type.fromInterned(ty).hasRuntimeBits(zcu)) {
13301317 continue;
13311318 }
13321319 switch (abi.classifyType(.fromInterned(ty), zcu)) {
......@@ -1357,7 +1344,7 @@ pub fn firstParamSRet(
13571344 zcu: *const Zcu,
13581345 target: *const std.Target,
13591346) bool {
1360 if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) return false;
1347 if (!return_type.hasRuntimeBits(zcu)) return false;
13611348 switch (cc) {
13621349 .@"inline" => unreachable,
13631350 .auto => return isByRef(return_type, zcu, target),
......@@ -1457,7 +1444,7 @@ fn restoreStackPointer(cg: *CodeGen) !void {
14571444fn allocStack(cg: *CodeGen, ty: Type) !WValue {
14581445 const pt = cg.pt;
14591446 const zcu = pt.zcu;
1460 assert(ty.hasRuntimeBitsIgnoreComptime(zcu));
1447 assert(ty.hasRuntimeBits(zcu));
14611448 if (cg.initial_stack_value == .none) {
14621449 try cg.initializeStack();
14631450 }
......@@ -1491,7 +1478,7 @@ fn allocStackPtr(cg: *CodeGen, inst: Air.Inst.Index) !WValue {
14911478 try cg.initializeStack();
14921479 }
14931480
1494 if (!pointee_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
1481 if (!pointee_ty.hasRuntimeBits(zcu)) {
14951482 return cg.allocStack(Type.usize); // create a value containing just the stack pointer.
14961483 }
14971484
......@@ -1676,7 +1663,6 @@ fn ptrSize(cg: *const CodeGen) u16 {
16761663/// For a given `Type`, will return true when the type will be passed
16771664/// by reference, rather than by value
16781665fn isByRef(ty: Type, zcu: *const Zcu, target: *const std.Target) bool {
1679 const ip = &zcu.intern_pool;
16801666 switch (ty.zigTypeTag(zcu)) {
16811667 .type,
16821668 .comptime_int,
......@@ -1697,20 +1683,10 @@ fn isByRef(ty: Type, zcu: *const Zcu, target: *const std.Target) bool {
16971683
16981684 .array,
16991685 .frame,
1700 => return ty.hasRuntimeBitsIgnoreComptime(zcu),
1701 .@"union" => {
1702 if (zcu.typeToUnion(ty)) |union_obj| {
1703 if (union_obj.flagsUnordered(ip).layout == .@"packed") {
1704 return ty.abiSize(zcu) > 8;
1705 }
1706 }
1707 return ty.hasRuntimeBitsIgnoreComptime(zcu);
1708 },
1709 .@"struct" => {
1710 if (zcu.typeToPackedStruct(ty)) |packed_struct| {
1711 return isByRef(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)), zcu, target);
1712 }
1713 return ty.hasRuntimeBitsIgnoreComptime(zcu);
1686 => return ty.hasRuntimeBits(zcu),
1687 .@"struct", .@"union" => switch (ty.containerLayout(zcu)) {
1688 .@"packed" => return isByRef(ty.bitpackBackingInt(zcu), zcu, target),
1689 .@"extern", .auto => return ty.hasRuntimeBits(zcu),
17141690 },
17151691 .vector => return determineSimdStoreStrategy(ty, zcu, target) == .unrolled,
17161692 .int => return ty.intInfo(zcu).bits > 64,
......@@ -1718,7 +1694,7 @@ fn isByRef(ty: Type, zcu: *const Zcu, target: *const std.Target) bool {
17181694 .float => return ty.floatBits(target) > 64,
17191695 .error_union => {
17201696 const pl_ty = ty.errorUnionPayload(zcu);
1721 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
1697 if (!pl_ty.hasRuntimeBits(zcu)) {
17221698 return false;
17231699 }
17241700 return true;
......@@ -1727,7 +1703,7 @@ fn isByRef(ty: Type, zcu: *const Zcu, target: *const std.Target) bool {
17271703 if (ty.isPtrLikeOptional(zcu)) return false;
17281704 const pl_type = ty.optionalChild(zcu);
17291705 if (pl_type.zigTypeTag(zcu) == .error_set) return false;
1730 return pl_type.hasRuntimeBitsIgnoreComptime(zcu);
1706 return pl_type.hasRuntimeBits(zcu);
17311707 },
17321708 .pointer => {
17331709 // Slices act like struct and will be passed by reference
......@@ -2069,7 +2045,7 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
20692045 // to the stack instead
20702046 if (cg.return_value != .none) {
20712047 try cg.store(cg.return_value, operand, ret_ty, 0);
2072 } else if (fn_info.cc == .wasm_mvp and ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
2048 } else if (fn_info.cc == .wasm_mvp and ret_ty.hasRuntimeBits(zcu)) {
20732049 switch (abi.classifyType(ret_ty, zcu)) {
20742050 .direct => |scalar_type| {
20752051 assert(!abi.lowerAsDoubleI64(scalar_type, zcu));
......@@ -2082,7 +2058,7 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
20822058 .indirect => unreachable,
20832059 }
20842060 } else {
2085 if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu) and ret_ty.isError(zcu)) {
2061 if (!ret_ty.hasRuntimeBits(zcu) and ret_ty.isError(zcu)) {
20862062 try cg.addImm32(0);
20872063 } else {
20882064 try cg.emitWValue(operand);
......@@ -2099,7 +2075,7 @@ fn airRetPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
20992075 const child_type = cg.typeOfIndex(inst).childType(zcu);
21002076
21012077 const result = result: {
2102 if (!child_type.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {
2078 if (!child_type.hasRuntimeBits(zcu)) {
21032079 break :result try cg.allocStack(Type.usize); // create pointer to void
21042080 }
21052081
......@@ -2121,7 +2097,7 @@ fn airRetLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
21212097 const ret_ty = cg.typeOf(un_op).childType(zcu);
21222098
21232099 const fn_info = zcu.typeToFunc(zcu.navValue(cg.owner_nav).typeOf(zcu)).?;
2124 if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
2100 if (!ret_ty.hasRuntimeBits(zcu)) {
21252101 if (ret_ty.isError(zcu)) {
21262102 try cg.addImm32(0);
21272103 }
......@@ -2177,7 +2153,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie
21772153 const arg_val = try cg.resolveInst(arg);
21782154
21792155 const arg_ty = cg.typeOf(arg);
2180 if (!arg_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
2156 if (!arg_ty.hasRuntimeBits(zcu)) continue;
21812157
21822158 try cg.lowerArg(zcu.typeToFunc(fn_ty).?.cc, arg_ty, arg_val);
21832159 }
......@@ -2199,10 +2175,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie
21992175 }
22002176
22012177 const result_value = result_value: {
2202 if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu) and !ret_ty.isError(zcu)) {
2203 break :result_value .none;
2204 } else if (ret_ty.isNoReturn(zcu)) {
2205 try cg.addTag(.@"unreachable");
2178 if (!ret_ty.hasRuntimeBits(zcu) and !ret_ty.isError(zcu)) {
22062179 break :result_value .none;
22072180 } else if (first_param_sret) {
22082181 break :result_value sret;
......@@ -2323,12 +2296,12 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErr
23232296 const zcu = pt.zcu;
23242297 const abi_size = ty.abiSize(zcu);
23252298
2326 if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) return;
2299 if (!ty.hasRuntimeBits(zcu)) return;
23272300
23282301 switch (ty.zigTypeTag(zcu)) {
23292302 .error_union => {
23302303 const pl_ty = ty.errorUnionPayload(zcu);
2331 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
2304 if (!pl_ty.hasRuntimeBits(zcu)) {
23322305 return cg.store(lhs, rhs, Type.anyerror, offset);
23332306 }
23342307
......@@ -2341,7 +2314,7 @@ fn store(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErr
23412314 return cg.store(lhs, rhs, Type.usize, offset);
23422315 }
23432316 const pl_ty = ty.optionalChild(zcu);
2344 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
2317 if (!pl_ty.hasRuntimeBits(zcu)) {
23452318 return cg.store(lhs, rhs, Type.u8, offset);
23462319 }
23472320 if (pl_ty.zigTypeTag(zcu) == .error_set) {
......@@ -2441,7 +2414,7 @@ fn airLoad(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
24412414 const ptr_ty = cg.typeOf(ty_op.operand);
24422415 const ptr_info = ptr_ty.ptrInfo(zcu);
24432416
2444 if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) return cg.finishAir(inst, .none, &.{ty_op.operand});
2417 if (!ty.hasRuntimeBits(zcu)) return cg.finishAir(inst, .none, &.{ty_op.operand});
24452418
24462419 const result = result: {
24472420 if (isByRef(ty, zcu, cg.target)) {
......@@ -3092,7 +3065,7 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro
30923065 return switch (ptr.base_addr) {
30933066 .nav => |nav| return .{ .nav_ref = .{ .nav_index = nav, .offset = @intCast(offset) } },
30943067 .uav => |uav| return .{ .uav_ref = .{ .ip_index = uav.val, .offset = @intCast(offset), .orig_ptr_ty = uav.orig_ty } },
3095 .int => return cg.lowerConstant(try pt.intValue(Type.usize, offset), Type.usize),
3068 .int => return cg.lowerConstant(try pt.intValue(.usize, offset)),
30963069 .eu_payload => |eu_ptr| try cg.lowerPtr(
30973070 eu_ptr,
30983071 offset + codegen.errUnionPayloadOffset(
......@@ -3129,10 +3102,11 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro
31293102 };
31303103}
31313104
3132/// Asserts that `isByRef` returns `false` for `ty`.
3133fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3105/// Asserts that `isByRef` returns `false` for `val.typeOf(zcu)`.
3106fn lowerConstant(cg: *CodeGen, val: Value) InnerError!WValue {
31343107 const pt = cg.pt;
31353108 const zcu = pt.zcu;
3109 const ty = val.typeOf(zcu);
31363110 assert(!isByRef(ty, zcu, cg.target));
31373111 const ip = &zcu.intern_pool;
31383112 if (val.isUndef(zcu)) return cg.emitUndefined(ty);
......@@ -3158,10 +3132,8 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
31583132
31593133 .undef => unreachable, // handled above
31603134 .simple_value => |simple_value| switch (simple_value) {
3161 .undefined,
31623135 .void,
31633136 .null,
3164 .empty_tuple,
31653137 .@"unreachable",
31663138 => unreachable, // non-runtime values
31673139 .false, .true => return .{ .imm32 = switch (simple_value) {
......@@ -3174,7 +3146,6 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
31743146 .@"extern",
31753147 .func,
31763148 .enum_literal,
3177 .empty_enum_value,
31783149 => unreachable, // non-runtime values
31793150 .int => {
31803151 const int_info = ty.intInfo(zcu);
......@@ -3197,31 +3168,22 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
31973168 },
31983169 .error_union => |error_union| {
31993170 const err_int_ty = try pt.errorIntType();
3200 const err_ty, const err_val = switch (error_union.val) {
3201 .err_name => |err_name| .{
3202 ty.errorUnionSet(zcu),
3203 Value.fromInterned(try pt.intern(.{ .err = .{
3204 .ty = ty.errorUnionSet(zcu).toIntern(),
3205 .name = err_name,
3206 } })),
3207 },
3208 .payload => .{
3209 err_int_ty,
3210 try pt.intValue(err_int_ty, 0),
3211 },
3171 const err_val: Value = switch (error_union.val) {
3172 .err_name => |err_name| .fromInterned(try pt.intern(.{ .err = .{
3173 .ty = ty.errorUnionSet(zcu).toIntern(),
3174 .name = err_name,
3175 } })),
3176 .payload => try pt.intValue(err_int_ty, 0),
32123177 };
32133178 const payload_type = ty.errorUnionPayload(zcu);
3214 if (!payload_type.hasRuntimeBitsIgnoreComptime(zcu)) {
3179 if (!payload_type.hasRuntimeBits(zcu)) {
32153180 // We use the error type directly as the type.
3216 return cg.lowerConstant(err_val, err_ty);
3181 return cg.lowerConstant(err_val);
32173182 }
32183183
32193184 return cg.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{});
32203185 },
3221 .enum_tag => |enum_tag| {
3222 const int_tag_ty = ip.typeOf(enum_tag.int);
3223 return cg.lowerConstant(Value.fromInterned(enum_tag.int), Type.fromInterned(int_tag_ty));
3224 },
3186 .enum_tag => |enum_tag| return cg.lowerConstant(.fromInterned(enum_tag.int)),
32253187 .float => |float| switch (float.storage) {
32263188 .f16 => |f16_val| return .{ .imm32 = @as(u16, @bitCast(f16_val)) },
32273189 .f32 => |f32_val| return .{ .float32 = f32_val },
......@@ -3231,9 +3193,8 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
32313193 .slice => unreachable, // isByRef == true
32323194 .ptr => return cg.lowerPtr(val.toIntern(), 0),
32333195 .opt => if (ty.optionalReprIsPayload(zcu)) {
3234 const pl_ty = ty.optionalChild(zcu);
32353196 if (val.optionalValue(zcu)) |payload| {
3236 return cg.lowerConstant(payload, pl_ty);
3197 return cg.lowerConstant(payload);
32373198 } else {
32383199 return .{ .imm32 = 0 };
32393200 }
......@@ -3248,33 +3209,11 @@ fn lowerConstant(cg: *CodeGen, val: Value, ty: Type) InnerError!WValue {
32483209 val.writeToMemory(pt, &buf) catch unreachable;
32493210 return cg.storeSimdImmd(buf);
32503211 },
3251 .struct_type => {
3252 const struct_type = ip.loadStructType(ty.toIntern());
3253 // non-packed structs are not handled in this function because they
3254 // are by-ref types.
3255 assert(struct_type.layout == .@"packed");
3256 var buf: [8]u8 = .{0} ** 8; // zero the buffer so we do not read 0xaa as integer
3257 val.writeToPackedMemory(ty, pt, &buf, 0) catch unreachable;
3258 const backing_int_ty = Type.fromInterned(struct_type.backingIntTypeUnordered(ip));
3259 const int_val = try pt.intValue(
3260 backing_int_ty,
3261 mem.readInt(u64, &buf, .little),
3262 );
3263 return cg.lowerConstant(int_val, backing_int_ty);
3264 },
3212 .struct_type => unreachable, // packed structs use `bitpack`
32653213 else => unreachable,
32663214 },
3267 .un => {
3268 const int_type = try pt.intType(.unsigned, @intCast(ty.bitSize(zcu)));
3269
3270 var buf: [8]u8 = .{0} ** 8; // zero the buffer so we do not read 0xaa as integer
3271 val.writeToPackedMemory(ty, pt, &buf, 0) catch unreachable;
3272 const int_val = try pt.intValue(
3273 int_type,
3274 mem.readInt(u64, &buf, .little),
3275 );
3276 return cg.lowerConstant(int_val, int_type);
3277 },
3215 .un => unreachable, // packed unions use `bitpack`
3216 .bitpack => |bitpack| return cg.lowerConstant(.fromInterned(bitpack.backing_int_val)),
32783217 .memoized_call => unreachable,
32793218 }
32803219}
......@@ -3289,7 +3228,6 @@ fn storeSimdImmd(cg: *CodeGen, value: [16]u8) !WValue {
32893228
32903229fn emitUndefined(cg: *CodeGen, ty: Type) InnerError!WValue {
32913230 const zcu = cg.pt.zcu;
3292 const ip = &zcu.intern_pool;
32933231 switch (ty.zigTypeTag(zcu)) {
32943232 .bool, .error_set => return .{ .imm32 = 0xaaaaaaaa },
32953233 .int, .@"enum" => switch (ty.intInfo(zcu).bits) {
......@@ -3317,17 +3255,9 @@ fn emitUndefined(cg: *CodeGen, ty: Type) InnerError!WValue {
33173255 .error_union => {
33183256 return .{ .imm32 = 0xaaaaaaaa };
33193257 },
3320 .@"struct" => {
3321 const packed_struct = zcu.typeToPackedStruct(ty).?;
3322 return cg.emitUndefined(Type.fromInterned(packed_struct.backingIntTypeUnordered(ip)));
3323 },
3324 .@"union" => switch (ty.containerLayout(zcu)) {
3325 .@"packed" => switch (ty.bitSize(zcu)) {
3326 0...32 => return .{ .imm32 = 0xaaaaaaaa },
3327 33...64 => return .{ .imm64 = 0xaaaaaaaaaaaaaaaa },
3328 else => unreachable,
3329 },
3330 else => unreachable,
3258 .@"struct", .@"union" => {
3259 const backing_int_ty = ty.bitpackBackingInt(zcu);
3260 return cg.emitUndefined(backing_int_ty);
33313261 },
33323262 else => return cg.fail("Wasm TODO: emitUndefined for type: {t}\n", .{ty.zigTypeTag(zcu)}),
33333263 }
......@@ -3341,7 +3271,7 @@ fn airBlock(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
33413271fn lowerBlock(cg: *CodeGen, inst: Air.Inst.Index, block_ty: Type, body: []const Air.Inst.Index) InnerError!void {
33423272 const zcu = cg.pt.zcu;
33433273 // if wasm_block_ty is non-empty, we create a register to store the temporary value
3344 const block_result: WValue = if (block_ty.hasRuntimeBitsIgnoreComptime(zcu))
3274 const block_result: WValue = if (block_ty.hasRuntimeBits(zcu))
33453275 try cg.allocLocal(block_ty)
33463276 else
33473277 .none;
......@@ -3455,7 +3385,7 @@ fn cmp(cg: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareOpe
34553385 const zcu = cg.pt.zcu;
34563386 if (ty.zigTypeTag(zcu) == .optional and !ty.optionalReprIsPayload(zcu)) {
34573387 const payload_ty = ty.optionalChild(zcu);
3458 if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
3388 if (payload_ty.hasRuntimeBits(zcu)) {
34593389 // When we hit this case, we must check the value of optionals
34603390 // that are not pointers. This means first checking against non-null for
34613391 // both lhs and rhs, as well as checking the payload are matching of lhs and rhs
......@@ -3798,7 +3728,6 @@ fn structFieldPtr(
37983728fn airStructFieldVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37993729 const pt = cg.pt;
38003730 const zcu = pt.zcu;
3801 const ip = &zcu.intern_pool;
38023731 const ty_pl = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
38033732 const struct_field = cg.air.extraData(Air.StructField, ty_pl.payload).data;
38043733
......@@ -3806,14 +3735,14 @@ fn airStructFieldVal(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38063735 const operand = try cg.resolveInst(struct_field.struct_operand);
38073736 const field_index = struct_field.field_index;
38083737 const field_ty = struct_ty.fieldType(field_index, zcu);
3809 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) return cg.finishAir(inst, .none, &.{struct_field.struct_operand});
3738 if (!field_ty.hasRuntimeBits(zcu)) return cg.finishAir(inst, .none, &.{struct_field.struct_operand});
38103739
38113740 const result: WValue = switch (struct_ty.containerLayout(zcu)) {
38123741 .@"packed" => switch (struct_ty.zigTypeTag(zcu)) {
38133742 .@"struct" => result: {
38143743 const packed_struct = zcu.typeToPackedStruct(struct_ty).?;
38153744 const offset = zcu.structPackedFieldBitOffset(packed_struct, field_index);
3816 const backing_ty = Type.fromInterned(packed_struct.backingIntTypeUnordered(ip));
3745 const backing_ty = Type.fromInterned(packed_struct.packed_backing_int_type);
38173746 const host_bits = backing_ty.intInfo(zcu).bits;
38183747
38193748 const const_wvalue: WValue = if (33 <= host_bits and host_bits <= 64)
......@@ -3891,7 +3820,7 @@ fn airSwitchBr(cg: *CodeGen, inst: Air.Inst.Index, is_dispatch_loop: bool) Inner
38913820 const switch_br = cg.air.unwrapSwitch(inst);
38923821 const target_ty = cg.typeOf(switch_br.operand);
38933822
3894 assert(target_ty.hasRuntimeBitsIgnoreComptime(zcu));
3823 assert(target_ty.hasRuntimeBits(zcu));
38953824
38963825 // swap target value with placeholder local, for dispatching
38973826 const target = if (is_dispatch_loop) target: {
......@@ -4125,7 +4054,7 @@ fn airIsErr(cg: *CodeGen, inst: Air.Inst.Index, opcode: std.wasm.Opcode, op_kind
41254054 }
41264055
41274056 try cg.emitWValue(operand);
4128 if (op_kind == .ptr or pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
4057 if (op_kind == .ptr or pl_ty.hasRuntimeBits(zcu)) {
41294058 try cg.addMemArg(.i32_load16_u, .{
41304059 .offset = operand.offset() + @as(u32, @intCast(errUnionErrorOffset(pl_ty, zcu))),
41314060 .alignment = @intCast(Type.anyerror.abiAlignment(zcu).toByteUnits().?),
......@@ -4152,7 +4081,7 @@ fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
41524081 const payload_ty = eu_ty.errorUnionPayload(zcu);
41534082
41544083 const result: WValue = result: {
4155 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
4084 if (!payload_ty.hasRuntimeBits(zcu)) {
41564085 if (op_is_ptr) {
41574086 break :result cg.reuseOperand(ty_op.operand, operand);
41584087 } else {
......@@ -4172,7 +4101,7 @@ fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
41724101}
41734102
41744103/// E!T -> E op_is_ptr == false
4175/// *(E!T) -> E op_is_prt == true
4104/// *(E!T) -> E op_is_ptr == true
41764105/// NOTE: op_is_ptr will not change return type
41774106fn airUnwrapErrUnionError(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
41784107 const zcu = cg.pt.zcu;
......@@ -4192,7 +4121,7 @@ fn airUnwrapErrUnionError(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) I
41924121 if (op_is_ptr or isByRef(eu_ty, zcu, cg.target)) {
41934122 break :result try cg.load(operand, Type.anyerror, err_offset);
41944123 } else {
4195 assert(!payload_ty.hasRuntimeBitsIgnoreComptime(zcu));
4124 assert(!payload_ty.hasRuntimeBits(zcu));
41964125 break :result cg.reuseOperand(ty_op.operand, operand);
41974126 }
41984127 };
......@@ -4208,7 +4137,7 @@ fn airWrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
42084137
42094138 const pl_ty = cg.typeOf(ty_op.operand);
42104139 const result = result: {
4211 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
4140 if (!pl_ty.hasRuntimeBits(zcu)) {
42124141 break :result cg.reuseOperand(ty_op.operand, operand);
42134142 }
42144143
......@@ -4238,7 +4167,7 @@ fn airWrapErrUnionErr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
42384167 const pl_ty = err_ty.errorUnionPayload(zcu);
42394168
42404169 const result = result: {
4241 if (!pl_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
4170 if (!pl_ty.hasRuntimeBits(zcu)) {
42424171 break :result cg.reuseOperand(ty_op.operand, operand);
42434172 }
42444173
......@@ -4354,7 +4283,7 @@ fn isNull(cg: *CodeGen, operand: WValue, optional_ty: Type, opcode: std.wasm.Opc
43544283 if (!optional_ty.optionalReprIsPayload(zcu)) {
43554284 // When payload is zero-bits, we can treat operand as a value, rather than
43564285 // a pointer to the stack value
4357 if (payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
4286 if (payload_ty.hasRuntimeBits(zcu)) {
43584287 const offset = std.math.cast(u32, payload_ty.abiSize(zcu)) orelse {
43594288 return cg.fail("Optional type {f} too big to fit into stack frame", .{optional_ty.fmt(pt)});
43604289 };
......@@ -4379,7 +4308,7 @@ fn airOptionalPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
43794308 const ty_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
43804309 const opt_ty = cg.typeOf(ty_op.operand);
43814310 const payload_ty = cg.typeOfIndex(inst);
4382 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
4311 if (!payload_ty.hasRuntimeBits(zcu)) {
43834312 return cg.finishAir(inst, .none, &.{ty_op.operand});
43844313 }
43854314
......@@ -4404,7 +4333,7 @@ fn airOptionalPayloadPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
44044333
44054334 const result = result: {
44064335 const payload_ty = opt_ty.optionalChild(zcu);
4407 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu) or opt_ty.optionalReprIsPayload(zcu)) {
4336 if (!payload_ty.hasRuntimeBits(zcu) or opt_ty.optionalReprIsPayload(zcu)) {
44084337 break :result cg.reuseOperand(ty_op.operand, operand);
44094338 }
44104339
......@@ -4444,7 +4373,7 @@ fn airWrapOptional(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
44444373 const zcu = pt.zcu;
44454374
44464375 const result = result: {
4447 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
4376 if (!payload_ty.hasRuntimeBits(zcu)) {
44484377 const non_null_bit = try cg.allocStack(Type.u1);
44494378 try cg.emitWValue(non_null_bit);
44504379 try cg.addImm32(1);
......@@ -4612,7 +4541,7 @@ fn airArrayToSlice(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
46124541 const slice_local = try cg.allocStack(slice_ty);
46134542
46144543 // store the array ptr in the slice
4615 if (array_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
4544 if (array_ty.hasRuntimeBits(zcu)) {
46164545 try cg.store(slice_local, operand, Type.usize, 0);
46174546 }
46184547
......@@ -5111,7 +5040,7 @@ fn airShuffleOne(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
51115040 try cg.emitWValue(dest_alloc);
51125041 const elem_val = switch (mask_elem.unwrap()) {
51135042 .elem => |idx| try cg.load(operand, elem_ty, @intCast(elem_size * idx)),
5114 .value => |val| try cg.lowerConstant(.fromInterned(val), elem_ty),
5043 .value => |val| try cg.lowerConstant(.fromInterned(val)),
51155044 };
51165045 try cg.store(.stack, elem_val, elem_ty, @intCast(dest_alloc.offset() + elem_size * out_idx));
51175046 }
......@@ -5252,7 +5181,7 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
52525181 }
52535182 const packed_struct = zcu.typeToPackedStruct(result_ty).?;
52545183 const field_types = packed_struct.field_types;
5255 const backing_type = Type.fromInterned(packed_struct.backingIntTypeUnordered(ip));
5184 const backing_type = Type.fromInterned(packed_struct.packed_backing_int_type);
52565185
52575186 // ensure the result is zero'd
52585187 const result = try cg.allocLocal(backing_type);
......@@ -5265,7 +5194,7 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
52655194 var current_bit: u16 = 0;
52665195 for (elements, 0..) |elem, elem_index| {
52675196 const field_ty = Type.fromInterned(field_types.get(ip)[elem_index]);
5268 if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue;
5197 if (!field_ty.hasRuntimeBits(zcu)) continue;
52695198
52705199 const shift_val: WValue = if (backing_type.bitSize(zcu) <= 32)
52715200 .{ .imm32 = current_bit }
......@@ -5338,13 +5267,13 @@ fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
53385267 const layout = union_ty.unionGetLayout(zcu);
53395268 const union_obj = zcu.typeToUnion(union_ty).?;
53405269 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[extra.field_index]);
5341 const field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index];
5270 const field_name = ip.loadEnumType(union_obj.enum_tag_type).field_names.get(ip)[extra.field_index];
53425271
53435272 const tag_int = blk: {
53445273 const tag_ty = union_ty.unionTagTypeHypothetical(zcu);
53455274 const enum_field_index = tag_ty.enumFieldIndex(field_name, zcu).?;
53465275 const tag_val = try pt.enumValueFieldIndex(tag_ty, enum_field_index);
5347 break :blk try cg.lowerConstant(tag_val, tag_ty);
5276 break :blk try cg.lowerConstant(tag_val);
53485277 };
53495278 if (layout.payload_size == 0) {
53505279 if (layout.tag_size == 0) {
......@@ -5366,7 +5295,7 @@ fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
53665295 }
53675296
53685297 if (layout.tag_size > 0) {
5369 try cg.store(result_ptr, tag_int, Type.fromInterned(union_obj.enum_tag_ty), 0);
5298 try cg.store(result_ptr, tag_int, .fromInterned(union_obj.enum_tag_type), 0);
53705299 }
53715300 } else {
53725301 try cg.store(result_ptr, payload, field_ty, 0);
......@@ -5374,7 +5303,7 @@ fn airUnionInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
53745303 try cg.store(
53755304 result_ptr,
53765305 tag_int,
5377 Type.fromInterned(union_obj.enum_tag_ty),
5306 .fromInterned(union_obj.enum_tag_type),
53785307 @intCast(layout.payload_size),
53795308 );
53805309 }
......@@ -5421,7 +5350,7 @@ fn airWasmMemoryGrow(cg: *CodeGen, inst: Air.Inst.Index) !void {
54215350
54225351fn cmpOptionals(cg: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {
54235352 const zcu = cg.pt.zcu;
5424 assert(operand_ty.hasRuntimeBitsIgnoreComptime(zcu));
5353 assert(operand_ty.hasRuntimeBits(zcu));
54255354 assert(op == .eq or op == .neq);
54265355 const payload_ty = operand_ty.optionalChild(zcu);
54275356 assert(!isByRef(payload_ty, zcu, cg.target));
......@@ -5675,7 +5604,7 @@ fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void
56755604 );
56765605
56775606 const result = result: {
5678 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
5607 if (!payload_ty.hasRuntimeBits(zcu)) {
56795608 break :result cg.reuseOperand(ty_op.operand, operand);
56805609 }
56815610
......@@ -6464,7 +6393,7 @@ fn lowerTry(
64646393 const zcu = cg.pt.zcu;
64656394
64666395 const pl_ty = err_union_ty.errorUnionPayload(zcu);
6467 const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime(zcu);
6396 const pl_has_bits = pl_ty.hasRuntimeBits(zcu);
64686397
64696398 if (!err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) {
64706399 // Block we can jump out of when error is not set
......@@ -7102,16 +7031,13 @@ fn callIntrinsic(
71027031 // Lower all arguments to the stack before we call our function
71037032 for (args, 0..) |arg, arg_i| {
71047033 assert(!(want_sret_param and arg == .stack));
7105 assert(Type.fromInterned(param_types[arg_i]).hasRuntimeBitsIgnoreComptime(zcu));
7034 assert(Type.fromInterned(param_types[arg_i]).hasRuntimeBits(zcu));
71067035 try cg.lowerArg(.{ .wasm_mvp = .{} }, Type.fromInterned(param_types[arg_i]), arg);
71077036 }
71087037
71097038 try cg.addInst(.{ .tag = .call_intrinsic, .data = .{ .intrinsic = intrinsic } });
71107039
7111 if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) {
7112 return .none;
7113 } else if (return_type.isNoReturn(zcu)) {
7114 try cg.addTag(.@"unreachable");
7040 if (!return_type.hasRuntimeBits(zcu)) {
71157041 return .none;
71167042 } else if (want_sret_param) {
71177043 return sret;
src/codegen/wasm/abi.zig+3-3
......@@ -22,7 +22,7 @@ pub const Class = union(enum) {
2222/// or returned as value within a wasm function.
2323pub fn classifyType(ty: Type, zcu: *const Zcu) Class {
2424 const ip = &zcu.intern_pool;
25 assert(ty.hasRuntimeBitsIgnoreComptime(zcu));
25 assert(ty.hasRuntimeBits(zcu));
2626 switch (ty.zigTypeTag(zcu)) {
2727 .int, .@"enum", .error_set => return .{ .direct = ty },
2828 .float => return .{ .direct = ty },
......@@ -47,7 +47,7 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class {
4747 return .indirect;
4848 }
4949 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[0]);
50 const explicit_align = struct_type.fieldAlign(ip, 0);
50 const explicit_align = struct_type.field_aligns.getOrNone(ip, 0);
5151 if (explicit_align != .none) {
5252 if (explicit_align.compareStrict(.gt, field_ty.abiAlignment(zcu)))
5353 return .indirect;
......@@ -56,7 +56,7 @@ pub fn classifyType(ty: Type, zcu: *const Zcu) Class {
5656 },
5757 .@"union" => {
5858 const union_obj = zcu.typeToUnion(ty).?;
59 if (union_obj.flagsUnordered(ip).layout == .@"packed") {
59 if (union_obj.layout == .@"packed") {
6060 return .{ .direct = ty };
6161 }
6262 const layout = ty.unionGetLayout(zcu);
src/codegen/x86_64/CodeGen.zig+80-86
......@@ -43261,7 +43261,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4326143261 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
4326243262 try ops[0].toSlicePtr(cg);
4326343263 var res: [1]Temp = undefined;
43264 if (!hack_around_sema_opv_bugs or ty_pl.ty.toType().elemType2(zcu).hasRuntimeBitsIgnoreComptime(zcu)) cg.select(&res, &.{ty_pl.ty.toType()}, &ops, comptime &.{ .{
43264 if (!hack_around_sema_opv_bugs or ty_pl.ty.toType().childType(zcu).hasRuntimeBits(zcu)) cg.select(&res, &.{ty_pl.ty.toType()}, &ops, comptime &.{ .{
4326543265 .patterns = &.{
4326643266 .{ .src = .{ .to_gpr, .simm32, .none } },
4326743267 },
......@@ -43375,7 +43375,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
4337543375 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
4337643376 try ops[0].toSlicePtr(cg);
4337743377 var res: [1]Temp = undefined;
43378 if (!hack_around_sema_opv_bugs or ty_pl.ty.toType().elemType2(zcu).hasRuntimeBitsIgnoreComptime(zcu)) cg.select(&res, &.{ty_pl.ty.toType()}, &ops, comptime &.{ .{
43378 if (!hack_around_sema_opv_bugs or ty_pl.ty.toType().childType(zcu).hasRuntimeBits(zcu)) cg.select(&res, &.{ty_pl.ty.toType()}, &ops, comptime &.{ .{
4337943379 .patterns = &.{
4338043380 .{ .src = .{ .to_gpr, .simm32, .none } },
4338143381 },
......@@ -103699,7 +103699,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103699103699 .optional_payload => {
103700103700 const ty_op = air_datas[@intFromEnum(inst)].ty_op;
103701103701 var ops = try cg.tempsFromOperands(inst, .{ty_op.operand});
103702 const pl = if (!hack_around_sema_opv_bugs or ty_op.ty.toType().hasRuntimeBitsIgnoreComptime(zcu))
103702 const pl = if (!hack_around_sema_opv_bugs or ty_op.ty.toType().hasRuntimeBits(zcu))
103703103703 try ops[0].read(ty_op.ty.toType(), .{}, cg)
103704103704 else
103705103705 try cg.tempInit(ty_op.ty.toType(), .none);
......@@ -103745,7 +103745,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103745103745 const eu_pl_ty = ty_op.ty.toType();
103746103746 const eu_pl_off: i32 = @intCast(codegen.errUnionPayloadOffset(eu_pl_ty, zcu));
103747103747 var ops = try cg.tempsFromOperands(inst, .{ty_op.operand});
103748 const pl = if (!hack_around_sema_opv_bugs or eu_pl_ty.hasRuntimeBitsIgnoreComptime(zcu))
103748 const pl = if (!hack_around_sema_opv_bugs or eu_pl_ty.hasRuntimeBits(zcu))
103749103749 try ops[0].read(eu_pl_ty, .{ .disp = eu_pl_off }, cg)
103750103750 else
103751103751 try cg.tempInit(eu_pl_ty, .none);
......@@ -103864,7 +103864,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103864103864 .@"packed" => unreachable,
103865103865 };
103866103866 var ops = try cg.tempsFromOperands(inst, .{struct_field.struct_operand});
103867 var res = if (!hack_around_sema_opv_bugs or field_ty.hasRuntimeBitsIgnoreComptime(zcu))
103867 var res = if (!hack_around_sema_opv_bugs or field_ty.hasRuntimeBits(zcu))
103868103868 try ops[0].read(field_ty, .{ .disp = field_off }, cg)
103869103869 else
103870103870 try cg.tempInit(field_ty, .none);
......@@ -103926,7 +103926,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
103926103926 .array_elem_val, .legalize_vec_elem_val => {
103927103927 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
103928103928 const array_ty = cg.typeOf(bin_op.lhs);
103929 const res_ty = array_ty.elemType2(zcu);
103929 const res_ty = array_ty.childType(zcu);
103930103930 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
103931103931 var res: [1]Temp = undefined;
103932103932 cg.select(&res, &.{res_ty}, &ops, comptime &.{ .{
......@@ -104121,11 +104121,11 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
104121104121 },
104122104122 .slice_elem_val, .ptr_elem_val => {
104123104123 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
104124 const res_ty = cg.typeOf(bin_op.lhs).elemType2(zcu);
104124 const res_ty = cg.typeOf(bin_op.lhs).indexableElem(zcu);
104125104125 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
104126104126 try ops[0].toSlicePtr(cg);
104127104127 var res: [1]Temp = undefined;
104128 if (!hack_around_sema_opv_bugs or res_ty.hasRuntimeBitsIgnoreComptime(zcu)) cg.select(&res, &.{res_ty}, &ops, comptime &.{ .{
104128 if (!hack_around_sema_opv_bugs or res_ty.hasRuntimeBits(zcu)) cg.select(&res, &.{res_ty}, &ops, comptime &.{ .{
104129104129 .dst_constraints = .{ .{ .int = .byte }, .any },
104130104130 .patterns = &.{
104131104131 .{ .src = .{ .to_gpr, .simm32, .none } },
......@@ -171422,10 +171422,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171422171422 .auto, .@"extern" => {
171423171423 for (elems, 0..) |elem_ref, field_index| {
171424171424 const elem_dies = bt.feed();
171425 if (loaded_struct.fieldIsComptime(ip, field_index)) continue;
171426 if (!hack_around_sema_opv_bugs or Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]).hasRuntimeBitsIgnoreComptime(zcu)) {
171425 if (loaded_struct.field_is_comptime_bits.get(ip, field_index)) continue;
171426 if (!hack_around_sema_opv_bugs or Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]).hasRuntimeBits(zcu)) {
171427171427 var elem = try cg.tempFromOperand(elem_ref, elem_dies);
171428 try res.write(&elem, .{ .disp = @intCast(loaded_struct.offsets.get(ip)[field_index]) }, cg);
171428 try res.write(&elem, .{ .disp = @intCast(loaded_struct.field_offsets.get(ip)[field_index]) }, cg);
171429171429 try elem.die(cg);
171430171430 try cg.resetTemps(reset_index);
171431171431 }
......@@ -171441,7 +171441,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171441171441 const elem_dies = bt.feed();
171442171442 if (tuple_type.values.get(ip)[field_index] != .none) continue;
171443171443 const field_type = Type.fromInterned(tuple_type.types.get(ip)[field_index]);
171444 if (!hack_around_sema_opv_bugs or field_type.hasRuntimeBitsIgnoreComptime(zcu)) {
171444 if (!hack_around_sema_opv_bugs or field_type.hasRuntimeBits(zcu)) {
171445171445 elem_disp = @intCast(field_type.abiAlignment(zcu).forward(elem_disp));
171446171446 var elem = try cg.tempFromOperand(elem_ref, elem_dies);
171447171447 try res.write(&elem, .{ .disp = elem_disp }, cg);
......@@ -171467,7 +171467,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
171467171467 const union_layout = union_ty.unionGetLayout(zcu);
171468171468 if (union_layout.tag_size > 0) {
171469171469 var tag_temp = try cg.tempFromValue(try pt.enumValueFieldIndex(
171470 union_ty.unionTagTypeSafety(zcu).?,
171470 union_ty.unionTagTypeRuntime(zcu).?,
171471171471 union_init.field_index,
171472171472 ));
171473171473 try res.write(&tag_temp, .{
......@@ -173756,7 +173756,7 @@ fn genLazy(cg: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
173756173756
173757173757 var data_off: i32 = 0;
173758173758 const reset_index = cg.next_temp_index;
173759 const tag_names = ip.loadEnumType(lazy_sym.ty).names;
173759 const tag_names = ip.loadEnumType(lazy_sym.ty).field_names;
173760173760 for (0..tag_names.len) |tag_index| {
173761173761 var enum_temp = try cg.tempInit(enum_ty, if (enum_ty.abiSize(zcu) <= @as(u4, switch (cg.target.cpu.arch) {
173762173762 else => unreachable,
......@@ -174334,7 +174334,7 @@ fn genUnwrapErrUnionPayloadMir(
174334174334 const payload_ty = err_union_ty.errorUnionPayload(zcu);
174335174335
174336174336 const result: MCValue = result: {
174337 if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) break :result .none;
174337 if (!payload_ty.hasRuntimeBits(zcu)) break :result .none;
174338174338
174339174339 const payload_off: u31 = @intCast(codegen.errUnionPayloadOffset(payload_ty, zcu));
174340174340 switch (err_union) {
......@@ -174450,7 +174450,7 @@ fn load(self: *CodeGen, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerE
174450174450 const pt = self.pt;
174451174451 const zcu = pt.zcu;
174452174452 const dst_ty = ptr_ty.childType(zcu);
174453 if (!dst_ty.hasRuntimeBitsIgnoreComptime(zcu)) return;
174453 if (!dst_ty.hasRuntimeBits(zcu)) return;
174454174454 switch (ptr_mcv) {
174455174455 .none,
174456174456 .unreach,
......@@ -174503,7 +174503,7 @@ fn store(
174503174503 const pt = self.pt;
174504174504 const zcu = pt.zcu;
174505174505 const src_ty = ptr_ty.childType(zcu);
174506 if (!src_ty.hasRuntimeBitsIgnoreComptime(zcu)) return;
174506 if (!src_ty.hasRuntimeBits(zcu)) return;
174507174507 switch (ptr_mcv) {
174508174508 .none,
174509174509 .unreach,
......@@ -176615,7 +176615,7 @@ fn lowerSwitchBr(
176615176615 break :condition_index condition_index;
176616176616 };
176617176617 try cg.spillEflagsIfOccupied();
176618 if (min.?.orderAgainstZero(zcu).compare(.neq)) try cg.genBinOpMir(
176618 if (Value.compareHetero(min.?, .neq, .zero_comptime_int, zcu)) try cg.genBinOpMir(
176619176619 .{ ._, .sub },
176620176620 condition_ty,
176621176621 condition_index,
......@@ -176957,7 +176957,7 @@ fn airSwitchDispatch(self: *CodeGen, inst: Air.Inst.Index) !void {
176957176957 const unsigned_condition_ty = try self.pt.intType(.unsigned, self.intInfo(condition_ty).?.bits);
176958176958 const condition_mcv = block_tracking.short;
176959176959 try self.spillEflagsIfOccupied();
176960 if (table.min.orderAgainstZero(self.pt.zcu).compare(.neq)) try self.genBinOpMir(
176960 if (Value.compareHetero(table.min, .neq, .zero_comptime_int, self.pt.zcu)) try self.genBinOpMir(
176961176961 .{ ._, .sub },
176962176962 condition_ty,
176963176963 condition_mcv,
......@@ -177054,8 +177054,7 @@ fn airBr(self: *CodeGen, inst: Air.Inst.Index) !void {
177054177054 const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
177055177055
177056177056 const block_ty = self.typeOfIndex(br.block_inst);
177057 const block_unused =
177058 !block_ty.hasRuntimeBitsIgnoreComptime(zcu) or self.liveness.isUnused(br.block_inst);
177057 const block_unused = !block_ty.hasRuntimeBits(zcu) or self.liveness.isUnused(br.block_inst);
177059177058 const block_tracking = self.inst_tracking.getPtr(br.block_inst).?;
177060177059 const block_data = self.blocks.getPtr(br.block_inst).?;
177061177060 const first_br = block_data.relocs.items.len == 0;
......@@ -177295,41 +177294,38 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void {
177295177294 }
177296177295
177297177296 const ip = &zcu.intern_pool;
177298 const aggregate = ip.indexToKey(unwrapped_asm.clobbers).aggregate;
177299 const struct_type: Type = .fromInterned(aggregate.ty);
177300 switch (aggregate.storage) {
177301 .elems => |elems| for (elems, 0..) |elem, i| switch (elem) {
177302 .bool_true => {
177303 const clobber = struct_type.structFieldName(i, zcu).toSlice(ip).?;
177304 assert(clobber.len != 0);
177305
177306 if (std.mem.eql(u8, clobber, "memory") or
177307 std.mem.eql(u8, clobber, "fpsr") or
177308 std.mem.eql(u8, clobber, "fpcr") or
177309 std.mem.eql(u8, clobber, "mxcsr") or
177310 std.mem.eql(u8, clobber, "dirflag"))
177311 {
177312 // ok, sure
177313 } else if (std.mem.eql(u8, clobber, "cc") or
177314 std.mem.eql(u8, clobber, "flags") or
177315 std.mem.eql(u8, clobber, "eflags") or
177316 std.mem.eql(u8, clobber, "rflags"))
177317 {
177318 try self.spillEflagsIfOccupied();
177319 } else {
177320 try self.register_manager.getReg(parseRegName(clobber) orelse
177321 return self.fail("invalid clobber: '{s}'", .{clobber}), null);
177322 }
177323 },
177324 .bool_false => continue,
177325 else => unreachable,
177326 },
177327 .repeated_elem => |elem| switch (elem) {
177328 .bool_true => @panic("TODO"),
177329 .bool_false => {},
177330 else => unreachable,
177331 },
177332 .bytes => @panic("TODO"),
177297 const clobbers_val: Value = .fromInterned(unwrapped_asm.clobbers);
177298 const clobbers_ty = clobbers_val.typeOf(zcu);
177299 var clobbers_bigint_buf: Value.BigIntSpace = undefined;
177300 const clobbers_bigint = clobbers_val.toBigInt(&clobbers_bigint_buf, zcu);
177301 for (0..clobbers_ty.structFieldCount(zcu)) |field_index| {
177302 assert(clobbers_ty.fieldType(field_index, zcu).toIntern() == .bool_type);
177303 const limb_bits = @bitSizeOf(std.math.big.Limb);
177304 if (field_index / limb_bits >= clobbers_bigint.limbs.len) continue; // field is false
177305 switch (@as(u1, @truncate(clobbers_bigint.limbs[field_index / limb_bits] >> @intCast(field_index % limb_bits)))) {
177306 0 => continue, // field is false
177307 1 => {}, // field is true
177308 }
177309 const clobber = clobbers_ty.structFieldName(field_index, zcu).toSlice(ip).?;
177310 assert(clobber.len != 0);
177311
177312 if (std.mem.eql(u8, clobber, "memory") or
177313 std.mem.eql(u8, clobber, "fpsr") or
177314 std.mem.eql(u8, clobber, "fpcr") or
177315 std.mem.eql(u8, clobber, "mxcsr") or
177316 std.mem.eql(u8, clobber, "dirflag"))
177317 {
177318 // ok, sure
177319 } else if (std.mem.eql(u8, clobber, "cc") or
177320 std.mem.eql(u8, clobber, "flags") or
177321 std.mem.eql(u8, clobber, "eflags") or
177322 std.mem.eql(u8, clobber, "rflags"))
177323 {
177324 try self.spillEflagsIfOccupied();
177325 } else {
177326 try self.register_manager.getReg(parseRegName(clobber) orelse
177327 return self.fail("invalid clobber: '{s}'", .{clobber}), null);
177328 }
177333177329 }
177334177330
177335177331 const Label = struct {
......@@ -180986,7 +180982,7 @@ fn resolveInst(self: *CodeGen, ref: Air.Inst.Ref) InnerError!MCValue {
180986180982 const ty = self.typeOf(ref);
180987180983
180988180984 // If the type has no codegen bits, no need to store it.
180989 if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) return .none;
180985 if (!ty.hasRuntimeBits(zcu)) return .none;
180990180986
180991180987 const mcv: MCValue = if (ref.toIndex()) |inst| mcv: {
180992180988 break :mcv self.inst_tracking.getPtr(inst).?.short;
......@@ -181105,7 +181101,7 @@ fn resolveCallingConventionValues(
181105181101 // Return values
181106181102 if (ret_ty.isNoReturn(zcu)) {
181107181103 result.return_value = .init(.unreach);
181108 } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
181104 } else if (!ret_ty.hasRuntimeBits(zcu)) {
181109181105 // TODO: is this even possible for C calling convention?
181110181106 result.return_value = .init(.none);
181111181107 } else {
......@@ -181115,7 +181111,7 @@ fn resolveCallingConventionValues(
181115181111 var ret_sse = abi.getCAbiSseReturnRegs(cc);
181116181112 var ret_x87 = abi.getCAbiX87ReturnRegs(cc);
181117181113
181118 const classes = switch (cc) {
181114 const classes: []const abi.Class = switch (cc) {
181119181115 .x86_64_sysv => std.mem.sliceTo(&abi.classifySystemV(ret_ty, zcu, cg.target, .ret), .none),
181120181116 .x86_64_win => &.{abi.classifyWindows(ret_ty, zcu, cg.target, .ret)},
181121181117 else => unreachable,
......@@ -181182,7 +181178,7 @@ fn resolveCallingConventionValues(
181182181178
181183181179 // Input params
181184181180 params: for (param_types, result.args) |ty, *arg| {
181185 assert(ty.hasRuntimeBitsIgnoreComptime(zcu));
181181 assert(ty.hasRuntimeBits(zcu));
181186181182 result.air_arg_count += 1;
181187181183 switch (cc) {
181188181184 .x86_64_sysv => {},
......@@ -181327,7 +181323,7 @@ fn resolveCallingConventionValues(
181327181323 // Return values
181328181324 result.return_value = if (ret_ty.isNoReturn(zcu))
181329181325 .init(.unreach)
181330 else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu))
181326 else if (!ret_ty.hasRuntimeBits(zcu))
181331181327 .init(.none)
181332181328 else return_value: {
181333181329 const ret_gpr = abi.getCAbiIntReturnRegs(cc);
......@@ -181357,7 +181353,7 @@ fn resolveCallingConventionValues(
181357181353
181358181354 // Input params
181359181355 for (param_types, result.args) |param_ty, *arg| {
181360 if (!param_ty.hasRuntimeBitsIgnoreComptime(zcu)) {
181356 if (!param_ty.hasRuntimeBits(zcu)) {
181361181357 arg.* = .none;
181362181358 continue;
181363181359 }
......@@ -181721,7 +181717,7 @@ fn intInfo(cg: *CodeGen, ty: Type) ?std.builtin.Type.Int {
181721181717 .one, .many, .c => .{ .signedness = .unsigned, .bits = cg.target.ptrBitWidth() },
181722181718 .slice => null,
181723181719 },
181724 .opt_type => |opt_child| return if (!Type.fromInterned(opt_child).hasRuntimeBitsIgnoreComptime(zcu))
181720 .opt_type => |opt_child| return if (!Type.fromInterned(opt_child).hasRuntimeBits(zcu))
181725181721 .{ .signedness = .unsigned, .bits = 1 }
181726181722 else switch (ip.indexToKey(opt_child)) {
181727181723 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
......@@ -181734,7 +181730,7 @@ fn intInfo(cg: *CodeGen, ty: Type) ?std.builtin.Type.Int {
181734181730 else => null,
181735181731 },
181736181732 .error_union_type => |error_union_type| return if (!Type.fromInterned(error_union_type.payload_type)
181737 .hasRuntimeBitsIgnoreComptime(zcu)) .{ .signedness = .unsigned, .bits = zcu.errorSetBits() } else null,
181733 .hasRuntimeBits(zcu)) .{ .signedness = .unsigned, .bits = zcu.errorSetBits() } else null,
181738181734 .simple_type => |simple_type| return switch (simple_type) {
181739181735 .bool => .{ .signedness = .unsigned, .bits = 1 },
181740181736 .anyerror => .{ .signedness = .unsigned, .bits = zcu.errorSetBits() },
......@@ -181767,14 +181763,17 @@ fn intInfo(cg: *CodeGen, ty: Type) ?std.builtin.Type.Int {
181767181763 const loaded_struct = ip.loadStructType(ty_index);
181768181764 switch (loaded_struct.layout) {
181769181765 .auto, .@"extern" => return null,
181770 .@"packed" => ty_index = loaded_struct.backingIntTypeUnordered(ip),
181766 .@"packed" => ty_index = loaded_struct.packed_backing_int_type,
181771181767 }
181772181768 },
181773 .union_type => return switch (ip.loadUnionType(ty_index).flagsUnordered(ip).layout) {
181774 .auto, .@"extern" => null,
181775 .@"packed" => .{ .signedness = .unsigned, .bits = @intCast(ty.bitSize(zcu)) },
181769 .union_type => {
181770 const loaded_union = ip.loadUnionType(ty_index);
181771 switch (loaded_union.layout) {
181772 .auto, .@"extern" => return null,
181773 .@"packed" => ty_index = loaded_union.packed_backing_int_type,
181774 }
181776181775 },
181777 .enum_type => ty_index = ip.loadEnumType(ty_index).tag_ty,
181776 .enum_type => ty_index = ip.loadEnumType(ty_index).int_tag_type,
181778181777 .error_set_type, .inferred_error_set_type => return .{ .signedness = .unsigned, .bits = zcu.errorSetBits() },
181779181778 else => return null,
181780181779 };
......@@ -187919,7 +187918,6 @@ const Select = struct {
187919187918 unsigned_int: Memory.Size,
187920187919 elem_size_is: u8,
187921187920 po2_elem_size,
187922 elem_int: Memory.Size,
187923187921
187924187922 const OfIsSizes = struct { of: Memory.Size, is: Memory.Size };
187925187923
......@@ -188178,12 +188176,8 @@ const Select = struct {
188178188176 .signed => false,
188179188177 .unsigned => size.bitSize(cg.target) >= int_info.bits,
188180188178 } else false,
188181 .elem_size_is => |size| size == ty.elemType2(zcu).abiSize(zcu),
188182 .po2_elem_size => std.math.isPowerOfTwo(ty.elemType2(zcu).abiSize(zcu)),
188183 .elem_int => |size| if (cg.intInfo(ty.elemType2(zcu))) |elem_int_info|
188184 size.bitSize(cg.target) >= elem_int_info.bits
188185 else
188186 false,
188179 .elem_size_is => |size| size == ty.indexableElem(zcu).abiSize(zcu),
188180 .po2_elem_size => std.math.isPowerOfTwo(ty.indexableElem(zcu).abiSize(zcu)),
188187188181 };
188188188182 }
188189188183 };
......@@ -189918,20 +189912,20 @@ const Select = struct {
189918189912 .dst0_size => @intCast(Select.Operand.Ref.dst0.typeOf(s).abiSize(s.cg.pt.zcu)),
189919189913 .delta_size => @intCast(@as(SignedImm, @intCast(op.flags.base.ref.typeOf(s).abiSize(s.cg.pt.zcu))) -
189920189914 @as(SignedImm, @intCast(op.flags.index.ref.typeOf(s).abiSize(s.cg.pt.zcu)))),
189921 .delta_elem_size => @intCast(@as(SignedImm, @intCast(op.flags.base.ref.typeOf(s).elemType2(s.cg.pt.zcu).abiSize(s.cg.pt.zcu))) -
189922 @as(SignedImm, @intCast(op.flags.index.ref.typeOf(s).elemType2(s.cg.pt.zcu).abiSize(s.cg.pt.zcu)))),
189915 .delta_elem_size => @intCast(@as(SignedImm, @intCast(op.flags.base.ref.typeOf(s).scalarType(s.cg.pt.zcu).abiSize(s.cg.pt.zcu))) -
189916 @as(SignedImm, @intCast(op.flags.index.ref.typeOf(s).scalarType(s.cg.pt.zcu).abiSize(s.cg.pt.zcu)))),
189923189917 .unaligned_size => @intCast(s.cg.unalignedSize(op.flags.base.ref.typeOf(s))),
189924189918 .unaligned_size_add_elem_size => {
189925189919 const ty = op.flags.base.ref.typeOf(s);
189926 break :lhs @intCast(s.cg.unalignedSize(ty) + ty.elemType2(s.cg.pt.zcu).abiSize(s.cg.pt.zcu));
189920 break :lhs @intCast(s.cg.unalignedSize(ty) + ty.scalarType(s.cg.pt.zcu).abiSize(s.cg.pt.zcu));
189927189921 },
189928189922 .unaligned_size_sub_elem_size => {
189929189923 const ty = op.flags.base.ref.typeOf(s);
189930 break :lhs @intCast(s.cg.unalignedSize(ty) - ty.elemType2(s.cg.pt.zcu).abiSize(s.cg.pt.zcu));
189924 break :lhs @intCast(s.cg.unalignedSize(ty) - ty.scalarType(s.cg.pt.zcu).abiSize(s.cg.pt.zcu));
189931189925 },
189932189926 .unaligned_size_sub_2_elem_size => {
189933189927 const ty = op.flags.base.ref.typeOf(s);
189934 break :lhs @intCast(s.cg.unalignedSize(ty) - ty.elemType2(s.cg.pt.zcu).abiSize(s.cg.pt.zcu) * 2);
189928 break :lhs @intCast(s.cg.unalignedSize(ty) - ty.scalarType(s.cg.pt.zcu).abiSize(s.cg.pt.zcu) * 2);
189935189929 },
189936189930 .bit_size => @intCast(s.cg.nonBoolScalarBitSize(op.flags.base.ref.typeOf(s))),
189937189931 .src0_bit_size => @intCast(s.cg.nonBoolScalarBitSize(Select.Operand.Ref.src0.typeOf(s))),
......@@ -189944,10 +189938,10 @@ const Select = struct {
189944189938 op.flags.base.ref.typeOf(s).scalarType(s.cg.pt.zcu).abiSize(s.cg.pt.zcu),
189945189939 @divExact(op.flags.base.size.bitSize(s.cg.target), 8),
189946189940 )),
189947 .elem_size => @intCast(op.flags.base.ref.typeOf(s).elemType2(s.cg.pt.zcu).abiSize(s.cg.pt.zcu)),
189948 .src0_elem_size => @intCast(Select.Operand.Ref.src0.typeOf(s).elemType2(s.cg.pt.zcu).abiSize(s.cg.pt.zcu)),
189949 .dst0_elem_size => @intCast(Select.Operand.Ref.dst0.typeOf(s).elemType2(s.cg.pt.zcu).abiSize(s.cg.pt.zcu)),
189950 .src0_elem_size_mul_src1 => @intCast(Select.Operand.Ref.src0.typeOf(s).elemType2(s.cg.pt.zcu).abiSize(s.cg.pt.zcu) *
189941 .elem_size => @intCast(op.flags.base.ref.typeOf(s).indexableElem(s.cg.pt.zcu).abiSize(s.cg.pt.zcu)),
189942 .src0_elem_size => @intCast(Select.Operand.Ref.src0.typeOf(s).indexableElem(s.cg.pt.zcu).abiSize(s.cg.pt.zcu)),
189943 .dst0_elem_size => @intCast(Select.Operand.Ref.dst0.typeOf(s).indexableElem(s.cg.pt.zcu).abiSize(s.cg.pt.zcu)),
189944 .src0_elem_size_mul_src1 => @intCast(Select.Operand.Ref.src0.typeOf(s).indexableElem(s.cg.pt.zcu).abiSize(s.cg.pt.zcu) *
189951189945 Select.Operand.Ref.src1.valueOf(s).immediate),
189952189946 .vector_index => switch (op.flags.base.ref.typeOf(s).ptrInfo(s.cg.pt.zcu).flags.vector_index) {
189953189947 .none => unreachable,
......@@ -189956,7 +189950,7 @@ const Select = struct {
189956189950 .src1 => @intCast(Select.Operand.Ref.src1.valueOf(s).immediate),
189957189951 .src1_sub_bit_size => @as(SignedImm, @intCast(Select.Operand.Ref.src1.valueOf(s).immediate)) -
189958189952 @as(SignedImm, @intCast(s.cg.nonBoolScalarBitSize(op.flags.base.ref.typeOf(s)))),
189959 .log2_src0_elem_size => @intCast(std.math.log2(Select.Operand.Ref.src0.typeOf(s).elemType2(s.cg.pt.zcu).abiSize(s.cg.pt.zcu))),
189953 .log2_src0_elem_size => @intCast(std.math.log2(Select.Operand.Ref.src0.typeOf(s).indexableElem(s.cg.pt.zcu).abiSize(s.cg.pt.zcu))),
189960189954 .elem_mask => @as(u8, std.math.maxInt(u8)) >> @intCast(
189961189955 8 - ((s.cg.unalignedSize(op.flags.base.ref.typeOf(s)) - 1) %
189962189956 @divExact(op.flags.base.size.bitSize(s.cg.target), 8) + 1 >>
src/codegen/x86_64/abi.zig+6-6
......@@ -339,7 +339,7 @@ fn classifySystemVStruct(
339339 var field_it = loaded_struct.iterateRuntimeOrder(ip);
340340 while (field_it.next()) |field_index| {
341341 const field_ty = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
342 const field_align = loaded_struct.fieldAlign(ip, field_index);
342 const field_align = loaded_struct.field_aligns.getOrNone(ip, field_index);
343343 byte_offset = std.mem.alignForward(
344344 u64,
345345 byte_offset,
......@@ -355,7 +355,7 @@ fn classifySystemVStruct(
355355 .@"packed" => {},
356356 }
357357 } else if (zcu.typeToUnion(field_ty)) |field_loaded_union| {
358 switch (field_loaded_union.flagsUnordered(ip).layout) {
358 switch (field_loaded_union.layout) {
359359 .auto => unreachable,
360360 .@"extern" => {
361361 byte_offset = classifySystemVUnion(result, byte_offset, field_loaded_union, zcu, target);
......@@ -369,11 +369,11 @@ fn classifySystemVStruct(
369369 result_class.* = result_class.combineSystemV(field_class);
370370 byte_offset += field_ty.abiSize(zcu);
371371 }
372 const final_byte_offset = starting_byte_offset + loaded_struct.sizeUnordered(ip);
372 const final_byte_offset = starting_byte_offset + loaded_struct.size;
373373 std.debug.assert(final_byte_offset == std.mem.alignForward(
374374 u64,
375375 byte_offset,
376 loaded_struct.flagsUnordered(ip).alignment.toByteUnits().?,
376 loaded_struct.alignment.toByteUnits().?,
377377 ));
378378 return final_byte_offset;
379379}
......@@ -398,7 +398,7 @@ fn classifySystemVUnion(
398398 .@"packed" => {},
399399 }
400400 } else if (zcu.typeToUnion(field_ty)) |field_loaded_union| {
401 switch (field_loaded_union.flagsUnordered(ip).layout) {
401 switch (field_loaded_union.layout) {
402402 .auto => unreachable,
403403 .@"extern" => {
404404 _ = classifySystemVUnion(result, starting_byte_offset, field_loaded_union, zcu, target);
......@@ -411,7 +411,7 @@ fn classifySystemVUnion(
411411 for (result[@intCast(starting_byte_offset / 8)..][0..field_classes.len], field_classes) |*result_class, field_class|
412412 result_class.* = result_class.combineSystemV(field_class);
413413 }
414 return starting_byte_offset + loaded_union.sizeUnordered(ip);
414 return starting_byte_offset + loaded_union.size;
415415}
416416
417417pub const zigcc = struct {
src/link.zig+40-13
......@@ -29,6 +29,7 @@ const codegen = @import("codegen.zig");
2929pub const aarch64 = @import("link/aarch64.zig");
3030pub const LdScript = @import("link/LdScript.zig");
3131pub const Queue = @import("link/Queue.zig");
32pub const ConstPool = @import("link/ConstPool.zig");
3233
3334pub const Diags = struct {
3435 /// Stored here so that function definitions can distinguish between
......@@ -798,14 +799,27 @@ pub const File = struct {
798799 };
799800
800801 /// Never called when LLVM is codegenning the ZCU.
801 fn updateContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index) UpdateContainerTypeError!void {
802 fn updateContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index, success: bool) UpdateContainerTypeError!void {
803 assert(base.comp.zcu.?.llvm_object == null);
804 switch (base.tag) {
805 .lld => unreachable,
806 else => {},
807 inline .elf, .c => |tag| {
808 dev.check(tag.devFeature());
809 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateContainerType(pt, ty, success);
810 },
811 }
812 }
813
814 /// Never called when LLVM is codegenning the ZCU.
815 fn clearContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index) UpdateContainerTypeError!void {
802816 assert(base.comp.zcu.?.llvm_object == null);
803817 switch (base.tag) {
804818 .lld => unreachable,
805819 else => {},
806820 inline .elf => |tag| {
807821 dev.check(tag.devFeature());
808 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateContainerType(pt, ty);
822 return @as(*tag.Type(), @fieldParentPtr("base", base)).clearContainerType(pt, ty);
809823 },
810824 }
811825 }
......@@ -1375,8 +1389,14 @@ pub const ZcuTask = union(enum) {
13751389 link_nav: InternPool.Nav.Index,
13761390 /// Write the machine code for a function to the output file.
13771391 link_func: Zcu.CodegenTaskPool.Index,
1378 link_type: InternPool.Index,
1379 update_line_number: InternPool.TrackedInst.Index,
1392 /// This struct/union/enum type has finished type resolution (successfully or otherwise), so the
1393 /// linker can now lower debug information for this type (and any structural types which depend
1394 /// on it, such as `?T`, `struct { T }`, `[2]T`, etc).
1395 debug_update_container_type: struct {
1396 ty: InternPool.Index,
1397 success: bool,
1398 },
1399 debug_update_line_number: InternPool.TrackedInst.Index,
13801400};
13811401
13821402pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void {
......@@ -1537,7 +1557,10 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void
15371557 .link_func => |codegen_task| nav: {
15381558 timer.pause(io);
15391559 const func, var mir = codegen_task.wait(&zcu.codegen_task_pool, io) catch |err| switch (err) {
1540 error.Canceled, error.AlreadyReported => return,
1560 error.Canceled, error.AlreadyReported => {
1561 comp.link_prog_node.completeOne();
1562 return;
1563 },
15411564 };
15421565 defer mir.deinit(zcu);
15431566 timer.@"resume"(io);
......@@ -1563,21 +1586,25 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void
15631586 }
15641587 break :nav ip.indexToKey(func).func.owner_nav;
15651588 },
1566 .link_type => |ty| nav: {
1567 const name = Type.fromInterned(ty).containerTypeName(ip).toSlice(ip);
1568 const nav_prog_node = comp.link_prog_node.start(name, 0);
1569 defer nav_prog_node.end();
1570 if (zcu.llvm_object == null) {
1589 .debug_update_container_type => |container_update| nav: {
1590 const name = Type.fromInterned(container_update.ty).containerTypeName(ip).toSlice(ip);
1591 const ty_prog_node = comp.link_prog_node.start(name, 0);
1592 defer ty_prog_node.end();
1593 if (zcu.llvm_object) |llvm_object| {
1594 llvm_object.updateContainerType(pt, container_update.ty, container_update.success) catch |err| switch (err) {
1595 error.OutOfMemory => diags.setAllocFailure(),
1596 };
1597 } else {
15711598 if (comp.bin_file) |lf| {
1572 lf.updateContainerType(pt, ty) catch |err| switch (err) {
1599 lf.updateContainerType(pt, container_update.ty, container_update.success) catch |err| switch (err) {
15731600 error.OutOfMemory => diags.setAllocFailure(),
1574 error.TypeFailureReported => assert(zcu.failed_types.contains(ty)),
1601 error.TypeFailureReported => assert(zcu.failed_types.contains(container_update.ty)),
15751602 };
15761603 }
15771604 }
15781605 break :nav null;
15791606 },
1580 .update_line_number => |ti| nav: {
1607 .debug_update_line_number => |ti| nav: {
15811608 const nav_prog_node = comp.link_prog_node.start("Update line number", 0);
15821609 defer nav_prog_node.end();
15831610 if (pt.zcu.llvm_object == null) {
src/link/C.zig+1272-627
......@@ -1,3 +1,9 @@
1/// Unlike other linker implementations, `link.C` does not attempt to incrementally link its output,
2/// because C has many language rules which make that impractical. Instead, we individually generate
3/// each declaration (NAV), and the output is stitched together (alongside types and UAVs) in an
4/// appropriate order in `flush`.
5const C = @This();
6
17const std = @import("std");
28const mem = std.mem;
39const assert = std.debug.assert;
......@@ -5,7 +11,6 @@ const Allocator = std.mem.Allocator;
511const fs = std.fs;
612const Path = std.Build.Cache.Path;
713
8const C = @This();
914const build_options = @import("build_options");
1015const Zcu = @import("../Zcu.zig");
1116const Module = @import("../Package/Module.zig");
......@@ -19,40 +24,45 @@ const Type = @import("../Type.zig");
1924const Value = @import("../Value.zig");
2025const AnyMir = @import("../codegen.zig").AnyMir;
2126
22pub const zig_h = "#include \"zig.h\"\n";
23
2427base: link.File,
25/// This linker backend does not try to incrementally link output C source code.
26/// Instead, it tracks all declarations in this table, and iterates over it
27/// in the flush function, stitching pre-rendered pieces of C code together.
28navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, AvBlock),
29/// All the string bytes of rendered C code, all squished into one array.
30/// While in progress, a separate buffer is used, and then when finished, the
31/// buffer is copied into this one.
28
29/// All the string bytes of rendered C code, all squished into one array. `String` is used to refer
30/// to specific slices of this array, used for the rendered C code of an individual UAV/NAV/type.
31///
32/// During code generation for functions, a separate buffer is used, and the contents of that buffer
33/// are copied into `string_bytes` when the function is emitted by `updateFunc`.
3234string_bytes: std.ArrayList(u8),
33/// Tracks all the anonymous decls that are used by all the decls so they can
34/// be rendered during flush().
35uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, AvBlock),
36/// Sparse set of uavs that are overaligned. Underaligned anon decls are
37/// lowered the same as ABI-aligned anon decls. The keys here are a subset of
38/// the keys of `uavs`.
39aligned_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
40
41exported_navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, ExportedBlock),
42exported_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, ExportedBlock),
43
44/// Optimization, `updateDecl` reuses this buffer rather than creating a new
45/// one with every call.
46fwd_decl_buf: []u8,
47/// Optimization, `updateDecl` reuses this buffer rather than creating a new
48/// one with every call.
49code_header_buf: []u8,
50/// Optimization, `updateDecl` reuses this buffer rather than creating a new
51/// one with every call.
52code_buf: []u8,
53/// Optimization, `flush` reuses this buffer rather than creating a new
54/// one with every call.
55scratch_buf: []u32,
35
36/// Like with `string_bytes`, we concatenate all type dependencies into one array, and slice into it
37/// for specific groups of dependencies. These values are indices into `type_pool`, and thus also
38/// into `types`. We store these instead of `InternPool.Index` because it lets us avoid some hash
39/// map lookups in `flush`.
40type_dependencies: std.ArrayList(link.ConstPool.Index),
41/// For storing dependencies on "aligned" versions of types, we must associate each type with a
42/// bitmask of required alignments. As with `type_dependencies`, we concatenate all such masks into
43/// one array.
44align_dependency_masks: std.ArrayList(u64),
45
46/// All NAVs, regardless of whether they are functions or simple constants, are put in this map.
47navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, RenderedDecl),
48/// All UAVs which may be referenced are in this map. The UAV alignment is not included in the
49/// rendered C code stored here, because we don't know the alignment a UAV needs until `flush`.
50uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, RenderedDecl),
51/// Contains all types which are needed by some other rendered code. Does not contain any constants
52/// other than types.
53type_pool: link.ConstPool,
54/// Indices are `link.ConstPool.Index` from `type_pool`. Contains rendered C code for every type
55/// which may be referenced. Logic in `flush` will perform the appropriate topological sort to emit
56/// these type definitions in an order which C allows.
57types: std.ArrayList(RenderedType),
58
59/// The set of big int types required by *any* generated code so far. These are always safe to emit,
60/// so they do not participate in the dependency graph traversal in `flush`. Therefore, redundant
61/// big-int types may be emitted under incremental compilation.
62bigint_types: std.AutoArrayHashMapUnmanaged(codegen.CType.BigInt, void),
63
64exported_navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, String),
65exported_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, String),
5666
5767/// A reference into `string_bytes`.
5868const String = extern struct {
......@@ -64,50 +74,320 @@ const String = extern struct {
6474 .len = 0,
6575 };
6676
67 fn concat(lhs: String, rhs: String) String {
68 assert(lhs.start + lhs.len == rhs.start);
77 fn get(s: String, c: *C) []const u8 {
78 return c.string_bytes.items[s.start..][0..s.len];
79 }
80};
81
82const CTypeDependencies = struct {
83 len: u32,
84 errunion_len: u32,
85 fwd_len: u32,
86 errunion_fwd_len: u32,
87 aligned_fwd_len: u32,
88
89 /// Index into `C.type_dependencies`. Starting at this index are:
90 /// * `len` dependencies on complete types
91 /// * `errunion_len` dependencies on complete error union types
92 /// * `fwd_len` dependencies on forward-declared types
93 /// * `errunion_fwd_len` dependencies on forward-declared error union types
94 /// * `aligned_fwd_len` dependencies on aligned types
95 type_start: u32,
96 /// Index into `C.align_dependency_masks`. Starting at this index are `aligned_type_fwd_len`
97 /// items containing the bitmasks for each aligned type (in `C.type_dependencies`).
98 align_mask_start: u32,
99
100 const Resolved = struct {
101 type: []const link.ConstPool.Index,
102 errunion_type: []const link.ConstPool.Index,
103 type_fwd: []const link.ConstPool.Index,
104 errunion_type_fwd: []const link.ConstPool.Index,
105 aligned_type_fwd: []const link.ConstPool.Index,
106 aligned_type_masks: []const u64,
107 };
108
109 fn get(td: *const CTypeDependencies, c: *const C) Resolved {
110 const types_overlong = c.type_dependencies.items[td.type_start..];
69111 return .{
70 .start = lhs.start,
71 .len = lhs.len + rhs.len,
112 .type = types_overlong[0..td.len],
113 .errunion_type = types_overlong[td.len..][0..td.errunion_len],
114 .type_fwd = types_overlong[td.len + td.errunion_len ..][0..td.fwd_len],
115 .errunion_type_fwd = types_overlong[td.len + td.errunion_len + td.fwd_len ..][0..td.errunion_fwd_len],
116 .aligned_type_fwd = types_overlong[td.len + td.errunion_len + td.fwd_len + td.errunion_fwd_len ..][0..td.aligned_fwd_len],
117 .aligned_type_masks = c.align_dependency_masks.items[td.align_mask_start..][0..td.aligned_fwd_len],
72118 };
73119 }
120
121 const empty: CTypeDependencies = .{
122 .len = 0,
123 .errunion_len = 0,
124 .fwd_len = 0,
125 .errunion_fwd_len = 0,
126 .aligned_fwd_len = 0,
127 .type_start = 0,
128 .align_mask_start = 0,
129 };
74130};
75131
76/// Per-declaration data.
77pub const AvBlock = struct {
78 fwd_decl: String = .empty,
79 code: String = .empty,
80 /// Each `Decl` stores a set of used `CType`s. In `flush()`, we iterate
81 /// over each `Decl` and generate the definition for each used `CType` once.
82 ctype_pool: codegen.CType.Pool = .empty,
83 /// May contain string references to ctype_pool
84 lazy_fns: codegen.LazyFnMap = .{},
85
86 fn deinit(ab: *AvBlock, gpa: Allocator) void {
87 ab.lazy_fns.deinit(gpa);
88 ab.ctype_pool.deinit(gpa);
89 ab.* = undefined;
132const RenderedDecl = struct {
133 fwd_decl: String,
134 code: String,
135 ctype_deps: CTypeDependencies,
136 need_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
137 need_tag_name_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
138 need_never_tail_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void),
139 need_never_inline_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void),
140
141 const init: RenderedDecl = .{
142 .fwd_decl = .empty,
143 .code = .empty,
144 .ctype_deps = .empty,
145 .need_uavs = .empty,
146 .need_tag_name_funcs = .empty,
147 .need_never_tail_funcs = .empty,
148 .need_never_inline_funcs = .empty,
149 };
150
151 fn deinit(rd: *RenderedDecl, gpa: Allocator) void {
152 rd.need_uavs.deinit(gpa);
153 rd.need_tag_name_funcs.deinit(gpa);
154 rd.need_never_tail_funcs.deinit(gpa);
155 rd.need_never_inline_funcs.deinit(gpa);
156 rd.* = undefined;
157 }
158
159 /// We are about to re-render this declaration, but we want to reuse the existing buffers, so
160 /// call `clearRetainCapacity` on the containers. Sets `fwd_decl` and `code` to `undefined`,
161 /// because we shouldn't be using the old values any longer.
162 fn clearRetainingCapacity(rd: *RenderedDecl) void {
163 rd.fwd_decl = undefined;
164 rd.code = undefined;
165 rd.need_uavs.clearRetainingCapacity();
166 rd.need_tag_name_funcs.clearRetainingCapacity();
167 rd.need_never_tail_funcs.clearRetainingCapacity();
168 rd.need_never_inline_funcs.clearRetainingCapacity();
90169 }
91170};
92171
93/// Per-exported-symbol data.
94pub const ExportedBlock = struct {
95 fwd_decl: String = .empty,
172const RenderedType = struct {
173 /// If this type lowers to an aggregate, this is a forward declaration of its struct/union tag.
174 /// Otherwise, this is `.empty`.
175 ///
176 /// Populated immediately and never changes.
177 fwd_decl: String,
178
179 /// A forward declaration of an error union type with this type as its *payload*.
180 ///
181 /// Populated immediately and never changes.
182 errunion_fwd_decl: String,
183
184 /// If this type lowers to an aggregate, this is the struct/union definition.
185 /// If this type lowers to a typedef, this is that typedef.
186 /// Otherwise, this is `.empty`.
187 definition: String,
188 /// The `struct` definition for an error union type with this type as its *payload*.
189 ///
190 /// This string is empty iff the payload type does not have a resolved layout. If the layout is
191 /// resolved, the error union struct is defined, even if the payload type lacks runtime bits.
192 errunion_definition: String,
193
194 /// Dependencies which must be satisfied before emitting the name of this type. As such, they
195 /// must be satisfied before emitting `errunion_definition` or any aligned typedef.
196 ///
197 /// Populated immediately and never changes.
198 deps: CTypeDependencies,
199
200 /// Dependencies which must be satisfied before emitting `definition`.
201 definition_deps: CTypeDependencies,
96202};
97203
98pub fn getString(this: C, s: String) []const u8 {
99 return this.string_bytes.items[s.start..][0..s.len];
204/// Only called by `link.ConstPool` due to `c.type_pool`, so `val` is always a type.
205pub fn addConst(
206 c: *C,
207 pt: Zcu.PerThread,
208 pool_index: link.ConstPool.Index,
209 val: InternPool.Index,
210) Allocator.Error!void {
211 const zcu = pt.zcu;
212 const gpa = zcu.comp.gpa;
213 assert(zcu.intern_pool.typeOf(val) == .type_type);
214 assert(@intFromEnum(pool_index) == c.types.items.len);
215
216 const ty: Type = .fromInterned(val);
217
218 const fwd_decl: String = fwd_decl: {
219 var aw: std.Io.Writer.Allocating = .fromArrayList(gpa, &c.string_bytes);
220 defer c.string_bytes = aw.toArrayList();
221 const start = aw.written().len;
222 codegen.CType.render_defs.fwdDecl(ty, &aw.writer, zcu) catch |err| switch (err) {
223 error.WriteFailed => return error.OutOfMemory,
224 };
225 break :fwd_decl .{
226 .start = @intCast(start),
227 .len = @intCast(aw.written().len - start),
228 };
229 };
230
231 const errunion_fwd_decl: String = errunion_fwd_decl: {
232 var aw: std.Io.Writer.Allocating = .fromArrayList(gpa, &c.string_bytes);
233 defer c.string_bytes = aw.toArrayList();
234 const start = aw.written().len;
235 codegen.CType.render_defs.errunionFwdDecl(ty, &aw.writer, zcu) catch |err| switch (err) {
236 error.WriteFailed => return error.OutOfMemory,
237 };
238 break :errunion_fwd_decl .{
239 .start = @intCast(start),
240 .len = @intCast(aw.written().len - start),
241 };
242 };
243
244 try c.types.append(gpa, .{
245 .fwd_decl = fwd_decl,
246 .errunion_fwd_decl = errunion_fwd_decl,
247 // This field will be populated just below.
248 .deps = undefined,
249 // The remaining fields will be populated later by either `updateConstIncomplete` or
250 // `updateConstComplete` (it is guaranteed that at least one will be called).
251 .definition = undefined,
252 .errunion_definition = undefined,
253 .definition_deps = undefined,
254 });
255
256 {
257 // Find the dependencies required to just render the type `ty`.
258 var arena: std.heap.ArenaAllocator = .init(gpa);
259 defer arena.deinit();
260 var deps: codegen.CType.Dependencies = .empty;
261 defer deps.deinit(gpa);
262 _ = try codegen.CType.lower(ty, &deps, arena.allocator(), zcu);
263 // This call may add more items to `c.types`.
264 const type_deps = try c.addCTypeDependencies(pt, &deps);
265 c.types.items[@intFromEnum(pool_index)].deps = type_deps;
266 }
100267}
101268
102pub fn addString(this: *C, s: []const u8) Allocator.Error!String {
103 const comp = this.base.comp;
104 const gpa = comp.gpa;
105 try this.string_bytes.appendSlice(gpa, s);
106 return .{
107 .start = @intCast(this.string_bytes.items.len - s.len),
108 .len = @intCast(s.len),
269/// Only called by `link.ConstPool` due to `c.type_pool`, so `val` is always a type.
270pub fn updateConstIncomplete(
271 c: *C,
272 pt: Zcu.PerThread,
273 index: link.ConstPool.Index,
274 val: InternPool.Index,
275) Allocator.Error!void {
276 const zcu = pt.zcu;
277 const gpa = zcu.comp.gpa;
278
279 assert(zcu.intern_pool.typeOf(val) == .type_type);
280 const ty: Type = .fromInterned(val);
281
282 const rendered: *RenderedType = &c.types.items[@intFromEnum(index)];
283
284 rendered.errunion_definition = .empty;
285 rendered.definition_deps = .empty;
286 rendered.definition = definition: {
287 if (rendered.fwd_decl.len != 0) {
288 // This is a struct or union type. We will never complete it, but we must forward
289 // declare it to ensure that its first usage does not appear in a different scope.
290 break :definition rendered.fwd_decl;
291 }
292 // Otherwise, we might need to `typedef` to `void`.
293 var aw: std.Io.Writer.Allocating = .fromArrayList(gpa, &c.string_bytes);
294 defer c.string_bytes = aw.toArrayList();
295 const start = aw.written().len;
296 codegen.CType.render_defs.defineIncomplete(ty, &aw.writer, pt) catch |err| switch (err) {
297 error.WriteFailed => return error.OutOfMemory,
298 };
299 break :definition .{
300 .start = @intCast(start),
301 .len = @intCast(aw.written().len - start),
302 };
109303 };
110304}
305/// Only called by `link.ConstPool` due to `c.type_pool`, so `val` is always a type.
306pub fn updateConst(
307 c: *C,
308 pt: Zcu.PerThread,
309 index: link.ConstPool.Index,
310 val: InternPool.Index,
311) Allocator.Error!void {
312 const zcu = pt.zcu;
313 const gpa = zcu.comp.gpa;
314
315 assert(zcu.intern_pool.typeOf(val) == .type_type);
316 const ty: Type = .fromInterned(val);
317
318 const rendered: *RenderedType = &c.types.items[@intFromEnum(index)];
319
320 var arena: std.heap.ArenaAllocator = .init(gpa);
321 defer arena.deinit();
322
323 var deps: codegen.CType.Dependencies = .empty;
324 defer deps.deinit(gpa);
325
326 {
327 var aw: std.Io.Writer.Allocating = .fromArrayList(gpa, &c.string_bytes);
328 defer c.string_bytes = aw.toArrayList();
329 const start = aw.written().len;
330 codegen.CType.render_defs.errunionDefineComplete(
331 ty,
332 &deps,
333 arena.allocator(),
334 &aw.writer,
335 pt,
336 ) catch |err| switch (err) {
337 error.WriteFailed => return error.OutOfMemory,
338 error.OutOfMemory => |e| return e,
339 };
340 rendered.errunion_definition = .{
341 .start = @intCast(start),
342 .len = @intCast(aw.written().len - start),
343 };
344 }
345
346 deps.clearRetainingCapacity();
347
348 {
349 var aw: std.Io.Writer.Allocating = .fromArrayList(gpa, &c.string_bytes);
350 defer c.string_bytes = aw.toArrayList();
351 const start = aw.written().len;
352 codegen.CType.render_defs.defineComplete(
353 ty,
354 &deps,
355 arena.allocator(),
356 &aw.writer,
357 pt,
358 ) catch |err| switch (err) {
359 error.WriteFailed => return error.OutOfMemory,
360 error.OutOfMemory => |e| return e,
361 };
362 // Remove dependency on a forward declaration of ourselves; we're defining this type so that
363 // forward declaration obviously exists!
364 _ = deps.type_fwd.swapRemove(ty.toIntern());
365 rendered.definition = .{
366 .start = @intCast(start),
367 .len = @intCast(aw.written().len - start),
368 };
369 }
370
371 {
372 // This call invalidates `rendered`.
373 const definition_deps = try c.addCTypeDependencies(pt, &deps);
374 c.types.items[@intFromEnum(index)].definition_deps = definition_deps;
375 }
376}
377
378fn addString(c: *C, vec: []const []const u8) Allocator.Error!String {
379 const gpa = c.base.comp.gpa;
380
381 var len: u32 = 0;
382 for (vec) |s| len += @intCast(s.len);
383 try c.string_bytes.ensureUnusedCapacity(gpa, len);
384
385 const start: u32 = @intCast(c.string_bytes.items.len);
386 for (vec) |s| c.string_bytes.appendSliceAssumeCapacity(s);
387 assert(c.string_bytes.items.len == start + len);
388
389 return .{ .start = start, .len = len };
390}
111391
112392pub fn open(
113393 arena: Allocator,
......@@ -156,267 +436,622 @@ pub fn createEmpty(
156436 .file = file,
157437 .build_id = options.build_id,
158438 },
159 .navs = .empty,
160439 .string_bytes = .empty,
440 .type_dependencies = .empty,
441 .align_dependency_masks = .empty,
442 .navs = .empty,
161443 .uavs = .empty,
162 .aligned_uavs = .empty,
444 .type_pool = .empty,
445 .types = .empty,
446 .bigint_types = .empty,
163447 .exported_navs = .empty,
164448 .exported_uavs = .empty,
165 .fwd_decl_buf = &.{},
166 .code_header_buf = &.{},
167 .code_buf = &.{},
168 .scratch_buf = &.{},
169449 };
170450
171451 return c_file;
172452}
173453
174pub fn deinit(self: *C) void {
175 const gpa = self.base.comp.gpa;
176
177 for (self.navs.values()) |*db| {
178 db.deinit(gpa);
179 }
180 self.navs.deinit(gpa);
181
182 for (self.uavs.values()) |*db| {
183 db.deinit(gpa);
184 }
185 self.uavs.deinit(gpa);
186 self.aligned_uavs.deinit(gpa);
454pub fn deinit(c: *C) void {
455 const gpa = c.base.comp.gpa;
187456
188 self.exported_navs.deinit(gpa);
189 self.exported_uavs.deinit(gpa);
457 for (c.navs.values()) |*r| r.deinit(gpa);
458 for (c.uavs.values()) |*r| r.deinit(gpa);
459
460 c.string_bytes.deinit(gpa);
461 c.type_dependencies.deinit(gpa);
462 c.align_dependency_masks.deinit(gpa);
463 c.navs.deinit(gpa);
464 c.uavs.deinit(gpa);
465 c.type_pool.deinit(gpa);
466 c.types.deinit(gpa);
467 c.bigint_types.deinit(gpa);
468 c.exported_navs.deinit(gpa);
469 c.exported_uavs.deinit(gpa);
470}
190471
191 self.string_bytes.deinit(gpa);
192 gpa.free(self.fwd_decl_buf);
193 gpa.free(self.code_header_buf);
194 gpa.free(self.code_buf);
195 gpa.free(self.scratch_buf);
472pub fn updateContainerType(
473 c: *C,
474 pt: Zcu.PerThread,
475 ty: InternPool.Index,
476 success: bool,
477) link.File.UpdateContainerTypeError!void {
478 try c.type_pool.updateContainerType(pt, .{ .c = c }, ty, success);
196479}
197480
198481pub fn updateFunc(
199 self: *C,
482 c: *C,
200483 pt: Zcu.PerThread,
201484 func_index: InternPool.Index,
202485 mir: *AnyMir,
203) link.File.UpdateNavError!void {
486) Allocator.Error!void {
204487 const zcu = pt.zcu;
205488 const gpa = zcu.gpa;
206 const func = zcu.funcInfo(func_index);
489 const nav = zcu.funcInfo(func_index).owner_nav;
207490
208 const gop = try self.navs.getOrPut(gpa, func.owner_nav);
209 if (gop.found_existing) gop.value_ptr.deinit(gpa);
210 gop.value_ptr.* = .{
211 .code = .empty,
212 .fwd_decl = .empty,
213 .ctype_pool = mir.c.ctype_pool.move(),
214 .lazy_fns = mir.c.lazy_fns.move(),
491 const rendered_decl: *RenderedDecl = rd: {
492 const gop = try c.navs.getOrPut(gpa, nav);
493 if (gop.found_existing) gop.value_ptr.deinit(gpa);
494 break :rd gop.value_ptr;
215495 };
216 gop.value_ptr.fwd_decl = try self.addString(mir.c.fwd_decl);
217 const code_header = try self.addString(mir.c.code_header);
218 const code = try self.addString(mir.c.code);
219 gop.value_ptr.code = code_header.concat(code);
220 try self.addUavsFromCodegen(&mir.c.uavs);
221}
222
223fn updateUav(self: *C, pt: Zcu.PerThread, i: usize) link.File.FlushError!void {
224 const gpa = self.base.comp.gpa;
225 const uav = self.uavs.keys()[i];
226
227 var object: codegen.Object = .{
228 .dg = .{
229 .gpa = gpa,
230 .pt = pt,
231 .mod = pt.zcu.root_mod,
232 .error_msg = null,
233 .pass = .{ .uav = uav },
234 .is_naked_fn = false,
235 .expected_block = null,
236 .fwd_decl = undefined,
237 .ctype_pool = .empty,
238 .scratch = .initBuffer(self.scratch_buf),
239 .uavs = .empty,
240 },
241 .code_header = undefined,
242 .code = undefined,
243 .indent_counter = 0,
244 };
245 object.dg.fwd_decl = .initOwnedSlice(gpa, self.fwd_decl_buf);
246 object.code = .initOwnedSlice(gpa, self.code_buf);
247 defer {
248 object.dg.uavs.deinit(gpa);
249 object.dg.ctype_pool.deinit(object.dg.gpa);
250
251 self.fwd_decl_buf = object.dg.fwd_decl.toArrayList().allocatedSlice();
252 self.code_buf = object.code.toArrayList().allocatedSlice();
253 self.scratch_buf = object.dg.scratch.allocatedSlice();
254 }
255 try object.dg.ctype_pool.init(gpa);
256
257 const c_value: codegen.CValue = .{ .constant = Value.fromInterned(uav) };
258 const alignment: Alignment = self.aligned_uavs.get(uav) orelse .none;
259 codegen.genDeclValue(&object, c_value.constant, c_value, alignment, .none) catch |err| switch (err) {
260 error.AnalysisFail => {
261 @panic("TODO: C backend AnalysisFail on anonymous decl");
262 //try zcu.failed_decls.put(gpa, decl_index, object.dg.error_msg.?);
263 //return;
264 },
265 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,
496 c.navs.lockPointers();
497 defer c.navs.unlockPointers();
498
499 rendered_decl.* = .{
500 .fwd_decl = try c.addString(&.{mir.c.fwd_decl}),
501 .code = try c.addString(&.{ mir.c.code_header, mir.c.code }),
502 .ctype_deps = try c.addCTypeDependencies(pt, &mir.c.ctype_deps),
503 .need_uavs = mir.c.need_uavs.move(),
504 .need_tag_name_funcs = mir.c.need_tag_name_funcs.move(),
505 .need_never_tail_funcs = mir.c.need_never_tail_funcs.move(),
506 .need_never_inline_funcs = mir.c.need_never_inline_funcs.move(),
266507 };
267508
268 try self.addUavsFromCodegen(&object.dg.uavs);
509 const old_uavs_len = c.uavs.count();
510 try c.uavs.ensureUnusedCapacity(gpa, rendered_decl.need_uavs.count());
511 for (rendered_decl.need_uavs.keys()) |val| {
512 const gop = c.uavs.getOrPutAssumeCapacity(val);
513 if (gop.found_existing) {
514 assert(gop.index < old_uavs_len);
515 } else {
516 assert(gop.index >= old_uavs_len);
517 }
518 }
519 try c.updateNewUavs(pt, old_uavs_len);
269520
270 object.dg.ctype_pool.freeUnusedCapacity(gpa);
271 self.uavs.values()[i] = .{
272 .fwd_decl = try self.addString(object.dg.fwd_decl.written()),
273 .code = try self.addString(object.code.written()),
274 .ctype_pool = object.dg.ctype_pool.move(),
275 };
521 try c.type_pool.flushPending(pt, .{ .c = c });
276522}
277523
278pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) link.File.UpdateNavError!void {
524pub fn updateNav(
525 c: *C,
526 pt: Zcu.PerThread,
527 nav_index: InternPool.Nav.Index,
528) Allocator.Error!void {
279529 const tracy = trace(@src());
280530 defer tracy.end();
281531
282 const gpa = self.base.comp.gpa;
532 const gpa = c.base.comp.gpa;
283533 const zcu = pt.zcu;
284534 const ip = &zcu.intern_pool;
285535
286536 const nav = ip.getNav(nav_index);
287 const nav_init = switch (ip.indexToKey(nav.status.fully_resolved.val)) {
537 switch (ip.indexToKey(nav.status.fully_resolved.val)) {
288538 .func => return,
289 .@"extern" => .none,
290 .variable => |variable| variable.init,
291 else => nav.status.fully_resolved.val,
539 .@"extern" => {},
540 else => {
541 const nav_ty: Type = .fromInterned(nav.typeOf(ip));
542 if (!nav_ty.hasRuntimeBits(zcu)) {
543 if (c.navs.fetchSwapRemove(nav_index)) |kv| {
544 var old_rendered = kv.value;
545 old_rendered.deinit(gpa);
546 }
547 return;
548 }
549 },
550 }
551
552 const rendered_decl: *RenderedDecl = rd: {
553 const gop = try c.navs.getOrPut(gpa, nav_index);
554 if (gop.found_existing) {
555 gop.value_ptr.clearRetainingCapacity();
556 } else {
557 gop.value_ptr.* = .init;
558 }
559 break :rd gop.value_ptr;
292560 };
293 if (nav_init != .none and !Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(zcu)) return;
561 c.navs.lockPointers();
562 defer c.navs.unlockPointers();
294563
295 const gop = try self.navs.getOrPut(gpa, nav_index);
296 errdefer _ = self.navs.pop();
297 if (!gop.found_existing) gop.value_ptr.* = .{};
298 const ctype_pool = &gop.value_ptr.ctype_pool;
299 try ctype_pool.init(gpa);
300 ctype_pool.clearRetainingCapacity();
564 {
565 var arena: std.heap.ArenaAllocator = .init(gpa);
566 defer arena.deinit();
301567
302 var object: codegen.Object = .{
303 .dg = .{
568 var dg: codegen.DeclGen = .{
304569 .gpa = gpa,
570 .arena = arena.allocator(),
305571 .pt = pt,
306572 .mod = zcu.navFileScope(nav_index).mod.?,
307573 .error_msg = null,
308 .pass = .{ .nav = nav_index },
574 .owner_nav = nav_index.toOptional(),
309575 .is_naked_fn = false,
310576 .expected_block = null,
311 .fwd_decl = undefined,
312 .ctype_pool = ctype_pool.*,
313 .scratch = .initBuffer(self.scratch_buf),
314 .uavs = .empty,
315 },
316 .code_header = undefined,
317 .code = undefined,
318 .indent_counter = 0,
577 .ctype_deps = .empty,
578 .uavs = rendered_decl.need_uavs.move(),
579 };
580
581 defer {
582 rendered_decl.need_uavs = dg.uavs.move();
583 dg.ctype_deps.deinit(gpa);
584 }
585
586 rendered_decl.fwd_decl = fwd_decl: {
587 var aw: std.Io.Writer.Allocating = .fromArrayList(gpa, &c.string_bytes);
588 defer c.string_bytes = aw.toArrayList();
589 const start = aw.written().len;
590 codegen.genDeclFwd(&dg, &aw.writer) catch |err| switch (err) {
591 error.AnalysisFail => switch (zcu.codegenFailMsg(nav_index, dg.error_msg.?)) {
592 error.CodegenFail => return,
593 error.OutOfMemory => |e| return e,
594 },
595 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,
596 };
597 break :fwd_decl .{
598 .start = @intCast(start),
599 .len = @intCast(aw.written().len - start),
600 };
601 };
602
603 rendered_decl.code = code: {
604 var aw: std.Io.Writer.Allocating = .fromArrayList(gpa, &c.string_bytes);
605 defer c.string_bytes = aw.toArrayList();
606 const start = aw.written().len;
607 codegen.genDecl(&dg, &aw.writer) catch |err| switch (err) {
608 error.AnalysisFail => switch (zcu.codegenFailMsg(nav_index, dg.error_msg.?)) {
609 error.CodegenFail => return,
610 error.OutOfMemory => |e| return e,
611 },
612 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,
613 };
614 break :code .{
615 .start = @intCast(start),
616 .len = @intCast(aw.written().len - start),
617 };
618 };
619
620 rendered_decl.ctype_deps = try c.addCTypeDependencies(pt, &dg.ctype_deps);
621 }
622
623 const old_uavs_len = c.uavs.count();
624 try c.uavs.ensureUnusedCapacity(gpa, rendered_decl.need_uavs.count());
625 for (rendered_decl.need_uavs.keys()) |val| {
626 const gop = c.uavs.getOrPutAssumeCapacity(val);
627 if (gop.found_existing) {
628 assert(gop.index < old_uavs_len);
629 } else {
630 assert(gop.index >= old_uavs_len);
631 }
632 }
633 try c.updateNewUavs(pt, old_uavs_len);
634
635 try c.type_pool.flushPending(pt, .{ .c = c });
636}
637
638/// Unlike `updateNav` and `updateFunc`, this does *not* add newly-discovered UAVs to `c.uavs`. The
639/// caller is instead responsible for doing that (by iterating `rendered_decl.need_uavs`). However,
640/// this function *does* still add newly-discovered *types* to `c.type_pool`.
641///
642/// This function does not accept an alignment for the UAV, because the alignment needed on a UAV is
643/// not known until `flush` (since we need to have seen all uses of the UAV first). Instead, `flush`
644/// will prefix the UAV definition with an appropriate alignment annotation if necessary.
645fn updateUav(
646 c: *C,
647 pt: Zcu.PerThread,
648 val: Value,
649 rendered_decl: *RenderedDecl,
650) Allocator.Error!void {
651 const tracy = trace(@src());
652 defer tracy.end();
653
654 const gpa = c.base.comp.gpa;
655
656 var arena: std.heap.ArenaAllocator = .init(gpa);
657 defer arena.deinit();
658
659 var dg: codegen.DeclGen = .{
660 .gpa = gpa,
661 .arena = arena.allocator(),
662 .pt = pt,
663 .mod = pt.zcu.root_mod,
664 .error_msg = null,
665 .owner_nav = .none,
666 .is_naked_fn = false,
667 .expected_block = null,
668 .ctype_deps = .empty,
669 .uavs = .empty,
319670 };
320 object.dg.fwd_decl = .initOwnedSlice(gpa, self.fwd_decl_buf);
321 object.code = .initOwnedSlice(gpa, self.code_buf);
322671 defer {
323 object.dg.uavs.deinit(gpa);
324 ctype_pool.* = object.dg.ctype_pool.move();
325 ctype_pool.freeUnusedCapacity(gpa);
326
327 self.fwd_decl_buf = object.dg.fwd_decl.toArrayList().allocatedSlice();
328 self.code_buf = object.code.toArrayList().allocatedSlice();
329 self.scratch_buf = object.dg.scratch.allocatedSlice();
672 rendered_decl.need_uavs = dg.uavs.move();
673 dg.ctype_deps.deinit(gpa);
330674 }
331675
332 codegen.genDecl(&object) catch |err| switch (err) {
333 error.AnalysisFail => switch (zcu.codegenFailMsg(nav_index, object.dg.error_msg.?)) {
334 error.CodegenFail => return,
335 error.OutOfMemory => |e| return e,
336 },
337 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,
676 rendered_decl.fwd_decl = fwd_decl: {
677 var aw: std.Io.Writer.Allocating = .fromArrayList(gpa, &c.string_bytes);
678 defer c.string_bytes = aw.toArrayList();
679 const start = aw.written().len;
680 codegen.genDeclValueFwd(&dg, &aw.writer, .{
681 .name = .{ .constant = val },
682 .@"const" = true,
683 .@"threadlocal" = false,
684 .init_val = val,
685 }) catch |err| switch (err) {
686 error.AnalysisFail => {
687 @panic("TODO: CBE error.AnalysisFail on uav");
688 },
689 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,
690 };
691 break :fwd_decl .{
692 .start = @intCast(start),
693 .len = @intCast(aw.written().len - start),
694 };
695 };
696
697 rendered_decl.code = code: {
698 var aw: std.Io.Writer.Allocating = .fromArrayList(gpa, &c.string_bytes);
699 defer c.string_bytes = aw.toArrayList();
700 const start = aw.written().len;
701 codegen.genDeclValue(&dg, &aw.writer, .{
702 .name = .{ .constant = val },
703 .@"const" = true,
704 .@"threadlocal" = false,
705 .init_val = val,
706 }) catch |err| switch (err) {
707 error.AnalysisFail => {
708 @panic("TODO: CBE error.AnalysisFail on uav");
709 },
710 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,
711 };
712 break :code .{
713 .start = @intCast(start),
714 .len = @intCast(aw.written().len - start),
715 };
338716 };
339 gop.value_ptr.fwd_decl = try self.addString(object.dg.fwd_decl.written());
340 gop.value_ptr.code = try self.addString(object.code.written());
341 try self.addUavsFromCodegen(&object.dg.uavs);
717
718 rendered_decl.ctype_deps = try c.addCTypeDependencies(pt, &dg.ctype_deps);
342719}
343720
344pub fn updateLineNumber(self: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
345 // The C backend does not have the ability to fix line numbers without re-generating
346 // the entire Decl.
347 _ = self;
721pub fn updateLineNumber(c: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) error{}!void {
722 // The C backend does not currently emit "#line" directives. Even if it did, it would not be
723 // capable of updating those line numbers without re-generating the entire declaration.
724 _ = c;
348725 _ = pt;
349726 _ = ti_id;
350727}
351728
352fn abiDefines(w: *std.Io.Writer, target: *const std.Target) !void {
353 switch (target.abi) {
354 .msvc, .itanium => try w.writeAll("#define ZIG_TARGET_ABI_MSVC\n"),
355 else => {},
356 }
357 try w.print("#define ZIG_TARGET_MAX_INT_ALIGNMENT {d}\n", .{
358 target.cMaxIntAlignment(),
359 });
360}
361
362pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
363 _ = arena; // Has the same lifetime as the call to Compilation.update.
364
729pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
365730 const tracy = trace(@src());
366731 defer tracy.end();
367732
368733 const sub_prog_node = prog_node.start("Flush Module", 0);
369734 defer sub_prog_node.end();
370735
371 const comp = self.base.comp;
736 const comp = c.base.comp;
372737 const diags = &comp.link_diags;
373738 const gpa = comp.gpa;
374739 const io = comp.io;
375 const zcu = self.base.comp.zcu.?;
740 const zcu = c.base.comp.zcu.?;
376741 const ip = &zcu.intern_pool;
742 const target = zcu.getTarget();
377743 const pt: Zcu.PerThread = .activate(zcu, tid);
378744 defer pt.deactivate();
379745
746 // If it's somehow not made it into the pool, we need to generate the type `[:0]const u8` for
747 // error names.
748 const slice_const_u8_sentinel_0_pool_index = try c.type_pool.get(
749 pt,
750 .{ .c = c },
751 .slice_const_u8_sentinel_0_type,
752 );
753 try c.type_pool.flushPending(pt, .{ .c = c });
754
755 // Find the set of referenced NAVs; these are the ones we'll emit. It is important in this
756 // backend that we only emit referenced NAVs, because other ones may contain code from past
757 // incremental updates which is invalid C (due to e.g. types changing). Machine code backends
758 // don't have this problem because there are, of course, no type checking performed when you
759 // *execute* a binary!
760 var need_navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void) = .empty;
761 defer need_navs.deinit(gpa);
762 {
763 const unit_references = try zcu.resolveReferences();
764 for (c.navs.keys()) |nav| {
765 const nav_val = ip.getNav(nav).status.fully_resolved.val;
766 const check_unit: ?InternPool.AnalUnit = switch (ip.indexToKey(nav_val)) {
767 else => .wrap(.{ .nav_val = nav }),
768 .func => .wrap(.{ .func = nav_val }),
769 // TODO: this is a hack to deal with the fact that there's currently no good way to
770 // know which `extern`s are alive. This can and will break in certain patterns of
771 // incremental update. We kind of need to think a bit more about how the frontend
772 // actually represents `extern`, it's a bit awkward right now.
773 .@"extern" => null,
774 };
775 if (check_unit) |u| {
776 if (!unit_references.contains(u)) continue;
777 }
778 try need_navs.putNoClobber(gpa, nav, {});
779 }
780 }
781
782 // Using our knowledge of which NAVs are referenced, we now need to discover the set of UAVs and
783 // C types which are referenced (and hence must be emitted). As above, this is necessary to make
784 // sure we only emit valid C code.
785 //
786 // At the same time, we will discover the set of lazy functions which are referenced.
787
788 var need_uavs: std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment) = .empty;
789 defer need_uavs.deinit(gpa);
790
791 var need_types: std.AutoArrayHashMapUnmanaged(link.ConstPool.Index, void) = .empty;
792 defer need_types.deinit(gpa);
793 var need_errunion_types: std.AutoArrayHashMapUnmanaged(link.ConstPool.Index, void) = .empty;
794 defer need_errunion_types.deinit(gpa);
795 var need_aligned_types: std.AutoArrayHashMapUnmanaged(link.ConstPool.Index, u64) = .empty;
796 defer need_aligned_types.deinit(gpa);
797
798 var need_tag_name_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .empty;
799 defer need_tag_name_funcs.deinit(gpa);
800
801 var need_never_tail_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void) = .empty;
802 defer need_never_tail_funcs.deinit(gpa);
803
804 var need_never_inline_funcs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, void) = .empty;
805 defer need_never_inline_funcs.deinit(gpa);
806
807 // As mentioned above, we need this type for error names.
808 try need_types.put(gpa, slice_const_u8_sentinel_0_pool_index, {});
809
810 // Every exported NAV should have been discovered via `zcu.resolveReferences`...
811 for (c.exported_navs.keys()) |nav| assert(need_navs.contains(nav));
812 // ...but we *do* need to add exported UAVs to the set.
813 try need_uavs.ensureUnusedCapacity(gpa, c.exported_uavs.count());
814 for (c.exported_uavs.keys()) |uav| {
815 const gop = need_uavs.getOrPutAssumeCapacity(uav);
816 if (!gop.found_existing) gop.value_ptr.* = .none;
817 }
818
819 // For every referenced NAV, some UAVs, C types, and lazy functions may be referenced.
820 for (need_navs.keys()) |nav| {
821 const rendered = c.navs.getPtr(nav).?;
822 try mergeNeededCTypes(
823 c,
824 &need_types,
825 &need_errunion_types,
826 &need_aligned_types,
827 &rendered.ctype_deps,
828 );
829 try mergeNeededUavs(zcu, &need_uavs, &rendered.need_uavs);
830
831 try need_tag_name_funcs.ensureUnusedCapacity(gpa, rendered.need_tag_name_funcs.count());
832 for (rendered.need_tag_name_funcs.keys()) |enum_type| {
833 need_tag_name_funcs.putAssumeCapacity(enum_type, {});
834 }
835
836 try need_never_tail_funcs.ensureUnusedCapacity(gpa, rendered.need_never_tail_funcs.count());
837 for (rendered.need_never_tail_funcs.keys()) |fn_nav| {
838 need_never_tail_funcs.putAssumeCapacity(fn_nav, {});
839 }
840
841 try need_never_inline_funcs.ensureUnusedCapacity(gpa, rendered.need_never_inline_funcs.count());
842 for (rendered.need_never_inline_funcs.keys()) |fn_nav| {
843 need_never_inline_funcs.putAssumeCapacity(fn_nav, {});
844 }
845 }
846
847 // UAVs may reference other UAVs or C types.
380848 {
381 var i: usize = 0;
382 while (i < self.uavs.count()) : (i += 1) {
383 try self.updateUav(pt, i);
849 var index: usize = 0;
850 while (need_uavs.count() > index) : (index += 1) {
851 const val = need_uavs.keys()[index];
852 const rendered = c.uavs.getPtr(val).?;
853 try mergeNeededCTypes(
854 c,
855 &need_types,
856 &need_errunion_types,
857 &need_aligned_types,
858 &rendered.ctype_deps,
859 );
860 try mergeNeededUavs(zcu, &need_uavs, &rendered.need_uavs);
384861 }
385862 }
386863
387 // This code path happens exclusively with -ofmt=c. The flush logic for
388 // emit-h is in `flushEmitH` below.
864 // Finally, C types may reference other C types.
865 {
866 var index: usize = 0;
867 var errunion_index: usize = 0;
868 var aligned_index: usize = 0;
869 while (true) {
870 if (index < need_types.count()) {
871 const pool_index = need_types.keys()[index];
872 const rendered = &c.types.items[@intFromEnum(pool_index)];
873 try mergeNeededCTypes(
874 c,
875 &need_types,
876 &need_errunion_types,
877 &need_aligned_types,
878 &rendered.definition_deps, // we're tasked with emitting the *definition* of this type
879 );
880 index += 1;
881 continue;
882 }
389883
390 var f: Flush = .{
391 .ctype_pool = .empty,
392 .ctype_global_from_decl_map = .empty,
393 .ctypes = .empty,
884 if (errunion_index < need_errunion_types.count()) {
885 const payload_pool_index = need_errunion_types.keys()[errunion_index];
886 const rendered = &c.types.items[@intFromEnum(payload_pool_index)];
887 try mergeNeededCTypes(
888 c,
889 &need_types,
890 &need_errunion_types,
891 &need_aligned_types,
892 &rendered.deps, // the error union type requires emitting this type's *name*
893 );
894 errunion_index += 1;
895 continue;
896 }
394897
395 .lazy_ctype_pool = .empty,
396 .lazy_fns = .empty,
397 .lazy_fwd_decl = .empty,
398 .lazy_code = .empty,
898 if (aligned_index < need_aligned_types.count()) {
899 const pool_index = need_aligned_types.keys()[aligned_index];
900 const rendered = &c.types.items[@intFromEnum(pool_index)];
901 try mergeNeededCTypes(
902 c,
903 &need_types,
904 &need_errunion_types,
905 &need_aligned_types,
906 &rendered.deps, // an aligned typedef requires emitting this type's *name*
907 );
908 aligned_index += 1;
909 continue;
910 }
399911
400 .all_buffers = .empty,
401 .file_size = 0,
402 };
912 break;
913 }
914 }
915
916 // Now that we know which types are required, generate aligned typedefs. One buffer per aligned
917 // type, with *all* aligned typedefs for that type.
918 const aligned_type_strings = try arena.alloc([]const u8, need_aligned_types.count());
919 {
920 var aw: std.Io.Writer.Allocating = .init(gpa);
921 defer aw.deinit();
922 var unused_deps: codegen.CType.Dependencies = .empty;
923 defer unused_deps.deinit(gpa);
924 for (
925 need_aligned_types.keys(),
926 need_aligned_types.values(),
927 aligned_type_strings,
928 ) |pool_index, align_mask, *str_out| {
929 const ty: Type = .fromInterned(pool_index.val(&c.type_pool));
930 const has_layout = c.types.items[@intFromEnum(pool_index)].errunion_definition.len > 0;
931 for (0..@bitSizeOf(@TypeOf(align_mask))) |bit_index| {
932 switch (@as(u1, @truncate(align_mask >> @intCast(bit_index)))) {
933 0 => continue,
934 1 => {},
935 }
936 codegen.CType.render_defs.defineAligned(
937 ty,
938 .fromLog2Units(@intCast(bit_index)),
939 has_layout,
940 &unused_deps,
941 arena,
942 &aw.writer,
943 pt,
944 ) catch |err| switch (err) {
945 error.WriteFailed => return error.OutOfMemory,
946 error.OutOfMemory => |e| return e,
947 };
948 }
949 str_out.* = try arena.dupe(u8, aw.written());
950 aw.clearRetainingCapacity();
951 }
952 }
953
954 // We have discovered the full set of NAVs, UAVs, and types we need to emit, and will now begin
955 // to build the output buffer. Our strategy is to emit the C source in this order:
956 //
957 // * ABI defines and `#include "zig.h"`
958 // * Big-int type definitions
959 // * Other CType definitions (traversing the dependency graph to sort topologically)
960 // * Global assembly
961 // * UAV exports
962 // * NAV exports
963 // * UAV forward declarations
964 // * NAV forward declarations
965 // * Lazy declarations (error names; @tagName functions; never_tail/never_inline wrappers)
966 // * UAV definitions
967 // * NAV definitions
968 //
969 // Most of these sections are order-independent within themselves, with the exception of the
970 // type definitions, which must be ordered to avoid a struct/union from embedding a type which
971 // is currently incomplete.
972 //
973 // When emitting UAV forward declarations, if the UAV requires alignment, we must prefix it with
974 // an alignment annotation. We couldn't emit the alignment into the UAV's `RenderedDecl` because
975 // we couldn't have known the required alignment until now!
976
977 var f: Flush = .{ .all_buffers = .empty, .file_size = 0 };
403978 defer f.deinit(gpa);
404979
405 var abi_defines_aw: std.Io.Writer.Allocating = .init(gpa);
406 defer abi_defines_aw.deinit();
407 abiDefines(&abi_defines_aw.writer, zcu.getTarget()) catch |err| switch (err) {
408 error.WriteFailed => return error.OutOfMemory,
409 };
980 // We know exactly what we'll be emitting, so can reserve capacity for all of our buffers!
981
982 try f.all_buffers.ensureUnusedCapacity(gpa, 3 + // ABI defines and `#include "zig.h"`
983 1 + // Big-int type definitions
984 need_types.count() + // `RenderedType.fwd_decl` (worst-case)
985 need_types.count() + // `RenderedType.definition`
986 need_errunion_types.count() + // `RenderedType.errunion_fwd_decl` (worst-case)
987 need_errunion_types.count() + // `RenderedType.errunion_definition`
988 need_aligned_types.count() + // `aligned_type_strings`
989 1 + // Global assembly
990 c.exported_uavs.count() + // UAV export block
991 c.exported_navs.count() + // NAV export block
992 need_uavs.count() + // UAV forward declarations
993 need_navs.count() + // NAV forward declarations
994 1 + // Lazy declarations
995 need_uavs.count() * 3 + // UAV definitions ("static ", "zig_align(4)", "<definition body>")
996 need_navs.count() * 2); // NAV definitions ("static ", "<definition body>")
997
998 // ABI defines and `#include "zig.h"`
999 switch (target.abi) {
1000 .msvc, .itanium => f.appendBufAssumeCapacity("#define ZIG_TARGET_ABI_MSVC\n"),
1001 else => {},
1002 }
1003 f.appendBufAssumeCapacity(try std.fmt.allocPrint(
1004 arena,
1005 "#define ZIG_TARGET_MAX_INT_ALIGNMENT {d}\n",
1006 .{target.cMaxIntAlignment()},
1007 ));
1008 f.appendBufAssumeCapacity(
1009 \\#include "zig.h"
1010 \\
1011 );
4101012
411 // Covers defines, zig.h, ctypes, asm, lazy fwd.
412 try f.all_buffers.ensureUnusedCapacity(gpa, 5);
1013 // Big-int type definitions
1014 var bigint_aw: std.Io.Writer.Allocating = .init(gpa);
1015 defer bigint_aw.deinit();
1016 for (c.bigint_types.keys()) |bigint| {
1017 codegen.CType.render_defs.defineBigInt(bigint, &bigint_aw.writer, zcu) catch |err| switch (err) {
1018 error.WriteFailed => return error.OutOfMemory,
1019 };
1020 }
1021 f.appendBufAssumeCapacity(bigint_aw.written());
4131022
414 f.appendBufAssumeCapacity(abi_defines_aw.written());
415 f.appendBufAssumeCapacity(zig_h);
1023 // CType definitions
1024 {
1025 var ft: FlushTypes = .{
1026 .c = c,
1027 .f = &f,
1028 .aligned_types = &need_aligned_types,
1029 .aligned_type_strings = aligned_type_strings,
1030 .status = .empty,
1031 .errunion_status = .empty,
1032 .aligned_status = .empty,
1033 };
1034 defer {
1035 ft.status.deinit(gpa);
1036 ft.errunion_status.deinit(gpa);
1037 ft.aligned_status.deinit(gpa);
1038 }
1039 try ft.status.ensureUnusedCapacity(gpa, need_types.count());
1040 try ft.errunion_status.ensureUnusedCapacity(gpa, need_errunion_types.count());
1041 try ft.aligned_status.ensureUnusedCapacity(gpa, need_aligned_types.count());
4161042
417 const ctypes_index = f.all_buffers.items.len;
418 f.all_buffers.items.len += 1;
1043 for (need_types.keys()) |pool_index| {
1044 ft.doType(pool_index);
1045 }
1046 for (need_errunion_types.keys()) |pool_index| {
1047 ft.doErrunionType(pool_index);
1048 }
1049 for (need_aligned_types.keys()) |pool_index| {
1050 ft.doAlignedTypeFwd(pool_index);
1051 }
1052 }
4191053
1054 // Global assembly
4201055 var asm_aw: std.Io.Writer.Allocating = .init(gpa);
4211056 defer asm_aw.deinit();
4221057 codegen.genGlobalAsm(zcu, &asm_aw.writer) catch |err| switch (err) {
......@@ -424,462 +1059,472 @@ pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.P
4241059 };
4251060 f.appendBufAssumeCapacity(asm_aw.written());
4261061
427 const lazy_index = f.all_buffers.items.len;
428 f.all_buffers.items.len += 1;
1062 var export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .empty;
1063 defer export_names.deinit(gpa);
1064 try export_names.ensureTotalCapacity(gpa, @intCast(zcu.single_exports.count()));
1065 for (zcu.single_exports.values()) |export_index| {
1066 export_names.putAssumeCapacity(export_index.ptr(zcu).opts.name, {});
1067 }
1068 for (zcu.multi_exports.values()) |info| {
1069 try export_names.ensureUnusedCapacity(gpa, info.len);
1070 for (zcu.all_exports.items[info.index..][0..info.len]) |@"export"| {
1071 export_names.putAssumeCapacity(@"export".opts.name, {});
1072 }
1073 }
4291074
430 try f.lazy_ctype_pool.init(gpa);
431 try self.flushErrDecls(pt, &f);
1075 // UAV export block
1076 for (c.exported_uavs.values()) |code| {
1077 f.appendBufAssumeCapacity(code.get(c));
1078 }
4321079
433 // Unlike other backends, the .c code we are emitting has order-dependent decls.
434 // `CType`s, forward decls, and non-functions first.
1080 // NAV export block
1081 for (c.exported_navs.values()) |code| {
1082 f.appendBufAssumeCapacity(code.get(c));
1083 }
4351084
436 {
437 var export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .empty;
438 defer export_names.deinit(gpa);
439 try export_names.ensureTotalCapacity(gpa, @intCast(zcu.single_exports.count()));
440 for (zcu.single_exports.values()) |export_index| {
441 export_names.putAssumeCapacity(export_index.ptr(zcu).opts.name, {});
442 }
443 for (zcu.multi_exports.values()) |info| {
444 try export_names.ensureUnusedCapacity(gpa, info.len);
445 for (zcu.all_exports.items[info.index..][0..info.len]) |@"export"| {
446 export_names.putAssumeCapacity(@"export".opts.name, {});
447 }
1085 // UAV forward declarations
1086 for (need_uavs.keys()) |val| {
1087 if (c.exported_uavs.contains(val)) continue; // the export was the declaration
1088 const fwd_decl = c.uavs.getPtr(val).?.fwd_decl;
1089 f.appendBufAssumeCapacity(fwd_decl.get(c));
1090 }
1091
1092 // NAV forward declarations
1093 for (need_navs.keys()) |nav| {
1094 if (c.exported_navs.contains(nav)) continue; // the export was the declaration
1095 if (ip.getNav(nav).getExtern(ip)) |e| {
1096 if (export_names.contains(e.name)) continue;
4481097 }
1098 const fwd_decl = c.navs.getPtr(nav).?.fwd_decl;
1099 f.appendBufAssumeCapacity(fwd_decl.get(c));
1100 }
4491101
450 for (self.uavs.keys(), self.uavs.values()) |uav, *av_block| try self.flushAvBlock(
451 pt,
452 zcu.root_mod,
453 &f,
454 av_block,
455 self.exported_uavs.getPtr(uav),
456 export_names,
457 .none,
1102 // Lazy declarations
1103 var lazy_decls_aw: std.Io.Writer.Allocating = .init(gpa);
1104 defer lazy_decls_aw.deinit();
1105 {
1106 var lazy_dg: codegen.DeclGen = .{
1107 .gpa = gpa,
1108 .arena = arena,
1109 .pt = pt,
1110 .mod = pt.zcu.root_mod,
1111 .owner_nav = .none,
1112 .is_naked_fn = false,
1113 .expected_block = null,
1114 .error_msg = null,
1115 .ctype_deps = .empty,
1116 .uavs = .empty,
1117 };
1118 defer {
1119 assert(lazy_dg.uavs.count() == 0);
1120 lazy_dg.ctype_deps.deinit(gpa);
1121 }
1122 const slice_const_u8_sentinel_0_cty: codegen.CType = try .lower(
1123 .slice_const_u8_sentinel_0,
1124 &lazy_dg.ctype_deps,
1125 arena,
1126 zcu,
4581127 );
459
460 for (self.navs.keys(), self.navs.values()) |nav, *av_block| try self.flushAvBlock(
461 pt,
462 zcu.navFileScope(nav).mod.?,
463 &f,
464 av_block,
465 self.exported_navs.getPtr(nav),
466 export_names,
467 if (ip.getNav(nav).getExtern(ip) != null)
468 ip.getNav(nav).name.toOptional()
469 else
470 .none,
1128 const slice_const_u8_sentinel_0_name = try std.fmt.allocPrint(
1129 arena,
1130 "{f}",
1131 .{slice_const_u8_sentinel_0_cty.fmtTypeName(zcu)},
4711132 );
1133 codegen.genErrDecls(zcu, &lazy_decls_aw.writer, slice_const_u8_sentinel_0_name) catch |err| switch (err) {
1134 error.WriteFailed => return error.OutOfMemory,
1135 };
1136 for (need_tag_name_funcs.keys()) |enum_ty_ip| {
1137 const enum_ty: Type = .fromInterned(enum_ty_ip);
1138 const enum_cty: codegen.CType = try .lower(
1139 enum_ty,
1140 &lazy_dg.ctype_deps,
1141 arena,
1142 zcu,
1143 );
1144 codegen.genTagNameFn(
1145 zcu,
1146 &lazy_decls_aw.writer,
1147 slice_const_u8_sentinel_0_name,
1148 enum_ty,
1149 try std.fmt.allocPrint(arena, "{f}", .{enum_cty.fmtTypeName(zcu)}),
1150 ) catch |err| switch (err) {
1151 error.WriteFailed => return error.OutOfMemory,
1152 };
1153 }
1154 for (need_never_tail_funcs.keys()) |fn_nav| {
1155 codegen.genLazyCallModifierFn(&lazy_dg, fn_nav, .never_tail, &lazy_decls_aw.writer) catch |err| switch (err) {
1156 error.WriteFailed => return error.OutOfMemory,
1157 error.OutOfMemory => |e| return e,
1158 error.AnalysisFail => unreachable,
1159 };
1160 }
1161 for (need_never_inline_funcs.keys()) |fn_nav| {
1162 codegen.genLazyCallModifierFn(&lazy_dg, fn_nav, .never_inline, &lazy_decls_aw.writer) catch |err| switch (err) {
1163 error.WriteFailed => return error.OutOfMemory,
1164 error.OutOfMemory => |e| return e,
1165 error.AnalysisFail => unreachable,
1166 };
1167 }
4721168 }
473
474 {
475 // We need to flush lazy ctypes after flushing all decls but before flushing any decl ctypes.
476 // This ensures that every lazy CType.Index exactly matches the global CType.Index.
477 try f.ctype_pool.init(gpa);
478 try self.flushCTypes(zcu, &f, .flush, &f.lazy_ctype_pool);
479
480 for (self.uavs.keys(), self.uavs.values()) |uav, av_block| {
481 try self.flushCTypes(zcu, &f, .{ .uav = uav }, &av_block.ctype_pool);
1169 f.appendBufAssumeCapacity(lazy_decls_aw.written());
1170
1171 // UAV definitions
1172 for (need_uavs.keys(), need_uavs.values()) |val, overalign| {
1173 const code = c.uavs.getPtr(val).?.code;
1174 if (code.len == 0) continue;
1175 if (!c.exported_uavs.contains(val)) {
1176 f.appendBufAssumeCapacity("static ");
4821177 }
483
484 for (self.navs.keys(), self.navs.values()) |nav, av_block| {
485 try self.flushCTypes(zcu, &f, .{ .nav = nav }, &av_block.ctype_pool);
1178 if (overalign != .none) {
1179 // As long as `Alignment` isn't too big, it's reasonable to just generate all possible
1180 // alignment annotations statically into a LUT, which avoids allocating strings on this
1181 // path.
1182 comptime assert(@bitSizeOf(Alignment) < 8);
1183 const table_len = (1 << @bitSizeOf(Alignment)) - 1;
1184 const table: [table_len][]const u8 = comptime table: {
1185 @setEvalBranchQuota(16_000);
1186 var table: [table_len][]const u8 = undefined;
1187 for (&table, 0..) |*str, log2_align| {
1188 const byte_align = Alignment.fromLog2Units(log2_align).toByteUnits().?;
1189 str.* = std.fmt.comptimePrint("zig_align({d}) ", .{byte_align});
1190 }
1191 break :table table;
1192 };
1193 f.appendBufAssumeCapacity(table[overalign.toLog2Units()]);
4861194 }
1195 f.appendBufAssumeCapacity(code.get(c));
4871196 }
4881197
489 f.all_buffers.items[ctypes_index] = f.ctypes.items;
490 f.file_size += f.ctypes.items.len;
491
492 f.all_buffers.items[lazy_index] = f.lazy_fwd_decl.items;
493 f.file_size += f.lazy_fwd_decl.items.len;
494
495 // Now the code.
496 try f.all_buffers.ensureUnusedCapacity(gpa, 1 + (self.uavs.count() + self.navs.count()) * 2);
497 f.appendBufAssumeCapacity(f.lazy_code.items);
498 for (self.uavs.keys(), self.uavs.values()) |uav, av_block| f.appendCodeAssumeCapacity(
499 if (self.exported_uavs.contains(uav)) .default else switch (ip.indexToKey(uav)) {
500 .@"extern" => .zig_extern,
501 else => .static,
502 },
503 self.getString(av_block.code),
504 );
505 for (self.navs.keys(), self.navs.values()) |nav, av_block| f.appendCodeAssumeCapacity(storage: {
506 if (self.exported_navs.contains(nav)) break :storage .default;
507 if (ip.getNav(nav).getExtern(ip) != null) break :storage .zig_extern;
508 break :storage .static;
509 }, self.getString(av_block.code));
1198 // NAV definitions
1199 for (need_navs.keys()) |nav| {
1200 const code = c.navs.getPtr(nav).?.code;
1201 if (code.len == 0) continue;
1202 if (!c.exported_navs.contains(nav)) {
1203 const is_extern = ip.getNav(nav).getExtern(ip) != null;
1204 f.appendBufAssumeCapacity(if (is_extern) "zig_extern " else "static ");
1205 }
1206 f.appendBufAssumeCapacity(code.get(c));
1207 }
5101208
511 const file = self.base.file.?;
1209 // We've collected all of our buffers; it's now time to actually write the file!
1210 const file = c.base.file.?;
5121211 file.setLength(io, f.file_size) catch |err| return diags.fail("failed to allocate file: {t}", .{err});
5131212 var fw = file.writer(io, &.{});
5141213 var w = &fw.interface;
5151214 w.writeVecAll(f.all_buffers.items) catch |err| switch (err) {
5161215 error.WriteFailed => return diags.fail("failed to write to '{f}': {s}", .{
517 std.fmt.alt(self.base.emit, .formatEscapeChar), @errorName(fw.err.?),
1216 std.fmt.alt(c.base.emit, .formatEscapeChar), @errorName(fw.err.?),
5181217 }),
5191218 };
5201219}
5211220
5221221const Flush = struct {
523 ctype_pool: codegen.CType.Pool,
524 ctype_global_from_decl_map: std.ArrayList(codegen.CType),
525 ctypes: std.ArrayList(u8),
526
527 lazy_ctype_pool: codegen.CType.Pool,
528 lazy_fns: LazyFns,
529 lazy_fwd_decl: std.ArrayList(u8),
530 lazy_code: std.ArrayList(u8),
531
5321222 /// We collect a list of buffers to write, and write them all at once with pwritev 😎
5331223 all_buffers: std.ArrayList([]const u8),
5341224 /// Keeps track of the total bytes of `all_buffers`.
5351225 file_size: u64,
5361226
537 const LazyFns = std.AutoHashMapUnmanaged(codegen.LazyFnKey, void);
538
5391227 fn appendBufAssumeCapacity(f: *Flush, buf: []const u8) void {
5401228 if (buf.len == 0) return;
5411229 f.all_buffers.appendAssumeCapacity(buf);
5421230 f.file_size += buf.len;
5431231 }
5441232
545 fn appendCodeAssumeCapacity(f: *Flush, storage: enum { default, zig_extern, static }, code: []const u8) void {
546 if (code.len == 0) return;
547 f.appendBufAssumeCapacity(switch (storage) {
548 .default => "\n",
549 .zig_extern => "\nzig_extern ",
550 .static => "\nstatic ",
551 });
552 f.appendBufAssumeCapacity(code);
553 }
554
5551233 fn deinit(f: *Flush, gpa: Allocator) void {
556 f.ctype_pool.deinit(gpa);
557 assert(f.ctype_global_from_decl_map.items.len == 0);
558 f.ctype_global_from_decl_map.deinit(gpa);
559 f.ctypes.deinit(gpa);
560 f.lazy_ctype_pool.deinit(gpa);
561 f.lazy_fns.deinit(gpa);
562 f.lazy_fwd_decl.deinit(gpa);
563 f.lazy_code.deinit(gpa);
5641234 f.all_buffers.deinit(gpa);
5651235 }
5661236};
5671237
568const FlushDeclError = error{
569 OutOfMemory,
570};
571
572fn flushCTypes(
573 self: *C,
574 zcu: *Zcu,
575 f: *Flush,
576 pass: codegen.DeclGen.Pass,
577 decl_ctype_pool: *const codegen.CType.Pool,
578) FlushDeclError!void {
579 const gpa = self.base.comp.gpa;
580 const global_ctype_pool = &f.ctype_pool;
581
582 const global_from_decl_map = &f.ctype_global_from_decl_map;
583 assert(global_from_decl_map.items.len == 0);
584 try global_from_decl_map.ensureTotalCapacity(gpa, decl_ctype_pool.items.len);
585 defer global_from_decl_map.clearRetainingCapacity();
586
587 var ctypes_aw: std.Io.Writer.Allocating = .fromArrayList(gpa, &f.ctypes);
588 const ctypes_bw = &ctypes_aw.writer;
589 defer f.ctypes = ctypes_aw.toArrayList();
590
591 for (0..decl_ctype_pool.items.len) |decl_ctype_pool_index| {
592 const PoolAdapter = struct {
593 global_from_decl_map: []const codegen.CType,
594 pub fn eql(pool_adapter: @This(), decl_ctype: codegen.CType, global_ctype: codegen.CType) bool {
595 return if (decl_ctype.toPoolIndex()) |decl_pool_index|
596 decl_pool_index < pool_adapter.global_from_decl_map.len and
597 pool_adapter.global_from_decl_map[decl_pool_index].eql(global_ctype)
598 else
599 decl_ctype.index == global_ctype.index;
600 }
601 pub fn copy(pool_adapter: @This(), decl_ctype: codegen.CType) codegen.CType {
602 return if (decl_ctype.toPoolIndex()) |decl_pool_index|
603 pool_adapter.global_from_decl_map[decl_pool_index]
604 else
605 decl_ctype;
606 }
607 };
608 const decl_ctype = codegen.CType.fromPoolIndex(decl_ctype_pool_index);
609 const global_ctype, const found_existing = try global_ctype_pool.getOrPutAdapted(
610 gpa,
611 decl_ctype_pool,
612 decl_ctype,
613 PoolAdapter{ .global_from_decl_map = global_from_decl_map.items },
614 );
615 global_from_decl_map.appendAssumeCapacity(global_ctype);
616 codegen.genTypeDecl(
617 zcu,
618 ctypes_bw,
619 global_ctype_pool,
620 global_ctype,
621 pass,
622 decl_ctype_pool,
623 decl_ctype,
624 found_existing,
625 ) catch |err| switch (err) {
626 error.WriteFailed => return error.OutOfMemory,
627 };
628 }
629}
1238pub fn updateExports(
1239 c: *C,
1240 pt: Zcu.PerThread,
1241 exported: Zcu.Exported,
1242 export_indices: []const Zcu.Export.Index,
1243) Allocator.Error!void {
1244 const zcu = pt.zcu;
1245 const gpa = zcu.gpa;
6301246
631fn flushErrDecls(self: *C, pt: Zcu.PerThread, f: *Flush) FlushDeclError!void {
632 const gpa = self.base.comp.gpa;
1247 var arena: std.heap.ArenaAllocator = .init(gpa);
1248 defer arena.deinit();
6331249
634 var object: codegen.Object = .{
635 .dg = .{
636 .gpa = gpa,
637 .pt = pt,
638 .mod = pt.zcu.root_mod,
639 .error_msg = null,
640 .pass = .flush,
641 .is_naked_fn = false,
642 .expected_block = null,
643 .fwd_decl = undefined,
644 .ctype_pool = f.lazy_ctype_pool,
645 .scratch = .initBuffer(self.scratch_buf),
646 .uavs = .empty,
647 },
648 .code_header = undefined,
649 .code = undefined,
650 .indent_counter = 0,
1250 var dg: codegen.DeclGen = .{
1251 .gpa = gpa,
1252 .arena = arena.allocator(),
1253 .pt = pt,
1254 .mod = zcu.root_mod,
1255 .owner_nav = .none,
1256 .is_naked_fn = false,
1257 .expected_block = null,
1258 .error_msg = null,
1259 .ctype_deps = .empty,
1260 .uavs = .empty,
6511261 };
652 object.dg.fwd_decl = .fromArrayList(gpa, &f.lazy_fwd_decl);
653 object.code = .fromArrayList(gpa, &f.lazy_code);
6541262 defer {
655 object.dg.uavs.deinit(gpa);
656 f.lazy_ctype_pool = object.dg.ctype_pool.move();
657 f.lazy_ctype_pool.freeUnusedCapacity(gpa);
658
659 f.lazy_fwd_decl = object.dg.fwd_decl.toArrayList();
660 f.lazy_code = object.code.toArrayList();
661 self.scratch_buf = object.dg.scratch.allocatedSlice();
1263 assert(dg.uavs.count() == 0);
1264 dg.ctype_deps.deinit(gpa);
6621265 }
6631266
664 codegen.genErrDecls(&object) catch |err| switch (err) {
665 error.AnalysisFail => unreachable,
666 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,
667 };
668
669 try self.addUavsFromCodegen(&object.dg.uavs);
670}
671
672fn flushLazyFn(
673 self: *C,
674 pt: Zcu.PerThread,
675 mod: *Module,
676 f: *Flush,
677 lazy_ctype_pool: *const codegen.CType.Pool,
678 lazy_fn: codegen.LazyFnMap.Entry,
679) FlushDeclError!void {
680 const gpa = self.base.comp.gpa;
681
682 var object: codegen.Object = .{
683 .dg = .{
684 .gpa = gpa,
685 .pt = pt,
686 .mod = mod,
687 .error_msg = null,
688 .pass = .flush,
689 .is_naked_fn = false,
690 .expected_block = null,
691 .fwd_decl = undefined,
692 .ctype_pool = f.lazy_ctype_pool,
693 .scratch = .initBuffer(self.scratch_buf),
694 .uavs = .empty,
695 },
696 .code_header = undefined,
697 .code = undefined,
698 .indent_counter = 0,
1267 const code: String = code: {
1268 var aw: std.Io.Writer.Allocating = .fromArrayList(gpa, &c.string_bytes);
1269 defer c.string_bytes = aw.toArrayList();
1270 const start = aw.written().len;
1271 codegen.genExports(&dg, &aw.writer, exported, export_indices) catch |err| switch (err) {
1272 error.WriteFailed => return error.OutOfMemory,
1273 error.OutOfMemory => |e| return e,
1274 };
1275 break :code .{
1276 .start = @intCast(start),
1277 .len = @intCast(aw.written().len - start),
1278 };
6991279 };
700 object.dg.fwd_decl = .fromArrayList(gpa, &f.lazy_fwd_decl);
701 object.code = .fromArrayList(gpa, &f.lazy_code);
702 defer {
703 // If this assert trips just handle the anon_decl_deps the same as
704 // `updateFunc()` does.
705 assert(object.dg.uavs.count() == 0);
706 f.lazy_ctype_pool = object.dg.ctype_pool.move();
707 f.lazy_ctype_pool.freeUnusedCapacity(gpa);
708
709 f.lazy_fwd_decl = object.dg.fwd_decl.toArrayList();
710 f.lazy_code = object.code.toArrayList();
711 self.scratch_buf = object.dg.scratch.allocatedSlice();
1280 switch (exported) {
1281 .nav => |nav| try c.exported_navs.put(gpa, nav, code),
1282 .uav => |uav| try c.exported_uavs.put(gpa, uav, code),
7121283 }
713
714 codegen.genLazyFn(&object, lazy_ctype_pool, lazy_fn) catch |err| switch (err) {
715 error.AnalysisFail => unreachable,
716 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,
717 };
7181284}
7191285
720fn flushLazyFns(
1286pub fn deleteExport(
7211287 self: *C,
722 pt: Zcu.PerThread,
723 mod: *Module,
724 f: *Flush,
725 lazy_ctype_pool: *const codegen.CType.Pool,
726 lazy_fns: codegen.LazyFnMap,
727) FlushDeclError!void {
728 const gpa = self.base.comp.gpa;
729 try f.lazy_fns.ensureUnusedCapacity(gpa, @intCast(lazy_fns.count()));
730
731 var it = lazy_fns.iterator();
732 while (it.next()) |entry| {
733 const gop = f.lazy_fns.getOrPutAssumeCapacity(entry.key_ptr.*);
734 if (gop.found_existing) continue;
735 gop.value_ptr.* = {};
736 try self.flushLazyFn(pt, mod, f, lazy_ctype_pool, entry);
1288 exported: Zcu.Exported,
1289 _: InternPool.NullTerminatedString,
1290) void {
1291 switch (exported) {
1292 .nav => |nav| _ = self.exported_navs.swapRemove(nav),
1293 .uav => |uav| _ = self.exported_uavs.swapRemove(uav),
7371294 }
7381295}
7391296
740fn flushAvBlock(
741 self: *C,
742 pt: Zcu.PerThread,
743 mod: *Module,
744 f: *Flush,
745 av_block: *const AvBlock,
746 exported_block: ?*const ExportedBlock,
747 export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),
748 extern_name: InternPool.OptionalNullTerminatedString,
749) FlushDeclError!void {
750 const gpa = self.base.comp.gpa;
751 try self.flushLazyFns(pt, mod, f, &av_block.ctype_pool, av_block.lazy_fns);
752 try f.all_buffers.ensureUnusedCapacity(gpa, 1);
753 // avoid emitting extern decls that are already exported
754 if (extern_name.unwrap()) |name| if (export_names.contains(name)) return;
755 f.appendBufAssumeCapacity(self.getString(if (exported_block) |exported|
756 exported.fwd_decl
757 else
758 av_block.fwd_decl));
759}
1297fn mergeNeededCTypes(
1298 c: *C,
1299 need_types: *std.AutoArrayHashMapUnmanaged(link.ConstPool.Index, void),
1300 need_errunion_types: *std.AutoArrayHashMapUnmanaged(link.ConstPool.Index, void),
1301 need_aligned_types: *std.AutoArrayHashMapUnmanaged(link.ConstPool.Index, u64),
1302 deps: *const CTypeDependencies,
1303) Allocator.Error!void {
1304 const gpa = c.base.comp.gpa;
7601305
761pub fn flushEmitH(zcu: *Zcu) !void {
762 const tracy = trace(@src());
763 defer tracy.end();
1306 const resolved = deps.get(c);
7641307
765 if (true) return; // emit-h is regressed
1308 try need_types.ensureUnusedCapacity(gpa, resolved.type.len + resolved.type_fwd.len);
1309 try need_errunion_types.ensureUnusedCapacity(gpa, resolved.errunion_type.len + resolved.errunion_type_fwd.len);
1310 try need_aligned_types.ensureUnusedCapacity(gpa, resolved.aligned_type_fwd.len);
7661311
767 const emit_h = zcu.emit_h orelse return;
768 const io = zcu.comp.io;
1312 for (resolved.type) |index| need_types.putAssumeCapacity(index, {});
1313 for (resolved.type_fwd) |index| need_types.putAssumeCapacity(index, {});
7691314
770 // We collect a list of buffers to write, and write them all at once with pwritev 😎
771 const num_buffers = emit_h.decl_table.count() + 1;
772 var all_buffers = try std.array_list.Managed(std.posix.iovec_const).initCapacity(zcu.gpa, num_buffers);
773 defer all_buffers.deinit();
1315 for (resolved.errunion_type) |index| need_errunion_types.putAssumeCapacity(index, {});
1316 for (resolved.errunion_type_fwd) |index| need_errunion_types.putAssumeCapacity(index, {});
7741317
775 var file_size: u64 = zig_h.len;
776 if (zig_h.len != 0) {
777 all_buffers.appendAssumeCapacity(.{
778 .base = zig_h,
779 .len = zig_h.len,
780 });
1318 for (resolved.aligned_type_fwd, resolved.aligned_type_masks) |ty_index, align_mask| {
1319 const gop = need_aligned_types.getOrPutAssumeCapacity(ty_index);
1320 if (!gop.found_existing) gop.value_ptr.* = 0;
1321 gop.value_ptr.* |= align_mask;
7811322 }
1323}
7821324
783 for (emit_h.decl_table.keys()) |decl_index| {
784 const decl_emit_h = emit_h.declPtr(decl_index);
785 const buf = decl_emit_h.fwd_decl.items;
786 if (buf.len != 0) {
787 all_buffers.appendAssumeCapacity(.{
788 .base = buf.ptr,
789 .len = buf.len,
790 });
791 file_size += buf.len;
1325fn mergeNeededUavs(
1326 zcu: *const Zcu,
1327 global: *std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
1328 new: *const std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment),
1329) Allocator.Error!void {
1330 const gpa = zcu.comp.gpa;
1331
1332 try global.ensureUnusedCapacity(gpa, new.count());
1333 for (new.keys(), new.values()) |uav_val, need_align| {
1334 const gop = global.getOrPutAssumeCapacity(uav_val);
1335 if (!gop.found_existing) gop.value_ptr.* = .none;
1336
1337 if (need_align != .none) {
1338 const cur_align = switch (gop.value_ptr.*) {
1339 .none => Value.fromInterned(uav_val).typeOf(zcu).abiAlignment(zcu),
1340 else => |a| a,
1341 };
1342 if (need_align.compareStrict(.gt, cur_align)) {
1343 gop.value_ptr.* = need_align;
1344 }
7921345 }
7931346 }
794
795 const directory = emit_h.loc.directory orelse zcu.comp.local_cache_directory;
796 const file = try directory.handle.createFile(io, emit_h.loc.basename, .{
797 // We set the end position explicitly below; by not truncating the file, we possibly
798 // make it easier on the file system by doing 1 reallocation instead of two.
799 .truncate = false,
800 });
801 defer file.close(io);
802
803 try file.setLength(io, file_size);
804 try file.pwritevAll(all_buffers.items, 0);
8051347}
8061348
807pub fn updateExports(
808 self: *C,
1349fn addCTypeDependencies(
1350 c: *C,
8091351 pt: Zcu.PerThread,
810 exported: Zcu.Exported,
811 export_indices: []const Zcu.Export.Index,
812) !void {
813 const zcu = pt.zcu;
814 const gpa = zcu.gpa;
815 const mod, const pass: codegen.DeclGen.Pass, const decl_block, const exported_block = switch (exported) {
816 .nav => |nav| .{
817 zcu.navFileScope(nav).mod.?,
818 .{ .nav = nav },
819 self.navs.getPtr(nav).?,
820 (try self.exported_navs.getOrPut(gpa, nav)).value_ptr,
821 },
822 .uav => |uav| .{
823 zcu.root_mod,
824 .{ .uav = uav },
825 self.uavs.getPtr(uav).?,
826 (try self.exported_uavs.getOrPut(gpa, uav)).value_ptr,
827 },
828 };
829 const ctype_pool = &decl_block.ctype_pool;
830 var dg: codegen.DeclGen = .{
831 .gpa = gpa,
832 .pt = pt,
833 .mod = mod,
834 .error_msg = null,
835 .pass = pass,
836 .is_naked_fn = false,
837 .expected_block = null,
838 .fwd_decl = undefined,
839 .ctype_pool = decl_block.ctype_pool,
840 .scratch = .initBuffer(self.scratch_buf),
841 .uavs = .empty,
842 };
843 dg.fwd_decl = .initOwnedSlice(gpa, self.fwd_decl_buf);
844 defer {
845 assert(dg.uavs.count() == 0);
846 ctype_pool.* = dg.ctype_pool.move();
847 ctype_pool.freeUnusedCapacity(gpa);
1352 deps: *const codegen.CType.Dependencies,
1353) Allocator.Error!CTypeDependencies {
1354 const gpa = pt.zcu.comp.gpa;
1355
1356 try c.bigint_types.ensureUnusedCapacity(gpa, deps.bigint.count());
1357 for (deps.bigint.keys()) |bigint| c.bigint_types.putAssumeCapacity(bigint, {});
1358
1359 const type_start = c.type_dependencies.items.len;
1360 const errunion_type_start = type_start + deps.type.count();
1361 const type_fwd_start = errunion_type_start + deps.errunion_type.count();
1362 const errunion_type_fwd_start = type_fwd_start + deps.type_fwd.count();
1363 const aligned_type_fwd_start = errunion_type_fwd_start + deps.errunion_type_fwd.count();
1364 try c.type_dependencies.appendNTimes(gpa, undefined, deps.type.count() +
1365 deps.errunion_type.count() +
1366 deps.type_fwd.count() +
1367 deps.errunion_type_fwd.count() +
1368 deps.aligned_type_fwd.count());
1369
1370 const align_mask_start = c.align_dependency_masks.items.len;
1371 try c.align_dependency_masks.appendSlice(gpa, deps.aligned_type_fwd.values());
1372
1373 for (deps.type.keys(), type_start..) |ty, i| {
1374 const pool_index = try c.type_pool.get(pt, .{ .c = c }, ty);
1375 c.type_dependencies.items[i] = pool_index;
1376 }
8481377
849 self.fwd_decl_buf = dg.fwd_decl.toArrayList().allocatedSlice();
850 self.scratch_buf = dg.scratch.allocatedSlice();
1378 for (deps.errunion_type.keys(), errunion_type_start..) |ty, i| {
1379 const pool_index = try c.type_pool.get(pt, .{ .c = c }, ty);
1380 c.type_dependencies.items[i] = pool_index;
8511381 }
852 codegen.genExports(&dg, exported, export_indices) catch |err| switch (err) {
853 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,
1382
1383 for (deps.type_fwd.keys(), type_fwd_start..) |ty, i| {
1384 const pool_index = try c.type_pool.get(pt, .{ .c = c }, ty);
1385 c.type_dependencies.items[i] = pool_index;
1386 }
1387
1388 for (deps.errunion_type_fwd.keys(), errunion_type_fwd_start..) |ty, i| {
1389 const pool_index = try c.type_pool.get(pt, .{ .c = c }, ty);
1390 c.type_dependencies.items[i] = pool_index;
1391 }
1392
1393 for (deps.aligned_type_fwd.keys(), aligned_type_fwd_start..) |ty, i| {
1394 const pool_index = try c.type_pool.get(pt, .{ .c = c }, ty);
1395 c.type_dependencies.items[i] = pool_index;
1396 }
1397
1398 return .{
1399 .len = @intCast(deps.type.count()),
1400 .errunion_len = @intCast(deps.errunion_type.count()),
1401 .fwd_len = @intCast(deps.type_fwd.count()),
1402 .errunion_fwd_len = @intCast(deps.errunion_type_fwd.count()),
1403 .aligned_fwd_len = @intCast(deps.aligned_type_fwd.count()),
1404 .type_start = @intCast(type_start),
1405 .align_mask_start = @intCast(align_mask_start),
8541406 };
855 exported_block.* = .{ .fwd_decl = try self.addString(dg.fwd_decl.written()) };
8561407}
8571408
858pub fn deleteExport(
859 self: *C,
860 exported: Zcu.Exported,
861 _: InternPool.NullTerminatedString,
862) void {
863 switch (exported) {
864 .nav => |nav| _ = self.exported_navs.swapRemove(nav),
865 .uav => |uav| _ = self.exported_uavs.swapRemove(uav),
1409fn updateNewUavs(c: *C, pt: Zcu.PerThread, old_uavs_len: usize) Allocator.Error!void {
1410 const gpa = pt.zcu.comp.gpa;
1411 var index = old_uavs_len;
1412 while (index < c.uavs.count()) : (index += 1) {
1413 // `new_uavs` is UAVs discovered while lowering *this* UAV.
1414 const new_uavs: []const InternPool.Index = new: {
1415 c.uavs.lockPointers();
1416 defer c.uavs.unlockPointers();
1417 const val: Value = .fromInterned(c.uavs.keys()[index]);
1418 const rendered_decl = &c.uavs.values()[index];
1419 rendered_decl.* = .init;
1420 try c.updateUav(pt, val, rendered_decl);
1421 break :new rendered_decl.need_uavs.keys();
1422 };
1423 try c.uavs.ensureUnusedCapacity(gpa, new_uavs.len);
1424 for (new_uavs) |val| {
1425 const gop = c.uavs.getOrPutAssumeCapacity(val);
1426 if (!gop.found_existing) {
1427 assert(gop.index > index);
1428 }
1429 }
8661430 }
8671431}
8681432
869fn addUavsFromCodegen(c: *C, uavs: *const std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment)) Allocator.Error!void {
870 const gpa = c.base.comp.gpa;
871 try c.uavs.ensureUnusedCapacity(gpa, uavs.count());
872 try c.aligned_uavs.ensureUnusedCapacity(gpa, uavs.count());
873 for (uavs.keys(), uavs.values()) |uav_val, uav_align| {
874 {
875 const gop = c.uavs.getOrPutAssumeCapacity(uav_val);
876 if (!gop.found_existing) gop.value_ptr.* = .{};
1433const FlushTypes = struct {
1434 c: *C,
1435 f: *Flush,
1436
1437 aligned_types: *const std.AutoArrayHashMapUnmanaged(link.ConstPool.Index, u64),
1438 aligned_type_strings: []const []const u8,
1439
1440 status: std.AutoArrayHashMapUnmanaged(link.ConstPool.Index, bool),
1441 errunion_status: std.AutoArrayHashMapUnmanaged(link.ConstPool.Index, bool),
1442 aligned_status: std.AutoArrayHashMapUnmanaged(link.ConstPool.Index, void),
1443
1444 fn processDeps(ft: *FlushTypes, deps: *const CTypeDependencies) void {
1445 const resolved = deps.get(ft.c);
1446 for (resolved.type) |pool_index| ft.doType(pool_index);
1447 for (resolved.type_fwd) |pool_index| ft.doTypeFwd(pool_index);
1448 for (resolved.errunion_type) |pool_index| ft.doErrunionType(pool_index);
1449 for (resolved.errunion_type_fwd) |pool_index| ft.doErrunionTypeFwd(pool_index);
1450 for (resolved.aligned_type_fwd) |pool_index| ft.doAlignedTypeFwd(pool_index);
1451 }
1452 fn processDepsAsFwd(ft: *FlushTypes, deps: *const CTypeDependencies) void {
1453 const resolved = deps.get(ft.c);
1454 for (resolved.type) |pool_index| ft.doTypeFwd(pool_index);
1455 for (resolved.type_fwd) |pool_index| ft.doTypeFwd(pool_index);
1456 for (resolved.errunion_type) |pool_index| ft.doErrunionTypeFwd(pool_index);
1457 for (resolved.errunion_type_fwd) |pool_index| ft.doErrunionTypeFwd(pool_index);
1458 for (resolved.aligned_type_fwd) |pool_index| ft.doAlignedTypeFwd(pool_index);
1459 }
1460
1461 fn doAlignedTypeFwd(ft: *FlushTypes, pool_index: link.ConstPool.Index) void {
1462 const c = ft.c;
1463 if (ft.aligned_status.contains(pool_index)) return;
1464 if (ft.aligned_types.getIndex(pool_index)) |i| {
1465 const rendered = &c.types.items[@intFromEnum(pool_index)];
1466 ft.processDepsAsFwd(&rendered.deps);
1467 ft.f.appendBufAssumeCapacity(ft.aligned_type_strings[i]);
8771468 }
878 if (uav_align != .none) {
879 const gop = c.aligned_uavs.getOrPutAssumeCapacity(uav_val);
880 gop.value_ptr.* = if (gop.found_existing) max: {
881 break :max gop.value_ptr.*.maxStrict(uav_align);
882 } else uav_align;
1469 ft.aligned_status.putAssumeCapacity(pool_index, {});
1470 }
1471 fn doTypeFwd(ft: *FlushTypes, pool_index: link.ConstPool.Index) void {
1472 const c = ft.c;
1473 if (ft.status.contains(pool_index)) return;
1474 const rendered = &c.types.items[@intFromEnum(pool_index)];
1475 if (rendered.fwd_decl.len > 0) {
1476 ft.f.appendBufAssumeCapacity(rendered.fwd_decl.get(c));
1477 ft.status.putAssumeCapacityNoClobber(pool_index, false);
1478 } else {
1479 ft.processDepsAsFwd(&rendered.definition_deps);
1480 const gop = ft.status.getOrPutAssumeCapacity(pool_index);
1481 if (!gop.found_existing) {
1482 gop.value_ptr.* = false;
1483 ft.f.appendBufAssumeCapacity(rendered.definition.get(c));
1484 }
8831485 }
8841486 }
885}
1487 fn doType(ft: *FlushTypes, pool_index: link.ConstPool.Index) void {
1488 const c = ft.c;
1489 if (ft.status.get(pool_index)) |completed| {
1490 if (completed) return;
1491 }
1492 const rendered = &c.types.items[@intFromEnum(pool_index)];
1493 ft.processDeps(&rendered.definition_deps);
1494 if (rendered.fwd_decl.len == 0 and ft.status.contains(pool_index)) {
1495 // `doTypeFwd` already rendered the defintion, we just had to complete the type by
1496 // fully resolving its dependencies.
1497 } else if (rendered.definition.len > 0) {
1498 ft.f.appendBufAssumeCapacity(rendered.definition.get(c));
1499 } else if (!ft.status.contains(pool_index)) {
1500 // The type will never be completed, but it must be forward declared to avoid it being
1501 // declared in the wrong scope.
1502 ft.f.appendBufAssumeCapacity(rendered.fwd_decl.get(c));
1503 }
1504 ft.status.putAssumeCapacity(pool_index, true);
1505 }
1506 fn doErrunionTypeFwd(ft: *FlushTypes, pool_index: link.ConstPool.Index) void {
1507 const c = ft.c;
1508 const gop = ft.errunion_status.getOrPutAssumeCapacity(pool_index);
1509 if (gop.found_existing) return;
1510 const rendered = &c.types.items[@intFromEnum(pool_index)];
1511 ft.f.appendBufAssumeCapacity(rendered.errunion_fwd_decl.get(c));
1512 gop.value_ptr.* = false;
1513 }
1514 fn doErrunionType(ft: *FlushTypes, pool_index: link.ConstPool.Index) void {
1515 const c = ft.c;
1516 if (ft.errunion_status.get(pool_index)) |completed| {
1517 if (completed) return;
1518 }
1519 const rendered = &c.types.items[@intFromEnum(pool_index)];
1520 ft.processDeps(&rendered.deps);
1521 if (rendered.errunion_definition.len > 0) {
1522 ft.f.appendBufAssumeCapacity(rendered.errunion_definition.get(c));
1523 } else {
1524 // The error union type will never be completed, but forward declare it to avoid the
1525 // type being first declared in a different scope.
1526 ft.f.appendBufAssumeCapacity(rendered.errunion_fwd_decl.get(c));
1527 }
1528 ft.errunion_status.putAssumeCapacity(pool_index, true);
1529 }
1530};
src/link/Coff.zig+1-1
......@@ -1552,7 +1552,7 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
15521552 const sec_si = try coff.navSection(zcu, nav.status.fully_resolved);
15531553 try coff.nodes.ensureUnusedCapacity(gpa, 1);
15541554 const ni = try coff.mf.addLastChildNode(gpa, sec_si.node(coff), .{
1555 .alignment = pt.navAlignment(nav_index).toStdMem(),
1555 .alignment = zcu.navAlignment(nav_index).toStdMem(),
15561556 .moved = true,
15571557 });
15581558 coff.nodes.appendAssumeCapacity(.{ .nav = nmi });
src/link/ConstPool.zig created+288
......@@ -0,0 +1,288 @@
1/// Helper type for debug information implementations (such as `link.Dwarf`) to help them emit
2/// information about comptime-known values (constants), including types.
3///
4/// Every constant with associated debug information is assigned an `Index` by calling `get`. The
5/// pool will track which container types do and do not have a resolved layout, as well as which
6/// constants in the pool depend on which types, and call into the implementation to emit debug
7/// information for a constant only when all information is available.
8///
9/// Indices into the pool are dense, and constants are never removed from the pool, so the debug
10/// info implementation can store information for each one with a simple `ArrayList`.
11///
12/// To use `ConstPool`, the debug info implementation is required to:
13/// * forward `updateContainerType` calls to its `ConstPool`
14/// * expose some callback functions---see functions in `User`
15/// * ensure that any `get` call is eventually followed by a `flushPending` call
16const ConstPool = @This();
17
18values: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
19pending: std.ArrayList(Index),
20complete_containers: std.AutoArrayHashMapUnmanaged(InternPool.Index, void),
21container_deps: std.AutoArrayHashMapUnmanaged(InternPool.Index, ContainerDepEntry.Index),
22container_dep_entries: std.ArrayList(ContainerDepEntry),
23
24pub const empty: ConstPool = .{
25 .values = .empty,
26 .pending = .empty,
27 .complete_containers = .empty,
28 .container_deps = .empty,
29 .container_dep_entries = .empty,
30};
31
32pub fn deinit(pool: *ConstPool, gpa: Allocator) void {
33 pool.values.deinit(gpa);
34 pool.pending.deinit(gpa);
35 pool.complete_containers.deinit(gpa);
36 pool.container_deps.deinit(gpa);
37 pool.container_dep_entries.deinit(gpa);
38}
39
40pub const Index = enum(u32) {
41 _,
42 pub fn val(i: Index, pool: *const ConstPool) InternPool.Index {
43 return pool.values.keys()[@intFromEnum(i)];
44 }
45};
46
47pub const User = union(enum) {
48 dwarf: *@import("Dwarf.zig"),
49 c: *@import("C.zig"),
50 llvm: @import("../codegen/llvm.zig").Object.Ptr,
51
52 /// Inform the debug info implementation that the new constant `val` was added to the pool at
53 /// the given index (which equals the current pool length) due to a `get` call. It is guaranteed
54 /// that there will eventually be a call to either `updateConst` or `updateConstIncomplete`
55 /// following the `addConst` call, to actually populate the constant's debug info.
56 fn addConst(
57 user: User,
58 pt: Zcu.PerThread,
59 index: Index,
60 val: InternPool.Index,
61 ) Allocator.Error!void {
62 switch (user) {
63 inline else => |impl| return impl.addConst(pt, index, val),
64 }
65 }
66
67 /// Tell the debug info implementation to emit information for the constant `val`, which is in
68 /// the pool at the given index. `val` is "complete", which means:
69 /// * If it is a type, its layout is known.
70 /// * Otherwise, the layout of its type is known.
71 fn updateConst(
72 user: User,
73 pt: Zcu.PerThread,
74 index: Index,
75 val: InternPool.Index,
76 ) Allocator.Error!void {
77 switch (user) {
78 inline else => |impl| return impl.updateConst(pt, index, val),
79 }
80 }
81
82 /// Tell the debug info implementation to emit information for the constant `val`, which is in
83 /// the pool at the given index. `val` is "incomplete", meaning the implementation cannot emit
84 /// full information for it (for instance, perhaps it is a struct type which was never actually
85 /// initialized so never had its layout resolved). Instead, the implementation must emit some
86 /// form of placeholder entry representing an incomplete/unknown constant.
87 fn updateConstIncomplete(
88 user: User,
89 pt: Zcu.PerThread,
90 index: Index,
91 val: InternPool.Index,
92 ) Allocator.Error!void {
93 switch (user) {
94 inline else => |impl| return impl.updateConstIncomplete(pt, index, val),
95 }
96 }
97};
98
99const ContainerDepEntry = extern struct {
100 next: ContainerDepEntry.Index.Optional,
101 depender: ConstPool.Index,
102 const Index = enum(u32) {
103 _,
104 const Optional = enum(u32) {
105 none = std.math.maxInt(u32),
106 _,
107 fn unwrap(o: Optional) ?ContainerDepEntry.Index {
108 return switch (o) {
109 .none => null,
110 else => @enumFromInt(@intFromEnum(o)),
111 };
112 }
113 };
114 fn toOptional(i: ContainerDepEntry.Index) Optional {
115 return @enumFromInt(@intFromEnum(i));
116 }
117 fn ptr(i: ContainerDepEntry.Index, pool: *ConstPool) *ContainerDepEntry {
118 return &pool.container_dep_entries.items[@intFromEnum(i)];
119 }
120 };
121};
122
123/// Calls to `link.File.updateContainerType` must be forwarded to this function so that the debug
124/// constant pool has up-to-date information about the resolution status of types.
125pub fn updateContainerType(
126 pool: *ConstPool,
127 pt: Zcu.PerThread,
128 user: User,
129 container_ty: InternPool.Index,
130 success: bool,
131) Allocator.Error!void {
132 if (success) {
133 const gpa = pt.zcu.comp.gpa;
134 try pool.complete_containers.put(gpa, container_ty, {});
135 } else {
136 _ = pool.complete_containers.fetchSwapRemove(container_ty);
137 }
138 var opt_dep = pool.container_deps.get(container_ty);
139 while (opt_dep) |dep| : (opt_dep = dep.ptr(pool).next.unwrap()) {
140 try pool.update(pt, user, dep.ptr(pool).depender);
141 }
142}
143
144/// After this is called, there may be a constant for which debug information (complete or not) has
145/// not yet been emitted, so the user must call `flushPending` at some point after this call.
146pub fn get(pool: *ConstPool, pt: Zcu.PerThread, user: User, val: InternPool.Index) Allocator.Error!ConstPool.Index {
147 const zcu = pt.zcu;
148 const ip = &zcu.intern_pool;
149 const gpa = zcu.comp.gpa;
150 const gop = try pool.values.getOrPut(gpa, val);
151 const index: ConstPool.Index = @enumFromInt(gop.index);
152 if (!gop.found_existing) {
153 const ty: Type = switch (ip.typeOf(val)) {
154 .type_type => if (ip.isUndef(val)) .type else .fromInterned(val),
155 else => |ty| .fromInterned(ty),
156 };
157 try pool.registerTypeDeps(index, ty, zcu);
158 try pool.pending.append(gpa, index);
159 try user.addConst(pt, index, val);
160 }
161 return index;
162}
163pub fn flushPending(pool: *ConstPool, pt: Zcu.PerThread, user: User) Allocator.Error!void {
164 while (pool.pending.pop()) |pending_ty| {
165 try pool.update(pt, user, pending_ty);
166 }
167}
168
169fn update(pool: *ConstPool, pt: Zcu.PerThread, user: User, index: ConstPool.Index) Allocator.Error!void {
170 const zcu = pt.zcu;
171 const ip = &zcu.intern_pool;
172 const val = index.val(pool);
173 const ty: Type = switch (ip.typeOf(val)) {
174 .type_type => if (ip.isUndef(val)) .type else .fromInterned(val),
175 else => |ty| .fromInterned(ty),
176 };
177 if (pool.checkType(ty, zcu)) {
178 try user.updateConst(pt, index, val);
179 } else {
180 try user.updateConstIncomplete(pt, index, val);
181 }
182}
183fn checkType(pool: *const ConstPool, ty: Type, zcu: *const Zcu) bool {
184 if (ty.isGenericPoison()) return true;
185 return switch (ty.zigTypeTag(zcu)) {
186 .type,
187 .void,
188 .bool,
189 .noreturn,
190 .int,
191 .float,
192 .pointer,
193 .comptime_float,
194 .comptime_int,
195 .undefined,
196 .null,
197 .error_set,
198 .@"opaque",
199 .frame,
200 .@"anyframe",
201 .enum_literal,
202 => true,
203
204 .array, .vector => pool.checkType(ty.childType(zcu), zcu),
205 .optional => pool.checkType(ty.optionalChild(zcu), zcu),
206 .error_union => pool.checkType(ty.errorUnionPayload(zcu), zcu),
207 .@"fn" => {
208 const ip = &zcu.intern_pool;
209 const func = ip.indexToKey(ty.toIntern()).func_type;
210 for (func.param_types.get(ip)) |param_ty_ip| {
211 if (!pool.checkType(.fromInterned(param_ty_ip), zcu)) return false;
212 }
213 return pool.checkType(.fromInterned(func.return_type), zcu);
214 },
215 .@"struct" => if (ty.isTuple(zcu)) {
216 for (0..ty.structFieldCount(zcu)) |field_index| {
217 if (!pool.checkType(ty.fieldType(field_index, zcu), zcu)) return false;
218 }
219 return true;
220 } else {
221 return pool.complete_containers.contains(ty.toIntern());
222 },
223 .@"union", .@"enum" => {
224 return pool.complete_containers.contains(ty.toIntern());
225 },
226 };
227}
228fn registerTypeDeps(pool: *ConstPool, root: Index, ty: Type, zcu: *const Zcu) Allocator.Error!void {
229 if (ty.isGenericPoison()) return;
230 switch (ty.zigTypeTag(zcu)) {
231 .type,
232 .void,
233 .bool,
234 .noreturn,
235 .int,
236 .float,
237 .pointer,
238 .comptime_float,
239 .comptime_int,
240 .undefined,
241 .null,
242 .error_set,
243 .@"opaque",
244 .frame,
245 .@"anyframe",
246 .enum_literal,
247 => {},
248
249 .array, .vector => try pool.registerTypeDeps(root, ty.childType(zcu), zcu),
250 .optional => try pool.registerTypeDeps(root, ty.optionalChild(zcu), zcu),
251 .error_union => try pool.registerTypeDeps(root, ty.errorUnionPayload(zcu), zcu),
252 .@"fn" => {
253 const ip = &zcu.intern_pool;
254 const func = ip.indexToKey(ty.toIntern()).func_type;
255 for (func.param_types.get(ip)) |param_ty_ip| {
256 try pool.registerTypeDeps(root, .fromInterned(param_ty_ip), zcu);
257 }
258 try pool.registerTypeDeps(root, .fromInterned(func.return_type), zcu);
259 },
260 .@"struct", .@"union", .@"enum" => if (ty.isTuple(zcu)) {
261 for (0..ty.structFieldCount(zcu)) |field_index| {
262 try pool.registerTypeDeps(root, ty.fieldType(field_index, zcu), zcu);
263 }
264 } else {
265 // `ty` is a container; register the dependency.
266
267 const gpa = zcu.comp.gpa;
268 try pool.container_deps.ensureUnusedCapacity(gpa, 1);
269 try pool.container_dep_entries.ensureUnusedCapacity(gpa, 1);
270 errdefer comptime unreachable;
271
272 const gop = pool.container_deps.getOrPutAssumeCapacity(ty.toIntern());
273 const entry: ContainerDepEntry.Index = @enumFromInt(pool.container_dep_entries.items.len);
274 pool.container_dep_entries.appendAssumeCapacity(.{
275 .next = if (gop.found_existing) gop.value_ptr.toOptional() else .none,
276 .depender = root,
277 });
278 gop.value_ptr.* = entry;
279 },
280 }
281}
282
283const std = @import("std");
284const Allocator = std.mem.Allocator;
285
286const InternPool = @import("../InternPool.zig");
287const Type = @import("../Type.zig");
288const Zcu = @import("../Zcu.zig");
src/link/Dwarf.zig+828-918
......@@ -25,9 +25,11 @@ format: DW.Format,
2525endian: std.builtin.Endian,
2626address_size: AddressSize,
2727
28const_pool: link.ConstPool,
29
2830mods: std.AutoArrayHashMapUnmanaged(*Module, ModInfo),
29types: std.AutoArrayHashMapUnmanaged(InternPool.Index, Entry.Index),
30values: std.AutoArrayHashMapUnmanaged(InternPool.Index, Entry.Index),
31/// Indices are `link.ConstPool.Index`.
32values: std.ArrayList(struct { Unit.Index, Entry.Index }),
3133navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, Entry.Index),
3234decls: std.AutoArrayHashMapUnmanaged(InternPool.TrackedInst.Index, Entry.Index),
3335
......@@ -1034,15 +1036,14 @@ const Entry = struct {
10341036 });
10351037 const zcu = dwarf.bin_file.comp.zcu.?;
10361038 const ip = &zcu.intern_pool;
1037 for (dwarf.types.keys(), dwarf.types.values()) |ty, other_entry| {
1038 const ty_unit: Unit.Index = if (Type.fromInterned(ty).typeDeclInst(zcu)) |inst_index|
1039 dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod.?) catch unreachable
1040 else
1041 .main;
1042 if (sec.getUnit(ty_unit) == unit and unit.getEntry(other_entry) == entry)
1043 log.err("missing Type({f}({d}))", .{
1044 Type.fromInterned(ty).fmt(.{ .tid = .main, .zcu = zcu }),
1045 @intFromEnum(ty),
1039 for (0.., dwarf.values.items) |raw_index, unit_and_entry| {
1040 const index: link.ConstPool.Index = @enumFromInt(raw_index);
1041 const val = index.val(&dwarf.const_pool);
1042 const val_unit, const val_entry = unit_and_entry;
1043 if (sec.getUnit(val_unit) == unit and unit.getEntry(val_entry) == entry)
1044 log.err("missing Value({f}({d}))", .{
1045 Value.fromInterned(val).fmtValue(.{ .tid = .main, .zcu = zcu }),
1046 @intFromEnum(val),
10461047 });
10471048 }
10481049 for (dwarf.navs.keys(), dwarf.navs.values()) |nav, other_entry| {
......@@ -1520,7 +1521,6 @@ pub const WipNav = struct {
15201521 debug_info: Writer.Allocating,
15211522 debug_line: Writer.Allocating,
15221523 debug_loclists: Writer.Allocating,
1523 pending_lazy: PendingLazy,
15241524
15251525 pub fn deinit(wip_nav: *WipNav) void {
15261526 const gpa = wip_nav.dwarf.gpa;
......@@ -1529,8 +1529,6 @@ pub const WipNav = struct {
15291529 wip_nav.debug_info.deinit();
15301530 wip_nav.debug_line.deinit();
15311531 wip_nav.debug_loclists.deinit();
1532 wip_nav.pending_lazy.types.deinit(gpa);
1533 wip_nav.pending_lazy.values.deinit(gpa);
15341532 }
15351533
15361534 pub fn genDebugFrame(wip_nav: *WipNav, loc: u32, cfa: Cfa) UpdateError!void {
......@@ -1603,7 +1601,7 @@ pub const WipNav = struct {
16031601 const zcu = pt.zcu;
16041602 const ty = val.typeOf(zcu);
16051603 const has_runtime_bits = ty.hasRuntimeBits(zcu);
1606 const has_comptime_state = ty.comptimeOnly(zcu) and try ty.onePossibleValue(pt) == null;
1604 const has_comptime_state = ty.comptimeOnly(zcu);
16071605 try wip_nav.abbrevCode(if (has_runtime_bits and has_comptime_state) switch (tag) {
16081606 .comptime_arg => if (opt_name) |_| .comptime_arg_runtime_bits_comptime_state else .unnamed_comptime_arg_runtime_bits_comptime_state,
16091607 .local_const => if (opt_name) |_| .local_const_runtime_bits_comptime_state else unreachable,
......@@ -1945,6 +1943,12 @@ pub const WipNav = struct {
19451943 try wip_nav.infoSectionOffset(.debug_str, StringSection.unit, try wip_nav.dwarf.debug_str.addString(wip_nav.dwarf, str), 0);
19461944 }
19471945
1946 fn strpFmt(wip_nav: *WipNav, comptime fmt: []const u8, args: anytype) (UpdateError || Writer.Error)!void {
1947 const str = try std.fmt.allocPrint(wip_nav.dwarf.gpa, fmt, args);
1948 defer wip_nav.dwarf.gpa.free(str);
1949 return wip_nav.strp(str);
1950 }
1951
19481952 const ExprLocCounter = struct {
19491953 dw: Writer.Discarding,
19501954 section_offset_bytes: u32,
......@@ -2054,74 +2058,16 @@ pub const WipNav = struct {
20542058 try dfw.splatByteAll(0, @intFromEnum(wip_nav.dwarf.address_size));
20552059 }
20562060
2057 fn getNavEntry(
2058 wip_nav: *WipNav,
2059 nav_index: InternPool.Nav.Index,
2060 ) UpdateError!struct { Unit.Index, Entry.Index } {
2061 const zcu = wip_nav.pt.zcu;
2062 const ip = &zcu.intern_pool;
2063 const nav = ip.getNav(nav_index);
2064 const unit = try wip_nav.dwarf.getUnit(zcu.fileByIndex(nav.srcInst(ip).resolveFile(ip)).mod.?);
2065 const gop = try wip_nav.dwarf.navs.getOrPut(wip_nav.dwarf.gpa, nav_index);
2066 if (gop.found_existing) return .{ unit, gop.value_ptr.* };
2067 const entry = try wip_nav.dwarf.addCommonEntry(unit);
2068 gop.value_ptr.* = entry;
2069 return .{ unit, entry };
2070 }
2071
20722061 fn refNav(
20732062 wip_nav: *WipNav,
20742063 nav_index: InternPool.Nav.Index,
20752064 ) (UpdateError || Writer.Error)!void {
2076 const unit, const entry = try wip_nav.getNavEntry(nav_index);
2065 const unit, const entry = try wip_nav.dwarf.getNavEntry(nav_index);
20772066 try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);
20782067 }
20792068
2080 fn getTypeEntry(wip_nav: *WipNav, ty: Type) UpdateError!struct { Unit.Index, Entry.Index } {
2081 const zcu = wip_nav.pt.zcu;
2082 const ip = &zcu.intern_pool;
2083 const maybe_inst_index = ty.typeDeclInst(zcu);
2084 const unit = if (maybe_inst_index) |inst_index| switch (switch (ip.indexToKey(ty.toIntern())) {
2085 else => unreachable,
2086 .struct_type => ip.loadStructType(ty.toIntern()).name_nav,
2087 .union_type => ip.loadUnionType(ty.toIntern()).name_nav,
2088 .enum_type => ip.loadEnumType(ty.toIntern()).name_nav,
2089 .opaque_type => ip.loadOpaqueType(ty.toIntern()).name_nav,
2090 }) {
2091 .none => try wip_nav.dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod.?),
2092 else => |name_nav| return wip_nav.getNavEntry(name_nav.unwrap().?),
2093 } else .main;
2094 const gop = try wip_nav.dwarf.types.getOrPut(wip_nav.dwarf.gpa, ty.toIntern());
2095 if (gop.found_existing) return .{ unit, gop.value_ptr.* };
2096 const entry = try wip_nav.dwarf.addCommonEntry(unit);
2097 gop.value_ptr.* = entry;
2098 if (maybe_inst_index == null) try wip_nav.pending_lazy.types.append(wip_nav.dwarf.gpa, ty.toIntern());
2099 return .{ unit, entry };
2100 }
2101
21022069 fn refType(wip_nav: *WipNav, ty: Type) (UpdateError || Writer.Error)!void {
2103 const unit, const entry = try wip_nav.getTypeEntry(ty);
2104 try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);
2105 }
2106
2107 fn getValueEntry(wip_nav: *WipNav, value: Value) UpdateError!struct { Unit.Index, Entry.Index } {
2108 const zcu = wip_nav.pt.zcu;
2109 const ip = &zcu.intern_pool;
2110 const ty = value.typeOf(zcu);
2111 if (std.debug.runtime_safety) assert(ty.comptimeOnly(zcu) and try ty.onePossibleValue(wip_nav.pt) == null);
2112 if (ty.toIntern() == .type_type) return wip_nav.getTypeEntry(value.toType());
2113 if (ip.isFunctionType(ty.toIntern()) and !value.isUndef(zcu)) return wip_nav.getNavEntry(switch (ip.indexToKey(value.toIntern())) {
2114 else => unreachable,
2115 .func => |func| func.owner_nav,
2116 .@"extern" => |@"extern"| @"extern".owner_nav,
2117 });
2118 const gop = try wip_nav.dwarf.values.getOrPut(wip_nav.dwarf.gpa, value.toIntern());
2119 const unit: Unit.Index = .main;
2120 if (gop.found_existing) return .{ unit, gop.value_ptr.* };
2121 const entry = try wip_nav.dwarf.addCommonEntry(unit);
2122 gop.value_ptr.* = entry;
2123 try wip_nav.pending_lazy.values.append(wip_nav.dwarf.gpa, value.toIntern());
2124 return .{ unit, entry };
2070 return wip_nav.refValue(ty.toValue());
21252071 }
21262072
21272073 fn refValue(wip_nav: *WipNav, value: Value) (UpdateError || Writer.Error)!void {
......@@ -2129,6 +2075,15 @@ pub const WipNav = struct {
21292075 try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);
21302076 }
21312077
2078 fn getValueEntry(wip_nav: *WipNav, value: Value) UpdateError!struct { Unit.Index, Entry.Index } {
2079 if (value.typeOf(wip_nav.pt.zcu).toIntern() != .type_type) {
2080 assert(value.typeOf(wip_nav.pt.zcu).comptimeOnly(wip_nav.pt.zcu));
2081 }
2082 const dwarf = wip_nav.dwarf;
2083 const index = try dwarf.const_pool.get(wip_nav.pt, .{ .dwarf = dwarf }, value.toIntern());
2084 return dwarf.values.items[@intFromEnum(index)];
2085 }
2086
21322087 fn refForward(wip_nav: *WipNav) (Allocator.Error || Writer.Error)!u32 {
21332088 const dwarf = wip_nav.dwarf;
21342089 const diw = &wip_nav.debug_info.writer;
......@@ -2156,7 +2111,7 @@ pub const WipNav = struct {
21562111 ) (UpdateError || Writer.Error)!void {
21572112 const ty = val.typeOf(wip_nav.pt.zcu);
21582113 const diw = &wip_nav.debug_info.writer;
2159 const size = if (ty.hasRuntimeBits(wip_nav.pt.zcu)) ty.abiSize(wip_nav.pt.zcu) else 0;
2114 const size = ty.abiSize(wip_nav.pt.zcu);
21602115 try diw.writeUleb128(size);
21612116 if (size == 0) return;
21622117 const old_end = wip_nav.debug_info.writer.end;
......@@ -2243,8 +2198,8 @@ pub const WipNav = struct {
22432198 const zcu = wip_nav.pt.zcu;
22442199 const ip = &zcu.intern_pool;
22452200 var big_int_space: Value.BigIntSpace = undefined;
2246 try wip_nav.bigIntConstValue(abbrev_code, .fromInterned(loaded_enum.tag_ty), if (loaded_enum.values.len > 0)
2247 Value.fromInterned(loaded_enum.values.get(ip)[field_index]).toBigInt(&big_int_space, zcu)
2201 try wip_nav.bigIntConstValue(abbrev_code, .fromInterned(loaded_enum.int_tag_type), if (loaded_enum.field_values.len > 0)
2202 Value.fromInterned(loaded_enum.field_values.get(ip)[field_index]).toBigInt(&big_int_space, zcu)
22482203 else
22492204 std.math.big.int.Mutable.init(&big_int_space.limbs, field_index).toConst());
22502205 }
......@@ -2297,6 +2252,12 @@ pub const WipNav = struct {
22972252 .generic_decl_const,
22982253 .generic_decl_func,
22992254 => true,
2255
2256 // This comes from a decl which was previously generated as an incomplete value
2257 // (I think that must mean either a function or an extern which previously had
2258 // incomplete types).
2259 .undefined_comptime_value => false,
2260
23002261 else => |t| std.debug.panic("bad decl abbrev code: {t}", .{t}),
23012262 };
23022263 if (parent_type.getCaptures(zcu).len == 0) {
......@@ -2331,22 +2292,6 @@ pub const WipNav = struct {
23312292 try wip_nav.refType(parent_type.?);
23322293 try wip_nav.infoSectionOffset(.debug_info, wip_nav.unit, generic_decl_entry, 0);
23332294 }
2334
2335 const PendingLazy = struct {
2336 types: std.ArrayList(InternPool.Index),
2337 values: std.ArrayList(InternPool.Index),
2338
2339 const empty: PendingLazy = .{ .types = .empty, .values = .empty };
2340 };
2341
2342 fn updateLazy(wip_nav: *WipNav, src_loc: Zcu.LazySrcLoc) (UpdateError || Writer.Error)!void {
2343 while (true) if (wip_nav.pending_lazy.types.pop()) |pending_ty|
2344 try wip_nav.dwarf.updateLazyType(wip_nav.pt, src_loc, pending_ty, &wip_nav.pending_lazy)
2345 else if (wip_nav.pending_lazy.values.pop()) |pending_val|
2346 try wip_nav.dwarf.updateLazyValue(wip_nav.pt, src_loc, pending_val, &wip_nav.pending_lazy)
2347 else
2348 break;
2349 }
23502295};
23512296
23522297/// When allocating, the ideal_capacity is calculated by
......@@ -2372,8 +2317,9 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {
23722317 },
23732318 .endian = target.cpu.arch.endian(),
23742319
2320 .const_pool = .empty,
2321
23752322 .mods = .empty,
2376 .types = .empty,
23772323 .values = .empty,
23782324 .navs = .empty,
23792325 .decls = .empty,
......@@ -2544,9 +2490,9 @@ pub fn initMetadata(dwarf: *Dwarf) UpdateError!void {
25442490
25452491pub fn deinit(dwarf: *Dwarf) void {
25462492 const gpa = dwarf.gpa;
2493 dwarf.const_pool.deinit(gpa);
25472494 for (dwarf.mods.values()) |*mod_info| mod_info.deinit(gpa);
25482495 dwarf.mods.deinit(gpa);
2549 dwarf.types.deinit(gpa);
25502496 dwarf.values.deinit(gpa);
25512497 dwarf.navs.deinit(gpa);
25522498 dwarf.decls.deinit(gpa);
......@@ -2562,6 +2508,21 @@ pub fn deinit(dwarf: *Dwarf) void {
25622508 dwarf.* = undefined;
25632509}
25642510
2511fn getNavEntry(
2512 dwarf: *Dwarf,
2513 nav_index: InternPool.Nav.Index,
2514) UpdateError!struct { Unit.Index, Entry.Index } {
2515 const zcu = dwarf.bin_file.comp.zcu.?;
2516 const ip = &zcu.intern_pool;
2517 const nav = ip.getNav(nav_index);
2518 const unit = try dwarf.getUnit(zcu.fileByIndex(nav.srcInst(ip).resolveFile(ip)).mod.?);
2519 const gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);
2520 if (gop.found_existing) return .{ unit, gop.value_ptr.* };
2521 const entry = try dwarf.addCommonEntry(unit);
2522 gop.value_ptr.* = entry;
2523 return .{ unit, entry };
2524}
2525
25652526fn getUnit(dwarf: *Dwarf, mod: *Module) !Unit.Index {
25662527 const mod_gop = try dwarf.mods.getOrPut(dwarf.gpa, mod);
25672528 const unit: Unit.Index = @enumFromInt(mod_gop.index);
......@@ -2622,6 +2583,10 @@ fn getModInfo(dwarf: *Dwarf, unit: Unit.Index) *ModInfo {
26222583 return &dwarf.mods.values()[@intFromEnum(unit)];
26232584}
26242585
2586fn getUnitModule(dwarf: *Dwarf, unit: Unit.Index) *Module {
2587 return dwarf.mods.keys()[@intFromEnum(unit)];
2588}
2589
26252590pub fn initWipNav(
26262591 dwarf: *Dwarf,
26272592 pt: Zcu.PerThread,
......@@ -2683,7 +2648,6 @@ fn initWipNavInner(
26832648 .debug_info = .init(dwarf.gpa),
26842649 .debug_line = .init(dwarf.gpa),
26852650 .debug_loclists = .init(dwarf.gpa),
2686 .pending_lazy = .empty,
26872651 };
26882652 errdefer wip_nav.deinit();
26892653
......@@ -2705,7 +2669,7 @@ fn initWipNavInner(
27052669 try wip_nav.refType(.fromInterned(if (maybe_func_type) |func_type| func_type.return_type else @"extern".ty));
27062670 if (maybe_func_type) |func_type| {
27072671 try wip_nav.infoAddrSym(sym_index, 0);
2708 try diw.writeByte(@intFromBool(ip.isNoReturn(func_type.return_type)));
2672 try diw.writeByte(@intFromBool(Type.fromInterned(func_type.return_type).isNoReturn(zcu)));
27092673 if (func_type.param_types.len > 0 or func_type.is_var_args) {
27102674 for (func_type.param_types.get(ip)) |param_type| {
27112675 try wip_nav.abbrevCode(.extern_param);
......@@ -2733,7 +2697,7 @@ fn initWipNavInner(
27332697 try wip_nav.strp(@"extern".name.toSlice(ip));
27342698 try wip_nav.refType(.fromInterned(func_type.return_type));
27352699 try wip_nav.infoAddrSym(sym_index, 0);
2736 try diw.writeByte(@intFromBool(ip.isNoReturn(func_type.return_type)));
2700 try diw.writeByte(@intFromBool(Type.fromInterned(func_type.return_type).isNoReturn(zcu)));
27372701 if (func_type.param_types.len > 0 or func_type.is_var_args) {
27382702 for (func_type.param_types.get(ip)) |param_type| {
27392703 try wip_nav.abbrevCode(.extern_param);
......@@ -2818,7 +2782,7 @@ fn initWipNavInner(
28182782 else => |a| a.maxStrict(target_info.minFunctionAlignment(target)),
28192783 }.toByteUnits().?);
28202784 try diw.writeByte(@intFromBool(decl.linkage != .normal));
2821 try diw.writeByte(@intFromBool(ip.isNoReturn(func_type.return_type)));
2785 try diw.writeByte(@intFromBool(Type.fromInterned(func_type.return_type).isNoReturn(zcu)));
28222786
28232787 const dlw = &wip_nav.debug_line.writer;
28242788 try dlw.writeByte(DW.LNS.extended_op);
......@@ -3050,7 +3014,7 @@ fn finishWipNavWriterError(
30503014 }
30513015 try dwarf.debug_loclists.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_loclists.written());
30523016
3053 try wip_nav.updateLazy(zcu.navSrcLoc(nav_index));
3017 try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf });
30543018}
30553019
30563020pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error{ OutOfMemory, CodegenFail }!void {
......@@ -3087,34 +3051,12 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
30873051 return;
30883052 }
30893053
3090 var wip_nav: WipNav = .{
3091 .dwarf = dwarf,
3092 .pt = pt,
3093 .unit = try dwarf.getUnit(file.mod.?),
3094 .entry = undefined,
3095 .any_children = false,
3096 .func = .none,
3097 .func_sym_index = undefined,
3098 .func_high_pc = undefined,
3099 .blocks = undefined,
3100 .cfi = undefined,
3101 .debug_frame = .init(dwarf.gpa),
3102 .debug_info = .init(dwarf.gpa),
3103 .debug_line = .init(dwarf.gpa),
3104 .debug_loclists = .init(dwarf.gpa),
3105 .pending_lazy = .empty,
3106 };
3107 defer wip_nav.deinit();
3108
3109 const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);
3110 errdefer _ = if (!nav_gop.found_existing) dwarf.navs.pop();
3111
31123054 const tag: union(enum) {
3113 done,
3114 decl_alias,
3115 decl_var,
3116 decl_const,
3117 decl_func_alias: InternPool.Nav.Index,
3055 alias,
3056 @"var",
3057 @"const",
3058 func: Type,
3059 func_alias: InternPool.Nav.Index,
31183060 } = switch (ip.indexToKey(nav_val.toIntern())) {
31193061 .int_type,
31203062 .ptr_type,
......@@ -3128,242 +3070,49 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
31283070 .func_type,
31293071 .error_set_type,
31303072 .inferred_error_set_type,
3131 => .decl_alias,
3073 => .alias,
3074
31323075 .struct_type => tag: {
31333076 const loaded_struct = ip.loadStructType(nav_val.toIntern());
3134 if (loaded_struct.zir_index.resolveFile(ip) != inst_info.file) break :tag .decl_alias;
3135
3136 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
3137 if (type_gop.found_existing) {
3138 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;
3139 assert(!nav_gop.found_existing);
3140 nav_gop.value_ptr.* = type_gop.value_ptr.*;
3141 } else {
3142 if (nav_gop.found_existing)
3143 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
3144 else
3145 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
3146 type_gop.value_ptr.* = nav_gop.value_ptr.*;
3147 }
3148 wip_nav.entry = nav_gop.value_ptr.*;
3149
3150 const diw = &wip_nav.debug_info.writer;
3151
3152 switch (loaded_struct.layout) {
3153 .auto, .@"extern" => {
3154 try wip_nav.declCommon(if (loaded_struct.field_types.len == 0) .{
3155 .decl = .decl_namespace_struct,
3156 .generic_decl = .generic_decl_const,
3157 .decl_instance = .decl_instance_namespace_struct,
3158 } else .{
3159 .decl = .decl_struct,
3160 .generic_decl = .generic_decl_const,
3161 .decl_instance = .decl_instance_struct,
3162 }, &nav, inst_info.file, &decl);
3163 if (loaded_struct.field_types.len == 0) try diw.writeByte(@intFromBool(false)) else {
3164 try diw.writeUleb128(nav_val.toType().abiSize(zcu));
3165 try diw.writeUleb128(nav_val.toType().abiAlignment(zcu).toByteUnits().?);
3166 for (0..loaded_struct.field_types.len) |field_index| {
3167 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
3168 const field_init = loaded_struct.fieldInit(ip, field_index);
3169 assert(!(is_comptime and field_init == .none));
3170 const field_type: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
3171 const has_runtime_bits, const has_comptime_state = switch (field_init) {
3172 .none => .{ false, false },
3173 else => .{
3174 field_type.hasRuntimeBits(zcu),
3175 field_type.comptimeOnly(zcu) and try field_type.onePossibleValue(pt) == null,
3176 },
3177 };
3178 try wip_nav.abbrevCode(if (is_comptime)
3179 if (has_comptime_state)
3180 .struct_field_comptime_comptime_state
3181 else if (has_runtime_bits)
3182 .struct_field_comptime_runtime_bits
3183 else
3184 .struct_field_comptime
3185 else if (field_init != .none)
3186 if (has_comptime_state)
3187 .struct_field_default_comptime_state
3188 else if (has_runtime_bits)
3189 .struct_field_default_runtime_bits
3190 else
3191 .struct_field
3192 else
3193 .struct_field);
3194 try wip_nav.strp(loaded_struct.fieldName(ip, field_index).toSlice(ip));
3195 try wip_nav.refType(field_type);
3196 if (!is_comptime) {
3197 try diw.writeUleb128(loaded_struct.offsets.get(ip)[field_index]);
3198 try diw.writeUleb128(loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
3199 field_type.abiAlignment(zcu).toByteUnits().?);
3200 }
3201 if (has_comptime_state)
3202 try wip_nav.refValue(.fromInterned(field_init))
3203 else if (has_runtime_bits)
3204 try wip_nav.blockValue(nav_src_loc, .fromInterned(field_init));
3205 }
3206 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
3207 }
3208 },
3209 .@"packed" => {
3210 try wip_nav.declCommon(.{
3211 .decl = .decl_packed_struct,
3212 .generic_decl = .generic_decl_const,
3213 .decl_instance = .decl_instance_packed_struct,
3214 }, &nav, inst_info.file, &decl);
3215 try wip_nav.refType(.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
3216 var field_bit_offset: u16 = 0;
3217 for (0..loaded_struct.field_types.len) |field_index| {
3218 try wip_nav.abbrevCode(.packed_struct_field);
3219 try wip_nav.strp(loaded_struct.fieldName(ip, field_index).toSlice(ip));
3220 const field_type: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
3221 try wip_nav.refType(field_type);
3222 try diw.writeUleb128(field_bit_offset);
3223 field_bit_offset += @intCast(field_type.bitSize(zcu));
3224 }
3225 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
3226 },
3077 if (nav_index.toOptional() == loaded_struct.name_nav) {
3078 // This Nav's entry is populated by the type, not the actual Nav.
3079 _ = try dwarf.const_pool.get(pt, .{ .dwarf = dwarf }, nav_val.toIntern());
3080 try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf });
3081 return;
32273082 }
3228 break :tag .done;
3083 break :tag .alias;
32293084 },
32303085 .enum_type => tag: {
32313086 const loaded_enum = ip.loadEnumType(nav_val.toIntern());
3232 const type_zir_index = loaded_enum.zir_index.unwrap() orelse break :tag .decl_alias;
3233 if (type_zir_index.resolveFile(ip) != inst_info.file) break :tag .decl_alias;
3234
3235 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
3236 if (type_gop.found_existing) {
3237 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;
3238 assert(!nav_gop.found_existing);
3239 nav_gop.value_ptr.* = type_gop.value_ptr.*;
3240 } else {
3241 if (nav_gop.found_existing)
3242 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
3243 else
3244 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
3245 type_gop.value_ptr.* = nav_gop.value_ptr.*;
3246 }
3247 wip_nav.entry = nav_gop.value_ptr.*;
3248 const diw = &wip_nav.debug_info.writer;
3249 try wip_nav.declCommon(if (loaded_enum.names.len > 0) .{
3250 .decl = .decl_enum,
3251 .generic_decl = .generic_decl_const,
3252 .decl_instance = .decl_instance_enum,
3253 } else .{
3254 .decl = .decl_empty_enum,
3255 .generic_decl = .generic_decl_const,
3256 .decl_instance = .decl_instance_empty_enum,
3257 }, &nav, inst_info.file, &decl);
3258 try wip_nav.refType(.fromInterned(loaded_enum.tag_ty));
3259 for (0..loaded_enum.names.len) |field_index| {
3260 try wip_nav.enumConstValue(loaded_enum, .{
3261 .sdata = .signed_enum_field,
3262 .udata = .unsigned_enum_field,
3263 .block = .big_enum_field,
3264 }, field_index);
3265 try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip));
3087 if (nav_index.toOptional() == loaded_enum.name_nav) {
3088 // This Nav's entry is populated by the type, not the actual Nav.
3089 _ = try dwarf.const_pool.get(pt, .{ .dwarf = dwarf }, nav_val.toIntern());
3090 try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf });
3091 return;
32663092 }
3267 if (loaded_enum.names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
3268 break :tag .done;
3093 break :tag .alias;
32693094 },
32703095 .union_type => tag: {
32713096 const loaded_union = ip.loadUnionType(nav_val.toIntern());
3272 if (loaded_union.zir_index.resolveFile(ip) != inst_info.file) break :tag .decl_alias;
3273
3274 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
3275 if (type_gop.found_existing) {
3276 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;
3277 assert(!nav_gop.found_existing);
3278 nav_gop.value_ptr.* = type_gop.value_ptr.*;
3279 } else {
3280 if (nav_gop.found_existing)
3281 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
3282 else
3283 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
3284 type_gop.value_ptr.* = nav_gop.value_ptr.*;
3285 }
3286 wip_nav.entry = nav_gop.value_ptr.*;
3287 const diw = &wip_nav.debug_info.writer;
3288 try wip_nav.declCommon(.{
3289 .decl = .decl_union,
3290 .generic_decl = .generic_decl_const,
3291 .decl_instance = .decl_instance_union,
3292 }, &nav, inst_info.file, &decl);
3293 const union_layout = Type.getUnionLayout(loaded_union, zcu);
3294 try diw.writeUleb128(union_layout.abi_size);
3295 try diw.writeUleb128(union_layout.abi_align.toByteUnits().?);
3296 const loaded_tag = loaded_union.loadTagType(ip);
3297 if (loaded_union.hasTag(ip)) {
3298 try wip_nav.abbrevCode(.tagged_union);
3299 try wip_nav.infoSectionOffset(
3300 .debug_info,
3301 wip_nav.unit,
3302 wip_nav.entry,
3303 @intCast(diw.end + dwarf.sectionOffsetBytes()),
3304 );
3305 {
3306 try wip_nav.abbrevCode(.generated_field);
3307 try wip_nav.strp("tag");
3308 try wip_nav.refType(.fromInterned(loaded_union.enum_tag_ty));
3309 try diw.writeUleb128(union_layout.tagOffset());
3310
3311 for (0..loaded_union.field_types.len) |field_index| {
3312 try wip_nav.enumConstValue(loaded_tag, .{
3313 .sdata = .signed_tagged_union_field,
3314 .udata = .unsigned_tagged_union_field,
3315 .block = .big_tagged_union_field,
3316 }, field_index);
3317 {
3318 try wip_nav.abbrevCode(.struct_field);
3319 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
3320 const field_type: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
3321 try wip_nav.refType(field_type);
3322 try diw.writeUleb128(union_layout.payloadOffset());
3323 try diw.writeUleb128(loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
3324 if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?);
3325 }
3326 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
3327 }
3328 }
3329 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
3330 } else for (0..loaded_union.field_types.len) |field_index| {
3331 try wip_nav.abbrevCode(.untagged_union_field);
3332 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
3333 const field_type: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
3334 try wip_nav.refType(field_type);
3335 try diw.writeUleb128(loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
3336 if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?);
3097 if (nav_index.toOptional() == loaded_union.name_nav) {
3098 // This Nav's entry is populated by the type, not the actual Nav.
3099 _ = try dwarf.const_pool.get(pt, .{ .dwarf = dwarf }, nav_val.toIntern());
3100 try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf });
3101 return;
33373102 }
3338 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
3339 break :tag .done;
3103 break :tag .alias;
33403104 },
33413105 .opaque_type => tag: {
33423106 const loaded_opaque = ip.loadOpaqueType(nav_val.toIntern());
3343 if (loaded_opaque.zir_index.resolveFile(ip) != inst_info.file) break :tag .decl_alias;
3344
3345 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
3346 if (type_gop.found_existing) {
3347 if (dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).len > 0) break :tag .decl_alias;
3348 assert(!nav_gop.found_existing);
3349 nav_gop.value_ptr.* = type_gop.value_ptr.*;
3350 } else {
3351 if (nav_gop.found_existing)
3352 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
3353 else
3354 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
3355 type_gop.value_ptr.* = nav_gop.value_ptr.*;
3107 if (nav_index.toOptional() == loaded_opaque.name_nav) {
3108 // This Nav's entry is populated by the type, not the actual Nav.
3109 _ = try dwarf.const_pool.get(pt, .{ .dwarf = dwarf }, nav_val.toIntern());
3110 try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf });
3111 return;
33563112 }
3357 wip_nav.entry = nav_gop.value_ptr.*;
3358 const diw = &wip_nav.debug_info.writer;
3359 try wip_nav.declCommon(.{
3360 .decl = .decl_namespace_struct,
3361 .generic_decl = .generic_decl_const,
3362 .decl_instance = .decl_instance_namespace_struct,
3363 }, &nav, inst_info.file, &decl);
3364 try diw.writeByte(@intFromBool(true));
3365 break :tag .done;
3113 break :tag .alias;
33663114 },
3115
33673116 .undef,
33683117 .simple_value,
33693118 .int,
......@@ -3371,70 +3120,76 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
33713120 .error_union,
33723121 .enum_literal,
33733122 .enum_tag,
3374 .empty_enum_value,
33753123 .float,
33763124 .ptr,
33773125 .slice,
33783126 .opt,
33793127 .aggregate,
33803128 .un,
3381 => .decl_const,
3382 .variable => .decl_var,
3129 .bitpack,
3130 => .@"const",
3131
3132 .variable => .@"var",
3133
33833134 .@"extern" => unreachable,
3384 .func => |func| tag: {
3385 if (func.owner_nav != nav_index) break :tag .{ .decl_func_alias = func.owner_nav };
3386 if (nav_gop.found_existing) switch (try dwarf.debug_info.declAbbrevCode(wip_nav.unit, nav_gop.value_ptr.*)) {
3387 .null => {},
3388 else => unreachable,
3389 .decl_nullary_func, .decl_func, .decl_instance_nullary_func, .decl_instance_func => return,
3390 .decl_nullary_func_generic,
3391 .decl_func_generic,
3392 .decl_instance_nullary_func_generic,
3393 .decl_instance_func_generic,
3394 => dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear(),
3395 } else nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
3396 wip_nav.entry = nav_gop.value_ptr.*;
33973135
3398 const func_type = ip.indexToKey(func.ty).func_type;
3399 const is_nullary = !func_type.is_var_args and for (0..func_type.param_types.len) |param_index| {
3400 if (!func_type.paramIsComptime(std.math.cast(u5, param_index) orelse break false)) break false;
3401 } else true;
3402 const diw = &wip_nav.debug_info.writer;
3403 try wip_nav.declCommon(if (is_nullary) .{
3404 .decl = .decl_nullary_func_generic,
3405 .generic_decl = .generic_decl_func,
3406 .decl_instance = .decl_instance_nullary_func_generic,
3407 } else .{
3408 .decl = .decl_func_generic,
3409 .generic_decl = .generic_decl_func,
3410 .decl_instance = .decl_instance_func_generic,
3411 }, &nav, inst_info.file, &decl);
3412 try wip_nav.refType(.fromInterned(func_type.return_type));
3413 if (!is_nullary) {
3414 for (0..func_type.param_types.len) |param_index| {
3415 if (std.math.cast(u5, param_index)) |small_param_index|
3416 if (func_type.paramIsComptime(small_param_index)) continue;
3417 try wip_nav.abbrevCode(.func_type_param);
3418 try wip_nav.refType(.fromInterned(func_type.param_types.get(ip)[param_index]));
3419 }
3420 if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args);
3421 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
3422 }
3423 break :tag .done;
3136 .func => |func| tag: {
3137 if (func.owner_nav != nav_index) break :tag .{ .func_alias = func.owner_nav };
3138 break :tag .{ .func = .fromInterned(func.ty) };
34243139 },
3140
34253141 // memoization, not types
34263142 .memoized_call => unreachable,
34273143 };
3428 if (tag != .done) {
3429 if (nav_gop.found_existing)
3430 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
3431 else
3432 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
3433 wip_nav.entry = nav_gop.value_ptr.*;
3144
3145 const unit = try dwarf.getUnit(file.mod.?);
3146
3147 const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);
3148 errdefer _ = if (!nav_gop.found_existing) dwarf.navs.pop();
3149
3150 if (nav_gop.found_existing) {
3151 if (tag == .func) switch (try dwarf.debug_info.declAbbrevCode(unit, nav_gop.value_ptr.*)) {
3152 else => unreachable,
3153
3154 .decl_nullary_func,
3155 .decl_func,
3156 .decl_instance_nullary_func,
3157 .decl_instance_func,
3158 => return,
3159
3160 .null,
3161 .decl_nullary_func_generic,
3162 .decl_func_generic,
3163 .decl_instance_nullary_func_generic,
3164 .decl_instance_func_generic,
3165 => {},
3166 };
3167 dwarf.debug_info.section.getUnit(unit).getEntry(nav_gop.value_ptr.*).clear();
3168 } else {
3169 nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit);
34343170 }
3171
3172 var wip_nav: WipNav = .{
3173 .dwarf = dwarf,
3174 .pt = pt,
3175 .unit = unit,
3176 .entry = nav_gop.value_ptr.*,
3177 .any_children = false,
3178 .func = .none,
3179 .func_sym_index = undefined,
3180 .func_high_pc = undefined,
3181 .blocks = undefined,
3182 .cfi = undefined,
3183 .debug_frame = .init(dwarf.gpa),
3184 .debug_info = .init(dwarf.gpa),
3185 .debug_line = .init(dwarf.gpa),
3186 .debug_loclists = .init(dwarf.gpa),
3187 };
3188 defer wip_nav.deinit();
3189 const diw = &wip_nav.debug_info.writer;
3190
34353191 switch (tag) {
3436 .done => {},
3437 .decl_alias => {
3192 .alias => {
34383193 try wip_nav.declCommon(.{
34393194 .decl = .decl_alias,
34403195 .generic_decl = .generic_decl_const,
......@@ -3442,8 +3197,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
34423197 }, &nav, inst_info.file, &decl);
34433198 try wip_nav.refType(nav_val.toType());
34443199 },
3445 .decl_var => {
3446 const diw = &wip_nav.debug_info.writer;
3200 .@"var" => {
34473201 try wip_nav.declCommon(.{
34483202 .decl = .decl_var,
34493203 .generic_decl = .generic_decl_var,
......@@ -3460,11 +3214,10 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
34603214 nav_ty.abiAlignment(zcu).toByteUnits().?);
34613215 try diw.writeByte(@intFromBool(decl.linkage != .normal));
34623216 },
3463 .decl_const => {
3464 const diw = &wip_nav.debug_info.writer;
3217 .@"const" => {
34653218 const nav_ty = nav_val.typeOf(zcu);
34663219 const has_runtime_bits = nav_ty.hasRuntimeBits(zcu);
3467 const has_comptime_state = nav_ty.comptimeOnly(zcu) and try nav_ty.onePossibleValue(pt) == null;
3220 const has_comptime_state = nav_ty.comptimeOnly(zcu);
34683221 try wip_nav.declCommon(if (has_runtime_bits and has_comptime_state) .{
34693222 .decl = .decl_const_runtime_bits_comptime_state,
34703223 .generic_decl = .generic_decl_const,
......@@ -3496,40 +3249,129 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
34963249 try wip_nav.abbrevCode(.is_const);
34973250 try wip_nav.refType(nav_ty);
34983251 },
3499 .decl_func_alias => |owner_nav| {
3500 try wip_nav.declCommon(.{
3501 .decl = .decl_alias,
3502 .generic_decl = .generic_decl_const,
3503 .decl_instance = .decl_instance_alias,
3252 .func => |func_ty| {
3253 const func_type = ip.indexToKey(func_ty.toIntern()).func_type;
3254 const is_nullary = !func_type.is_var_args and for (0..func_type.param_types.len) |param_index| {
3255 if (!func_type.paramIsComptime(std.math.cast(u5, param_index) orelse break false)) break false;
3256 } else true;
3257 try wip_nav.declCommon(if (is_nullary) .{
3258 .decl = .decl_nullary_func_generic,
3259 .generic_decl = .generic_decl_func,
3260 .decl_instance = .decl_instance_nullary_func_generic,
3261 } else .{
3262 .decl = .decl_func_generic,
3263 .generic_decl = .generic_decl_func,
3264 .decl_instance = .decl_instance_func_generic,
35043265 }, &nav, inst_info.file, &decl);
3505 try wip_nav.refNav(owner_nav);
3506 },
3507 }
3508 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.written());
3509 try wip_nav.updateLazy(nav_src_loc);
3266 try wip_nav.refType(.fromInterned(func_type.return_type));
3267 if (!is_nullary) {
3268 for (0..func_type.param_types.len) |param_index| {
3269 if (std.math.cast(u5, param_index)) |small_param_index|
3270 if (func_type.paramIsComptime(small_param_index)) continue;
3271 try wip_nav.abbrevCode(.func_type_param);
3272 try wip_nav.refType(.fromInterned(func_type.param_types.get(ip)[param_index]));
3273 }
3274 if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args);
3275 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
3276 }
3277 },
3278 .func_alias => |owner_nav| {
3279 try wip_nav.declCommon(.{
3280 .decl = .decl_alias,
3281 .generic_decl = .generic_decl_const,
3282 .decl_instance = .decl_instance_alias,
3283 }, &nav, inst_info.file, &decl);
3284 try wip_nav.refNav(owner_nav);
3285 },
3286 }
3287 try dwarf.debug_info.section.replaceEntry(unit, wip_nav.entry, dwarf, wip_nav.debug_info.written());
3288 try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf });
35103289}
35113290
3512fn updateLazyType(
3291pub fn updateContainerType(
35133292 dwarf: *Dwarf,
35143293 pt: Zcu.PerThread,
3515 src_loc: Zcu.LazySrcLoc,
3516 type_index: InternPool.Index,
3517 pending_lazy: *WipNav.PendingLazy,
3518) (UpdateError || Writer.Error)!void {
3294 ty: InternPool.Index,
3295 success: bool,
3296) !void {
3297 try dwarf.const_pool.updateContainerType(pt, .{ .dwarf = dwarf }, ty, success);
3298}
3299/// Should only be called by the `link.ConstPool` implementation.
3300pub fn addConst(dwarf: *Dwarf, pt: Zcu.PerThread, index: link.ConstPool.Index, val: InternPool.Index) Allocator.Error!void {
3301 addConstInner(dwarf, pt, index, val) catch |err| switch (err) {
3302 error.OutOfMemory => |e| return e,
3303 else => |e| std.debug.panic("DWARF TODO: '{t}' while registering constant\n", .{e}),
3304 };
3305}
3306fn addConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, index: link.ConstPool.Index, val: InternPool.Index) !void {
35193307 const zcu = pt.zcu;
35203308 const ip = &zcu.intern_pool;
3521 assert(ip.typeOf(type_index) == .type_type);
3522 const ty: Type = .fromInterned(type_index);
3523 switch (type_index) {
3524 .generic_poison_type => log.debug("updateLazyType({s})", .{"anytype"}),
3525 else => log.debug("updateLazyType({f})", .{ty.fmt(pt)}),
3309
3310 const unit: Unit.Index, const entry: Entry.Index = switch (ip.indexToKey(val)) {
3311 else => .{ .main, try dwarf.addCommonEntry(.main) },
3312 .func => |func| try dwarf.getNavEntry(func.owner_nav),
3313 .@"extern" => |@"extern"| try dwarf.getNavEntry(@"extern".owner_nav),
3314 .struct_type, .union_type, .enum_type, .opaque_type => |_, tag| entry: {
3315 const name_nav = switch (tag) {
3316 .struct_type => ip.loadStructType(val).name_nav,
3317 .union_type => ip.loadUnionType(val).name_nav,
3318 .enum_type => ip.loadEnumType(val).name_nav,
3319 .opaque_type => ip.loadOpaqueType(val).name_nav,
3320 else => unreachable,
3321 };
3322 if (name_nav.unwrap()) |nav| {
3323 break :entry try dwarf.getNavEntry(nav);
3324 } else {
3325 const zir_index = Type.fromInterned(val).typeDeclInstAllowGeneratedTag(zcu).?;
3326 const unit = try dwarf.getUnit(zcu.fileByIndex(zir_index.resolveFile(ip)).mod.?);
3327 break :entry .{ unit, try dwarf.addCommonEntry(unit) };
3328 }
3329 },
3330 };
3331
3332 assert(@intFromEnum(index) == dwarf.values.items.len);
3333 try dwarf.values.append(dwarf.gpa, .{ unit, entry });
3334}
3335/// Should only be called by the `link.ConstPool` implementation.
3336///
3337/// Emits a "dummy" DIE for the given comptime-only value (which may be a type). For types, this is
3338/// an opaque type. Otherwise, it is an undefined value of the value's type.
3339pub fn updateConstIncomplete(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.ConstPool.Index, value_index: InternPool.Index) Allocator.Error!void {
3340 updateConstIncompleteInner(dwarf, pt, debug_const_index, value_index) catch |err| switch (err) {
3341 error.OutOfMemory => |e| return e,
3342 else => |e| std.debug.panic("DWARF TODO: '{t}' while updating incomplete constant\n", .{e}),
3343 };
3344}
3345fn updateConstIncompleteInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.ConstPool.Index, value_index: InternPool.Index) !void {
3346 const zcu = pt.zcu;
3347 const ip = &zcu.intern_pool;
3348
3349 const val: Value = .fromInterned(value_index);
3350
3351 switch (value_index) {
3352 .generic_poison_type => log.debug("updateValueIncomplete(anytype)", .{}),
3353 else => log.debug("updateValueIncomplete(@as({f}, {f}))", .{
3354 val.typeOf(zcu).fmt(pt),
3355 val.fmtValue(pt),
3356 }),
35263357 }
35273358
3359 const unit, const entry = dwarf.values.items[@intFromEnum(debug_const_index)];
3360
3361 for ([_]*Section{
3362 &dwarf.debug_aranges.section,
3363 &dwarf.debug_aranges.section,
3364 &dwarf.debug_info.section,
3365 &dwarf.debug_line.section,
3366 &dwarf.debug_loclists.section,
3367 &dwarf.debug_rnglists.section,
3368 }) |sec| sec.getUnit(unit).getEntry(entry).clear();
3369
35283370 var wip_nav: WipNav = .{
35293371 .dwarf = dwarf,
35303372 .pt = pt,
3531 .unit = .main,
3532 .entry = dwarf.types.get(type_index).?,
3373 .unit = unit,
3374 .entry = entry,
35333375 .any_children = false,
35343376 .func = .none,
35353377 .func_sym_index = undefined,
......@@ -3540,43 +3382,216 @@ fn updateLazyType(
35403382 .debug_info = .init(dwarf.gpa),
35413383 .debug_line = .init(dwarf.gpa),
35423384 .debug_loclists = .init(dwarf.gpa),
3543 .pending_lazy = pending_lazy.*,
35443385 };
3545 defer {
3546 pending_lazy.* = wip_nav.pending_lazy;
3547 wip_nav.pending_lazy = .empty;
3548 wip_nav.deinit();
3386 defer wip_nav.deinit();
3387
3388 switch (ip.indexToKey(value_index)) {
3389 // Container types still need to be valid namespaces.
3390 .struct_type => {
3391 const loaded_struct = ip.loadStructType(value_index);
3392 const root_of_file: ?Zcu.File.Index = if (loaded_struct.zir_index.resolveFull(ip)) |r| f: {
3393 if (r.inst != .main_struct_inst) break :f null;
3394 break :f r.file;
3395 } else null;
3396 if (root_of_file) |file_index| {
3397 assert(loaded_struct.name_nav == .none);
3398 const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, file_index);
3399 try wip_nav.abbrevCode(.empty_file);
3400 try wip_nav.debug_info.writer.writeUleb128(file_gop.index);
3401 try wip_nav.strp(loaded_struct.name.toSlice(ip));
3402 } else {
3403 try dwarf.emitIncompleteContainerType(
3404 &wip_nav,
3405 loaded_struct.zir_index,
3406 loaded_struct.name,
3407 loaded_struct.name_nav,
3408 );
3409 }
3410 },
3411 .union_type => {
3412 const loaded_union = ip.loadUnionType(value_index);
3413 try dwarf.emitIncompleteContainerType(
3414 &wip_nav,
3415 loaded_union.zir_index,
3416 loaded_union.name,
3417 loaded_union.name_nav,
3418 );
3419 },
3420 .enum_type => {
3421 const loaded_enum = ip.loadEnumType(value_index);
3422 if (loaded_enum.zir_index.unwrap()) |zir_index| {
3423 try dwarf.emitIncompleteContainerType(
3424 &wip_nav,
3425 zir_index,
3426 loaded_enum.name,
3427 loaded_enum.name_nav,
3428 );
3429 } else {
3430 try wip_nav.abbrevCode(.generated_empty_struct_type);
3431 try wip_nav.strp(loaded_enum.name.toSlice(ip));
3432 try wip_nav.debug_info.writer.writeByte(@intFromBool(true));
3433 }
3434 },
3435 .opaque_type => {
3436 const loaded_opaque = ip.loadOpaqueType(value_index);
3437 try dwarf.emitIncompleteContainerType(
3438 &wip_nav,
3439 loaded_opaque.zir_index,
3440 loaded_opaque.name,
3441 loaded_opaque.name_nav,
3442 );
3443 },
3444 // Not a container type, so just emit a dummy entry. If `val` happens to be a type, we'll
3445 // emit it as if it were an opaque type so that we can name it.
3446 else => |val_key| switch (val_key.typeOf()) {
3447 .type_type => {
3448 try wip_nav.abbrevCode(.generated_empty_struct_type);
3449 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3450 try wip_nav.debug_info.writer.writeByte(@intFromBool(true));
3451 },
3452 else => |ty| {
3453 try wip_nav.abbrevCode(.undefined_comptime_value);
3454 try wip_nav.refType(.fromInterned(ty));
3455 },
3456 },
35493457 }
3550 const diw = &wip_nav.debug_info.writer;
3551 const name = switch (type_index) {
3552 .generic_poison_type => "",
3553 else => try std.fmt.allocPrint(dwarf.gpa, "{f}", .{ty.fmt(pt)}),
3458 try dwarf.debug_info.section.replaceEntry(unit, entry, dwarf, wip_nav.debug_info.written());
3459 try dwarf.debug_loclists.section.replaceEntry(unit, entry, dwarf, wip_nav.debug_loclists.written());
3460}
3461fn emitIncompleteContainerType(
3462 dwarf: *Dwarf,
3463 wip_nav: *WipNav,
3464 zir_index: InternPool.TrackedInst.Index,
3465 name: InternPool.NullTerminatedString,
3466 name_nav: InternPool.Nav.Index.Optional,
3467) !void {
3468 const zcu = wip_nav.pt.zcu;
3469 const ip = &zcu.intern_pool;
3470 const file = zir_index.resolveFile(ip);
3471 if (name_nav.unwrap()) |nav_index| {
3472 const nav = ip.getNav(nav_index);
3473 const decl_inst = nav.srcInst(ip).resolve(ip).?;
3474 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);
3475 try wip_nav.declCommon(.{
3476 .decl = .decl_namespace_struct,
3477 .generic_decl = .generic_decl_const,
3478 .decl_instance = .decl_instance_namespace_struct,
3479 }, &nav, file, &decl);
3480 try wip_nav.debug_info.writer.writeByte(@intFromBool(true));
3481 } else {
3482 const diw = &wip_nav.debug_info.writer;
3483 const file_gop = try dwarf.getModInfo(wip_nav.unit).files.getOrPut(dwarf.gpa, file);
3484 try wip_nav.abbrevCode(.empty_struct_type);
3485 try diw.writeUleb128(file_gop.index);
3486 try wip_nav.strp(name.toSlice(ip));
3487 try diw.writeByte(@intFromBool(true));
3488 }
3489}
3490/// Should only be called by the `link.ConstPool` implementation.
3491///
3492/// Emits a DIE for the given comptime-only value (which may be a type).
3493pub fn updateConst(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.ConstPool.Index, value_index: InternPool.Index) Allocator.Error!void {
3494 updateConstInner(dwarf, pt, debug_const_index, value_index) catch |err| switch (err) {
3495 error.OutOfMemory => |e| return e,
3496 else => |e| std.debug.panic("DWARF TODO: '{t}' while updating constant\n", .{e}),
35543497 };
3555 defer dwarf.gpa.free(name);
3498}
3499fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.ConstPool.Index, value_index: InternPool.Index) !void {
3500 const zcu = pt.zcu;
3501 const ip = &zcu.intern_pool;
3502
3503 const val: Value = .fromInterned(value_index);
3504
3505 if (val.typeOf(zcu).toIntern() == .type_type and !val.isUndef(zcu)) {
3506 val.toType().assertHasLayout(zcu);
3507 } else {
3508 val.typeOf(zcu).assertHasLayout(zcu);
3509 }
3510
3511 if (value_index == .anyerror_type) return; // handled in `flush` instead
3512
3513 const value_ip_key = ip.indexToKey(value_index);
3514 switch (value_ip_key) {
3515 .func => return, // populated by the Nav instead (`updateComptimeNav` or `initWipNav`)
3516 .@"extern" => return, // populated by the Nav instead (`initWipNav`)
3517 else => {},
3518 }
3519
3520 switch (value_index) {
3521 .generic_poison_type => log.debug("updateValue(anytype)", .{}),
3522 else => log.debug("updateValue(@as({f}, {f}))", .{
3523 val.typeOf(zcu).fmt(pt),
3524 val.fmtValue(pt),
3525 }),
3526 }
3527
3528 const unit, const entry = dwarf.values.items[@intFromEnum(debug_const_index)];
3529
3530 for ([_]*Section{
3531 &dwarf.debug_aranges.section,
3532 &dwarf.debug_info.section,
3533 &dwarf.debug_line.section,
3534 &dwarf.debug_loclists.section,
3535 &dwarf.debug_rnglists.section,
3536 }) |sec| sec.getUnit(unit).getEntry(entry).clear();
3537
3538 var wip_nav: WipNav = .{
3539 .dwarf = dwarf,
3540 .pt = pt,
3541 .unit = unit,
3542 .entry = entry,
3543 .any_children = false,
3544 .func = .none,
3545 .func_sym_index = undefined,
3546 .func_high_pc = undefined,
3547 .blocks = undefined,
3548 .cfi = undefined,
3549 .debug_frame = .init(dwarf.gpa),
3550 .debug_info = .init(dwarf.gpa),
3551 .debug_line = .init(dwarf.gpa),
3552 .debug_loclists = .init(dwarf.gpa),
3553 };
3554 defer wip_nav.deinit();
3555
3556 // TODO: we really shouldn't need source locations at this point in the pipeline: we've lost
3557 // that information by now. If the linker fundamentally cannot lower certain values, that needs
3558 // to be caught in the frontend; if it can only hit transient failures, they should be reported
3559 // without trying to tie them to a bogus source location.
3560 const src_loc: Zcu.LazySrcLoc = .{
3561 .base_node_inst = inst: {
3562 const mod_root_file_index = zcu.module_roots.get(zcu.std_mod).?.unwrap().?;
3563 const mod_root_type_index = zcu.fileRootType(mod_root_file_index);
3564 break :inst ip.loadStructType(mod_root_type_index).zir_index;
3565 },
3566 .offset = .{ .byte_abs = 0 },
3567 };
3568
3569 const diw = &wip_nav.debug_info.writer;
3570 var big_int_space: Value.BigIntSpace = undefined;
3571 switch (value_ip_key) {
3572 .func => unreachable, // handled above
3573 .@"extern" => unreachable, // handled above
35563574
3557 switch (ip.indexToKey(type_index)) {
3558 .undef => {
3559 try wip_nav.abbrevCode(.undefined_comptime_value);
3560 try wip_nav.refType(.type);
3561 },
35623575 .int_type => |int_type| {
35633576 try wip_nav.abbrevCode(.numeric_type);
3564 try wip_nav.strp(name);
3577 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
35653578 try diw.writeByte(switch (int_type.signedness) {
35663579 inline .signed, .unsigned => |signedness| @field(DW.ATE, @tagName(signedness)),
35673580 });
35683581 try diw.writeUleb128(int_type.bits);
3569 try diw.writeUleb128(ty.abiSize(zcu));
3570 try diw.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);
3582 try diw.writeUleb128(val.toType().abiSize(zcu));
3583 try diw.writeUleb128(val.toType().abiAlignment(zcu).toByteUnits().?);
35713584 },
35723585 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
35733586 .one, .many, .c => {
35743587 const ptr_child_type: Type = .fromInterned(ptr_type.child);
3575 try wip_nav.abbrevCode(if (ptr_type.sentinel == .none) .ptr_type else .ptr_sentinel_type);
3576 try wip_nav.strp(name);
3588 try wip_nav.abbrevCode(switch (ptr_type.flags.alignment) {
3589 .none => if (ptr_type.sentinel == .none) .ptr_type else .ptr_sentinel_type,
3590 else => if (ptr_type.sentinel == .none) .ptr_aligned_type else .ptr_aligned_sentinel_type,
3591 });
3592 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
35773593 if (ptr_type.sentinel != .none) try wip_nav.blockValue(src_loc, .fromInterned(ptr_type.sentinel));
3578 try diw.writeUleb128(ptr_type.flags.alignment.toByteUnits() orelse
3579 ptr_child_type.abiAlignment(zcu).toByteUnits().?);
3594 if (ptr_type.flags.alignment.toByteUnits()) |a| try diw.writeUleb128(a);
35803595 try diw.writeByte(@intFromEnum(ptr_type.flags.address_space));
35813596 if (ptr_type.flags.is_const or ptr_type.flags.is_volatile) try wip_nav.infoSectionOffset(
35823597 .debug_info,
......@@ -3600,12 +3615,12 @@ fn updateLazyType(
36003615 },
36013616 .slice => {
36023617 try wip_nav.abbrevCode(.generated_struct_type);
3603 try wip_nav.strp(name);
3604 try diw.writeUleb128(ty.abiSize(zcu));
3605 try diw.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);
3618 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3619 try diw.writeUleb128(val.toType().abiSize(zcu));
3620 try diw.writeUleb128(val.toType().abiAlignment(zcu).toByteUnits().?);
36063621 try wip_nav.abbrevCode(.generated_field);
36073622 try wip_nav.strp("ptr");
3608 const ptr_field_type = ty.slicePtrFieldType(zcu);
3623 const ptr_field_type = val.toType().slicePtrFieldType(zcu);
36093624 try wip_nav.refType(ptr_field_type);
36103625 try diw.writeUleb128(0);
36113626 try wip_nav.abbrevCode(.generated_field);
......@@ -3619,7 +3634,7 @@ fn updateLazyType(
36193634 .array_type => |array_type| {
36203635 const array_child_type: Type = .fromInterned(array_type.child);
36213636 try wip_nav.abbrevCode(if (array_type.sentinel == .none) .array_type else .array_sentinel_type);
3622 try wip_nav.strp(name);
3637 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
36233638 if (array_type.sentinel != .none) try wip_nav.blockValue(src_loc, .fromInterned(array_type.sentinel));
36243639 try wip_nav.refType(array_child_type);
36253640 try wip_nav.abbrevCode(.array_len);
......@@ -3629,7 +3644,7 @@ fn updateLazyType(
36293644 },
36303645 .vector_type => |vector_type| {
36313646 try wip_nav.abbrevCode(.vector_type);
3632 try wip_nav.strp(name);
3647 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
36333648 try wip_nav.refType(.fromInterned(vector_type.child));
36343649 try wip_nav.abbrevCode(.array_len);
36353650 try wip_nav.refType(.usize);
......@@ -3640,9 +3655,9 @@ fn updateLazyType(
36403655 const opt_child_type: Type = .fromInterned(opt_child_type_index);
36413656 const opt_repr = optRepr(opt_child_type, zcu);
36423657 try wip_nav.abbrevCode(.generated_union_type);
3643 try wip_nav.strp(name);
3644 try diw.writeUleb128(ty.abiSize(zcu));
3645 try diw.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);
3658 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3659 try diw.writeUleb128(val.toType().abiSize(zcu));
3660 try diw.writeUleb128(val.toType().abiAlignment(zcu).toByteUnits().?);
36463661 switch (opt_repr) {
36473662 .opv_null => {
36483663 try wip_nav.abbrevCode(.generated_field);
......@@ -3720,12 +3735,12 @@ fn updateLazyType(
37203735 };
37213736
37223737 try wip_nav.abbrevCode(.generated_union_type);
3723 try wip_nav.strp(name);
3738 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
37243739 if (error_union_type.error_set_type != .generic_poison_type and
37253740 error_union_type.payload_type != .generic_poison_type)
37263741 {
3727 try diw.writeUleb128(ty.abiSize(zcu));
3728 try diw.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);
3742 try diw.writeUleb128(val.toType().abiSize(zcu));
3743 try diw.writeUleb128(val.toType().abiAlignment(zcu).toByteUnits().?);
37293744 } else {
37303745 try diw.writeUleb128(0);
37313746 try diw.writeUleb128(1);
......@@ -3791,20 +3806,24 @@ fn updateLazyType(
37913806 .bool,
37923807 => {
37933808 try wip_nav.abbrevCode(.numeric_type);
3794 try wip_nav.strp(name);
3795 try diw.writeByte(if (type_index == .bool_type)
3809 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3810 try diw.writeByte(if (value_index == .bool_type)
37963811 DW.ATE.boolean
3797 else if (ty.isRuntimeFloat())
3812 else if (val.toType().isRuntimeFloat())
37983813 DW.ATE.float
3799 else if (ty.isSignedInt(zcu))
3814 else if (val.toType().isSignedInt(zcu))
38003815 DW.ATE.signed
3801 else if (ty.isUnsignedInt(zcu))
3816 else if (val.toType().isUnsignedInt(zcu))
38023817 DW.ATE.unsigned
38033818 else
38043819 unreachable);
3805 try diw.writeUleb128(ty.bitSize(zcu));
3806 try diw.writeUleb128(ty.abiSize(zcu));
3807 try diw.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);
3820 try diw.writeUleb128(val.toType().bitSize(zcu));
3821 try diw.writeUleb128(val.toType().abiSize(zcu));
3822 try diw.writeUleb128(val.toType().abiAlignment(zcu).toByteUnits().?);
3823 },
3824 .generic_poison => {
3825 try wip_nav.abbrevCode(.void_type);
3826 try wip_nav.strp("anytype");
38083827 },
38093828 .anyopaque,
38103829 .void,
......@@ -3815,37 +3834,29 @@ fn updateLazyType(
38153834 .null,
38163835 .undefined,
38173836 .enum_literal,
3818 .generic_poison,
38193837 => {
38203838 try wip_nav.abbrevCode(.void_type);
3821 try wip_nav.strp(if (type_index == .generic_poison_type) "anytype" else name);
3839 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
38223840 },
3823 .anyerror => return, // delay until flush
3841 .anyerror => unreachable, // already did early return above
38243842 .adhoc_inferred_error_set => unreachable,
38253843 },
3826 .struct_type,
3827 .union_type,
3828 .opaque_type,
3829 => unreachable,
38303844 .tuple_type => |tuple_type| if (tuple_type.types.len == 0) {
38313845 try wip_nav.abbrevCode(.generated_empty_struct_type);
3832 try wip_nav.strp(name);
3846 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
38333847 try diw.writeByte(@intFromBool(false));
38343848 } else {
38353849 try wip_nav.abbrevCode(.generated_struct_type);
3836 try wip_nav.strp(name);
3837 try diw.writeUleb128(ty.abiSize(zcu));
3838 try diw.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);
3850 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3851 try diw.writeUleb128(val.toType().abiSize(zcu));
3852 try diw.writeUleb128(val.toType().abiAlignment(zcu).toByteUnits().?);
38393853 var field_byte_offset: u64 = 0;
38403854 for (0..tuple_type.types.len) |field_index| {
38413855 const comptime_value = tuple_type.values.get(ip)[field_index];
38423856 const field_type: Type = .fromInterned(tuple_type.types.get(ip)[field_index]);
38433857 const has_runtime_bits, const has_comptime_state = switch (comptime_value) {
38443858 .none => .{ false, false },
3845 else => .{
3846 field_type.hasRuntimeBits(zcu),
3847 field_type.comptimeOnly(zcu) and try field_type.onePossibleValue(pt) == null,
3848 },
3859 else => .{ field_type.hasRuntimeBits(zcu), field_type.comptimeOnly(zcu) },
38493860 };
38503861 try wip_nav.abbrevCode(if (has_comptime_state)
38513862 .struct_field_comptime_comptime_state
......@@ -3875,25 +3886,284 @@ fn updateLazyType(
38753886 }
38763887 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
38773888 },
3889 .struct_type => {
3890 const loaded_struct = ip.loadStructType(value_index);
3891 const ty = val.toType();
3892 const file = loaded_struct.zir_index.resolveFile(ip);
3893 switch (loaded_struct.layout) {
3894 .auto, .@"extern" => {
3895 const struct_is_file: bool = if (loaded_struct.zir_index.resolve(ip)) |inst| f: {
3896 break :f inst == .main_struct_inst;
3897 } else false;
3898 if (loaded_struct.name_nav.unwrap()) |nav_index| {
3899 assert(!struct_is_file);
3900 const nav = ip.getNav(nav_index);
3901 const decl_inst = nav.srcInst(ip).resolve(ip).?;
3902 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);
3903 try wip_nav.declCommon(if (loaded_struct.field_types.len == 0) .{
3904 .decl = .decl_namespace_struct,
3905 .generic_decl = .generic_decl_const,
3906 .decl_instance = .decl_instance_namespace_struct,
3907 } else .{
3908 .decl = .decl_struct,
3909 .generic_decl = .generic_decl_const,
3910 .decl_instance = .decl_instance_struct,
3911 }, &nav, file, &decl);
3912 } else {
3913 const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, file);
3914 try wip_nav.abbrevCode(switch (loaded_struct.field_types.len) {
3915 0 => if (struct_is_file) .empty_file else .empty_struct_type,
3916 else => if (struct_is_file) .file else .struct_type,
3917 });
3918 try diw.writeUleb128(file_gop.index);
3919 try wip_nav.strp(loaded_struct.name.toSlice(ip));
3920 }
3921 if (loaded_struct.field_types.len == 0) {
3922 if (!struct_is_file) try diw.writeByte(@intFromBool(false));
3923 } else {
3924 try diw.writeUleb128(ty.abiSize(zcu));
3925 try diw.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);
3926 for (0..loaded_struct.field_types.len) |field_index| {
3927 const is_comptime = loaded_struct.field_is_comptime_bits.get(ip, field_index);
3928 // TODO: we currently don't emit information about default values for
3929 // non-`comptime` fields, because these default values are resolved at a
3930 // separate time in the compiler frontend. To emit this information, the
3931 // frontend needs to tell us when the default values are available: like
3932 // how `Zcu.PerThread.ensureTypeLayoutUpToDate` enqueues a link task to
3933 // indicate completion of the type's layout, a task should be enqueued
3934 // by `Zcu.PerThread.ensureStructDefaultsUpToDate`, and upon receiving
3935 // it we should patch the correct default field values in.
3936 const field_init: InternPool.Index = if (is_comptime) loaded_struct.field_defaults.getOrNone(ip, field_index) else .none;
3937 assert(!(is_comptime and field_init == .none));
3938 const field_type: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
3939 const has_runtime_bits, const has_comptime_state = switch (field_init) {
3940 .none => .{ false, false },
3941 else => .{
3942 field_type.hasRuntimeBits(zcu),
3943 field_type.comptimeOnly(zcu),
3944 },
3945 };
3946 try wip_nav.abbrevCode(if (is_comptime)
3947 if (has_comptime_state)
3948 .struct_field_comptime_comptime_state
3949 else if (has_runtime_bits)
3950 .struct_field_comptime_runtime_bits
3951 else
3952 .struct_field_comptime
3953 else if (field_init != .none)
3954 if (has_comptime_state)
3955 .struct_field_default_comptime_state
3956 else if (has_runtime_bits)
3957 .struct_field_default_runtime_bits
3958 else
3959 .struct_field
3960 else
3961 .struct_field);
3962 try wip_nav.strp(loaded_struct.field_names.get(ip)[field_index].toSlice(ip));
3963 try wip_nav.refType(field_type);
3964 if (!is_comptime) {
3965 try diw.writeUleb128(loaded_struct.field_offsets.get(ip)[field_index]);
3966 try diw.writeUleb128(loaded_struct.field_aligns.getOrNone(ip, field_index).toByteUnits() orelse
3967 field_type.abiAlignment(zcu).toByteUnits().?);
3968 }
3969 if (has_comptime_state)
3970 try wip_nav.refValue(.fromInterned(field_init))
3971 else if (has_runtime_bits)
3972 try wip_nav.blockValue(ty.srcLoc(zcu), .fromInterned(field_init));
3973 }
3974 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
3975 }
3976 },
3977 .@"packed" => {
3978 const need_terminator: bool = if (loaded_struct.name_nav.unwrap()) |nav_index| t: {
3979 const nav = ip.getNav(nav_index);
3980 const decl_inst = nav.srcInst(ip).resolve(ip).?;
3981 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);
3982 try wip_nav.declCommon(.{
3983 .decl = .decl_packed_struct,
3984 .generic_decl = .generic_decl_const,
3985 .decl_instance = .decl_instance_packed_struct,
3986 }, &nav, file, &decl);
3987 break :t true;
3988 } else t: {
3989 const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, file);
3990 try wip_nav.abbrevCode(if (loaded_struct.field_types.len > 0) .packed_struct_type else .empty_packed_struct_type);
3991 try diw.writeUleb128(file_gop.index);
3992 try wip_nav.strp(loaded_struct.name.toSlice(ip));
3993 break :t loaded_struct.field_types.len > 0;
3994 };
3995 try wip_nav.refType(.fromInterned(loaded_struct.packed_backing_int_type));
3996 var field_bit_offset: u16 = 0;
3997 for (0..loaded_struct.field_types.len) |field_index| {
3998 try wip_nav.abbrevCode(.packed_struct_field);
3999 try wip_nav.strp(loaded_struct.field_names.get(ip)[field_index].toSlice(ip));
4000 const field_type: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
4001 try wip_nav.refType(field_type);
4002 try diw.writeUleb128(field_bit_offset);
4003 field_bit_offset += @intCast(field_type.bitSize(zcu));
4004 }
4005 if (need_terminator) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
4006 },
4007 }
4008 },
4009 .union_type => {
4010 const loaded_union = ip.loadUnionType(value_index);
4011 const file = loaded_union.zir_index.resolveFile(ip);
4012 switch (loaded_union.layout) {
4013 .auto, .@"extern" => {
4014 const need_terminator: bool = if (loaded_union.name_nav.unwrap()) |nav_index| t: {
4015 const nav = ip.getNav(nav_index);
4016 const decl_inst = nav.srcInst(ip).resolve(ip).?;
4017 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);
4018 try wip_nav.declCommon(.{
4019 .decl = .decl_union,
4020 .generic_decl = .generic_decl_const,
4021 .decl_instance = .decl_instance_union,
4022 }, &nav, file, &decl);
4023 break :t true;
4024 } else t: {
4025 const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, file);
4026 try wip_nav.abbrevCode(if (loaded_union.field_types.len > 0) .union_type else .empty_union_type);
4027 try diw.writeUleb128(file_gop.index);
4028 try wip_nav.strp(loaded_union.name.toSlice(ip));
4029 break :t loaded_union.field_types.len > 0;
4030 };
4031 const union_layout = Type.getUnionLayout(loaded_union, zcu);
4032 try diw.writeUleb128(union_layout.abi_size);
4033 try diw.writeUleb128(union_layout.abi_align.toByteUnits().?);
4034 const loaded_tag = ip.loadEnumType(loaded_union.enum_tag_type);
4035 if (loaded_union.has_runtime_tag) {
4036 try wip_nav.abbrevCode(.tagged_union);
4037 try wip_nav.infoSectionOffset(
4038 .debug_info,
4039 wip_nav.unit,
4040 wip_nav.entry,
4041 @intCast(diw.end + dwarf.sectionOffsetBytes()),
4042 );
4043 {
4044 try wip_nav.abbrevCode(.generated_field);
4045 try wip_nav.strp("tag");
4046 try wip_nav.refType(.fromInterned(loaded_union.enum_tag_type));
4047 try diw.writeUleb128(union_layout.tagOffset());
4048
4049 for (0..loaded_union.field_types.len) |field_index| {
4050 try wip_nav.enumConstValue(loaded_tag, .{
4051 .sdata = .signed_tagged_union_field,
4052 .udata = .unsigned_tagged_union_field,
4053 .block = .big_tagged_union_field,
4054 }, field_index);
4055 {
4056 try wip_nav.abbrevCode(.struct_field);
4057 try wip_nav.strp(loaded_tag.field_names.get(ip)[field_index].toSlice(ip));
4058 const field_type: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
4059 try wip_nav.refType(field_type);
4060 try diw.writeUleb128(union_layout.payloadOffset());
4061 try diw.writeUleb128(loaded_union.field_aligns.getOrNone(ip, field_index).toByteUnits() orelse
4062 if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?);
4063 }
4064 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
4065 }
4066 }
4067 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
4068 } else for (0..loaded_union.field_types.len) |field_index| {
4069 try wip_nav.abbrevCode(.untagged_union_field);
4070 try wip_nav.strp(loaded_tag.field_names.get(ip)[field_index].toSlice(ip));
4071 const field_type: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
4072 try wip_nav.refType(field_type);
4073 try diw.writeUleb128(loaded_union.field_aligns.getOrNone(ip, field_index).toByteUnits() orelse
4074 if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?);
4075 }
4076 if (need_terminator) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
4077 },
4078 .@"packed" => {
4079 // TODO: debug info for packed unions
4080 try wip_nav.abbrevCode(.numeric_type);
4081 try wip_nav.strp(loaded_union.name.toSlice(ip));
4082 const backing_int_ty: Type = .fromInterned(loaded_union.packed_backing_int_type);
4083 const int_info = backing_int_ty.intInfo(zcu);
4084 try diw.writeByte(switch (int_info.signedness) {
4085 inline .signed, .unsigned => |signedness| @field(DW.ATE, @tagName(signedness)),
4086 });
4087 try diw.writeUleb128(int_info.bits);
4088 try diw.writeUleb128(backing_int_ty.abiSize(zcu));
4089 try diw.writeUleb128(backing_int_ty.abiAlignment(zcu).toByteUnits().?);
4090 },
4091 }
4092 },
38784093 .enum_type => {
3879 const loaded_enum = ip.loadEnumType(type_index);
3880 try wip_nav.abbrevCode(if (loaded_enum.names.len == 0) .generated_empty_enum_type else .generated_enum_type);
3881 try wip_nav.strp(name);
3882 try wip_nav.refType(.fromInterned(loaded_enum.tag_ty));
3883 for (0..loaded_enum.names.len) |field_index| {
3884 try wip_nav.enumConstValue(loaded_enum, .{
3885 .sdata = .signed_enum_field,
3886 .udata = .unsigned_enum_field,
3887 .block = .big_enum_field,
3888 }, field_index);
3889 try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip));
4094 const loaded_enum = ip.loadEnumType(value_index);
4095 if (loaded_enum.zir_index.unwrap()) |zir_index| {
4096 assert(loaded_enum.owner_union == .none);
4097 const file = zir_index.resolveFile(ip);
4098 if (loaded_enum.name_nav.unwrap()) |nav_index| {
4099 const nav = ip.getNav(nav_index);
4100 const decl_inst = nav.srcInst(ip).resolve(ip).?;
4101 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);
4102 try wip_nav.declCommon(if (loaded_enum.field_names.len > 0) .{
4103 .decl = .decl_enum,
4104 .generic_decl = .generic_decl_const,
4105 .decl_instance = .decl_instance_enum,
4106 } else .{
4107 .decl = .decl_empty_enum,
4108 .generic_decl = .generic_decl_const,
4109 .decl_instance = .decl_instance_empty_enum,
4110 }, &nav, file, &decl);
4111 } else {
4112 const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, file);
4113 try wip_nav.abbrevCode(if (loaded_enum.field_names.len > 0) .enum_type else .empty_enum_type);
4114 try diw.writeUleb128(file_gop.index);
4115 try wip_nav.strp(loaded_enum.name.toSlice(ip));
4116 }
4117 try wip_nav.refType(.fromInterned(loaded_enum.int_tag_type));
4118 for (0..loaded_enum.field_names.len) |field_index| {
4119 try wip_nav.enumConstValue(loaded_enum, .{
4120 .sdata = .signed_enum_field,
4121 .udata = .unsigned_enum_field,
4122 .block = .big_enum_field,
4123 }, field_index);
4124 try wip_nav.strp(loaded_enum.field_names.get(ip)[field_index].toSlice(ip));
4125 }
4126 if (loaded_enum.field_names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
4127 } else {
4128 assert(loaded_enum.owner_union != .none);
4129 try wip_nav.abbrevCode(if (loaded_enum.field_names.len == 0) .generated_empty_enum_type else .generated_enum_type);
4130 try wip_nav.strp(loaded_enum.name.toSlice(ip));
4131 try wip_nav.refType(.fromInterned(loaded_enum.int_tag_type));
4132 for (0..loaded_enum.field_names.len) |field_index| {
4133 try wip_nav.enumConstValue(loaded_enum, .{
4134 .sdata = .signed_enum_field,
4135 .udata = .unsigned_enum_field,
4136 .block = .big_enum_field,
4137 }, field_index);
4138 try wip_nav.strp(loaded_enum.field_names.get(ip)[field_index].toSlice(ip));
4139 }
4140 if (loaded_enum.field_names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
4141 }
4142 },
4143 .opaque_type => {
4144 const loaded_opaque = ip.loadOpaqueType(value_index);
4145 const file = loaded_opaque.zir_index.resolveFile(ip);
4146 if (loaded_opaque.name_nav.unwrap()) |nav_index| {
4147 const nav = ip.getNav(nav_index);
4148 const decl_inst = nav.srcInst(ip).resolve(ip).?;
4149 const decl = zcu.fileByIndex(file).zir.?.getDeclaration(decl_inst);
4150 try wip_nav.declCommon(.{
4151 .decl = .decl_namespace_struct,
4152 .generic_decl = .generic_decl_const,
4153 .decl_instance = .decl_instance_namespace_struct,
4154 }, &nav, file, &decl);
4155 } else {
4156 const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, file);
4157 try wip_nav.abbrevCode(.empty_struct_type);
4158 try diw.writeUleb128(file_gop.index);
4159 try wip_nav.strp(loaded_opaque.name.toSlice(ip));
38904160 }
3891 if (loaded_enum.names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
4161 try diw.writeByte(@intFromBool(true));
38924162 },
38934163 .func_type => |func_type| {
38944164 const is_nullary = func_type.param_types.len == 0 and !func_type.is_var_args;
38954165 try wip_nav.abbrevCode(if (is_nullary) .nullary_func_type else .func_type);
3896 try wip_nav.strp(name);
4166 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
38974167 const cc: DW.CC = cc: {
38984168 if (zcu.getTarget().cCallingConvention()) |cc| {
38994169 if (@as(std.builtin.CallingConvention.Tag, cc) == func_type.cc) {
......@@ -3975,7 +4245,7 @@ fn updateLazyType(
39754245 },
39764246 .error_set_type => |error_set_type| {
39774247 try wip_nav.abbrevCode(if (error_set_type.names.len == 0) .generated_empty_enum_type else .generated_enum_type);
3978 try wip_nav.strp(name);
4248 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
39794249 try wip_nav.refType(.fromInterned(try pt.intern(.{ .int_type = .{
39804250 .signedness = .unsigned,
39814251 .bits = zcu.errorSetBits(),
......@@ -3990,100 +4260,28 @@ fn updateLazyType(
39904260 },
39914261 .inferred_error_set_type => |func| {
39924262 try wip_nav.abbrevCode(.inferred_error_set_type);
3993 try wip_nav.strp(name);
4263 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
39944264 try wip_nav.refType(.fromInterned(switch (ip.funcIesResolvedUnordered(func)) {
39954265 .none => .anyerror_type,
39964266 else => |ies| ies,
39974267 }));
39984268 },
39994269
4000 // values, not types
4001 .simple_value,
4002 .variable,
4003 .@"extern",
4004 .func,
4005 .int,
4006 .err,
4007 .error_union,
4008 .enum_literal,
4009 .enum_tag,
4010 .empty_enum_value,
4011 .float,
4012 .ptr,
4013 .slice,
4014 .opt,
4015 .aggregate,
4016 .un,
4017 // memoization, not types
4018 .memoized_call,
4019 => unreachable,
4020 }
4021 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.written());
4022}
4023
4024fn updateLazyValue(
4025 dwarf: *Dwarf,
4026 pt: Zcu.PerThread,
4027 src_loc: Zcu.LazySrcLoc,
4028 value_index: InternPool.Index,
4029 pending_lazy: *WipNav.PendingLazy,
4030) (UpdateError || Writer.Error)!void {
4031 const zcu = pt.zcu;
4032 const ip = &zcu.intern_pool;
4033 assert(ip.typeOf(value_index) != .type_type);
4034 log.debug("updateLazyValue(@as({f}, {f}))", .{
4035 Value.fromInterned(value_index).typeOf(zcu).fmt(pt),
4036 Value.fromInterned(value_index).fmtValue(pt),
4037 });
4038 var wip_nav: WipNav = .{
4039 .dwarf = dwarf,
4040 .pt = pt,
4041 .unit = .main,
4042 .entry = dwarf.values.get(value_index).?,
4043 .any_children = false,
4044 .func = .none,
4045 .func_sym_index = undefined,
4046 .func_high_pc = undefined,
4047 .blocks = undefined,
4048 .cfi = undefined,
4049 .debug_frame = .init(dwarf.gpa),
4050 .debug_info = .init(dwarf.gpa),
4051 .debug_line = .init(dwarf.gpa),
4052 .debug_loclists = .init(dwarf.gpa),
4053 .pending_lazy = pending_lazy.*,
4054 };
4055 defer {
4056 pending_lazy.* = wip_nav.pending_lazy;
4057 wip_nav.pending_lazy = .empty;
4058 wip_nav.deinit();
4059 }
4060 const diw = &wip_nav.debug_info.writer;
4061 var big_int_space: Value.BigIntSpace = undefined;
4062 switch (ip.indexToKey(value_index)) {
4063 .int_type,
4064 .ptr_type,
4065 .array_type,
4066 .vector_type,
4067 .opt_type,
4068 .anyframe_type,
4069 .error_union_type,
4070 .simple_type,
4071 .struct_type,
4072 .tuple_type,
4073 .union_type,
4074 .opaque_type,
4075 .enum_type,
4076 .func_type,
4077 .error_set_type,
4078 .inferred_error_set_type,
4079 => unreachable, // already handled
40804270 .undef => |ty| {
40814271 try wip_nav.abbrevCode(.undefined_comptime_value);
40824272 try wip_nav.refType(.fromInterned(ty));
40834273 },
4084 .simple_value => unreachable, // opv state
4085 .variable, .@"extern" => unreachable, // not a value
4086 .func => unreachable, // already handled
4274 .simple_value => |simple_value| switch (simple_value) {
4275 .void => unreachable, // opv state
4276 .true, .false => unreachable, // runtime bits
4277 .@"unreachable" => unreachable, // not a value
4278 .null => {
4279 // TODO: proper representation for this
4280 try wip_nav.abbrevCode(.undefined_comptime_value);
4281 try wip_nav.refType(.null);
4282 },
4283 },
4284 .variable => unreachable, // not a value
40874285 .int => |int| {
40884286 try wip_nav.bigIntConstValue(.{
40894287 .sdata = .sdata_comptime_value,
......@@ -4092,6 +4290,15 @@ fn updateLazyValue(
40924290 }, .fromInterned(int.ty), Value.fromInterned(value_index).toBigInt(&big_int_space, zcu));
40934291 try wip_nav.refType(.fromInterned(int.ty));
40944292 },
4293 .bitpack => |bitpack| {
4294 const backing_int_val: Value = .fromInterned(bitpack.backing_int_val);
4295 try wip_nav.bigIntConstValue(.{
4296 .sdata = .sdata_comptime_value,
4297 .udata = .udata_comptime_value,
4298 .block = .block_comptime_value,
4299 }, backing_int_val.typeOf(zcu), backing_int_val.toBigInt(&big_int_space, zcu));
4300 try wip_nav.refType(.fromInterned(bitpack.ty));
4301 },
40954302 .err => |err| {
40964303 try wip_nav.abbrevCode(.udata_comptime_value);
40974304 try wip_nav.refType(.fromInterned(err.ty));
......@@ -4117,7 +4324,7 @@ fn updateLazyValue(
41174324 .payload => |payload_val| {
41184325 const payload_type: Type = .fromInterned(ip.typeOf(payload_val));
41194326 const has_runtime_bits = payload_type.hasRuntimeBits(zcu);
4120 const has_comptime_state = payload_type.comptimeOnly(zcu) and try payload_type.onePossibleValue(pt) == null;
4327 const has_comptime_state = payload_type.comptimeOnly(zcu);
41214328 try wip_nav.abbrevCode(if (has_comptime_state)
41224329 .comptime_value_field_comptime_state
41234330 else if (has_runtime_bits)
......@@ -4153,7 +4360,6 @@ fn updateLazyValue(
41534360 }, .fromInterned(int.ty), Value.fromInterned(value_index).toBigInt(&big_int_space, zcu));
41544361 try wip_nav.refType(.fromInterned(enum_tag.ty));
41554362 },
4156 .empty_enum_value => unreachable,
41574363 .float => |float| {
41584364 switch (float.storage) {
41594365 .f16 => |f16_val| {
......@@ -4194,11 +4400,11 @@ fn updateLazyValue(
41944400 var byte_offset = ptr.byte_offset;
41954401 const base_unit, const base_entry = while (true) {
41964402 const base_ptr, const access: Access = base_ptr_access: switch (base_addr) {
4197 .nav => |nav_index| break try wip_nav.getNavEntry(nav_index),
4403 .nav => |nav_index| break try dwarf.getNavEntry(nav_index),
41984404 .comptime_alloc, .comptime_field => unreachable,
41994405 .uav => |uav| {
42004406 const uav_ty: Type = .fromInterned(ip.typeOf(uav.val));
4201 if (try uav_ty.onePossibleValue(pt)) |_| {
4407 if (uav_ty.classify(zcu) == .one_possible_value) {
42024408 try wip_nav.abbrevCode(if (zero_bit_accesses.items.len > 0)
42034409 .aggregate_udata_comptime_value
42044410 else
......@@ -4311,22 +4517,12 @@ fn updateLazyValue(
43114517 switch (optRepr(opt_child_type, zcu)) {
43124518 .opv_null => try diw.writeUleb128(0),
43134519 .unpacked => try wip_nav.blockValue(src_loc, .makeBool(opt.val != .none)),
4314 .error_set => try wip_nav.blockValue(src_loc, .fromInterned(value_index)),
4315 .pointer => if (opt_child_type.comptimeOnly(zcu)) {
4316 var buf: [8]u8 = undefined;
4317 const bytes = buf[0..@divExact(zcu.getTarget().ptrBitWidth(), 8)];
4318 dwarf.writeInt(bytes, switch (opt.val) {
4319 .none => 0,
4320 else => opt_child_type.ptrAlignment(zcu).toByteUnits().?,
4321 });
4322 try diw.writeUleb128(bytes.len);
4323 try diw.writeAll(bytes);
4324 } else try wip_nav.blockValue(src_loc, .fromInterned(value_index)),
4520 .error_set, .pointer => try wip_nav.blockValue(src_loc, .fromInterned(value_index)),
43254521 }
43264522 }
43274523 if (opt.val != .none) child_field: {
43284524 const has_runtime_bits = opt_child_type.hasRuntimeBits(zcu);
4329 const has_comptime_state = opt_child_type.comptimeOnly(zcu) and try opt_child_type.onePossibleValue(pt) == null;
4525 const has_comptime_state = opt_child_type.comptimeOnly(zcu);
43304526 try wip_nav.abbrevCode(if (has_comptime_state)
43314527 .comptime_value_field_comptime_state
43324528 else if (has_runtime_bits)
......@@ -4349,17 +4545,17 @@ fn updateLazyValue(
43494545 const loaded_struct_type = ip.loadStructType(aggregate.ty);
43504546 assert(loaded_struct_type.layout == .auto);
43514547 for (0..loaded_struct_type.field_types.len) |field_index| {
4352 if (loaded_struct_type.fieldIsComptime(ip, field_index)) continue;
4548 if (loaded_struct_type.field_is_comptime_bits.get(ip, field_index)) continue;
43534549 const field_type: Type = .fromInterned(loaded_struct_type.field_types.get(ip)[field_index]);
43544550 const has_runtime_bits = field_type.hasRuntimeBits(zcu);
4355 const has_comptime_state = field_type.comptimeOnly(zcu) and try field_type.onePossibleValue(pt) == null;
4551 const has_comptime_state = field_type.comptimeOnly(zcu);
43564552 try wip_nav.abbrevCode(if (has_comptime_state)
43574553 .comptime_value_field_comptime_state
43584554 else if (has_runtime_bits)
43594555 .comptime_value_field_runtime_bits
43604556 else
43614557 continue);
4362 try wip_nav.strp(loaded_struct_type.fieldName(ip, field_index).toSlice(ip));
4558 try wip_nav.strp(loaded_struct_type.field_names.get(ip)[field_index].toSlice(ip));
43634559 const field_value: Value = .fromInterned(switch (aggregate.storage) {
43644560 .bytes => unreachable,
43654561 .elems => |elems| elems[field_index],
......@@ -4375,7 +4571,7 @@ fn updateLazyValue(
43754571 if (tuple_type.values.get(ip)[field_index] != .none) continue;
43764572 const field_type: Type = .fromInterned(tuple_type.types.get(ip)[field_index]);
43774573 const has_runtime_bits = field_type.hasRuntimeBits(zcu);
4378 const has_comptime_state = field_type.comptimeOnly(zcu) and try field_type.onePossibleValue(pt) == null;
4574 const has_comptime_state = field_type.comptimeOnly(zcu);
43794575 try wip_nav.abbrevCode(if (has_comptime_state)
43804576 .comptime_value_field_comptime_state
43814577 else if (has_runtime_bits)
......@@ -4400,7 +4596,7 @@ fn updateLazyValue(
44004596 inline .array_type, .vector_type => |sequence_type| {
44014597 const child_type: Type = .fromInterned(sequence_type.child);
44024598 const has_runtime_bits = child_type.hasRuntimeBits(zcu);
4403 const has_comptime_state = child_type.comptimeOnly(zcu) and try child_type.onePossibleValue(pt) == null;
4599 const has_comptime_state = child_type.comptimeOnly(zcu);
44044600 for (switch (aggregate.storage) {
44054601 .bytes => unreachable,
44064602 .elems => |elems| elems,
......@@ -4427,12 +4623,12 @@ fn updateLazyValue(
44274623 try wip_nav.refType(.fromInterned(un.ty));
44284624 field: {
44294625 const loaded_union_type = ip.loadUnionType(un.ty);
4430 assert(loaded_union_type.flagsUnordered(ip).layout == .auto);
4626 assert(loaded_union_type.layout == .auto);
44314627 const field_index = zcu.unionTagFieldIndex(loaded_union_type, Value.fromInterned(un.tag)).?;
44324628 const field_ty: Type = .fromInterned(loaded_union_type.field_types.get(ip)[field_index]);
4433 const field_name = loaded_union_type.loadTagType(ip).names.get(ip)[field_index];
4629 const field_name = ip.loadEnumType(loaded_union_type.enum_tag_type).field_names.get(ip)[field_index];
44344630 const has_runtime_bits = field_ty.hasRuntimeBits(zcu);
4435 const has_comptime_state = field_ty.comptimeOnly(zcu) and try field_ty.onePossibleValue(pt) == null;
4631 const has_comptime_state = field_ty.comptimeOnly(zcu);
44364632 try wip_nav.abbrevCode(if (has_comptime_state)
44374633 .comptime_value_field_comptime_state
44384634 else if (has_runtime_bits)
......@@ -4449,7 +4645,8 @@ fn updateLazyValue(
44494645 },
44504646 .memoized_call => unreachable, // not a value
44514647 }
4452 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.written());
4648 try dwarf.debug_info.section.replaceEntry(unit, entry, dwarf, wip_nav.debug_info.written());
4649 try dwarf.debug_loclists.section.replaceEntry(unit, entry, dwarf, wip_nav.debug_loclists.written());
44534650}
44544651
44554652fn optRepr(opt_child_type: Type, zcu: *const Zcu) enum { unpacked, opv_null, error_set, pointer } {
......@@ -4464,312 +4661,6 @@ fn optRepr(opt_child_type: Type, zcu: *const Zcu) enum { unpacked, opv_null, err
44644661 };
44654662}
44664663
4467pub fn updateContainerType(
4468 dwarf: *Dwarf,
4469 pt: Zcu.PerThread,
4470 type_index: InternPool.Index,
4471) UpdateError!void {
4472 return dwarf.updateContainerTypeWriterError(pt, type_index) catch |err| switch (err) {
4473 error.WriteFailed => error.OutOfMemory,
4474 else => |e| e,
4475 };
4476}
4477fn updateContainerTypeWriterError(
4478 dwarf: *Dwarf,
4479 pt: Zcu.PerThread,
4480 type_index: InternPool.Index,
4481) (UpdateError || Writer.Error)!void {
4482 const zcu = pt.zcu;
4483 const ip = &zcu.intern_pool;
4484 const ty: Type = .fromInterned(type_index);
4485 const ty_src_loc = ty.srcLoc(zcu);
4486 log.debug("updateContainerType({f})", .{ty.fmt(pt)});
4487
4488 const inst_info = ty.typeDeclInst(zcu).?.resolveFull(ip).?;
4489 const file = zcu.fileByIndex(inst_info.file);
4490 const unit = try dwarf.getUnit(file.mod.?);
4491 const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file);
4492 if (inst_info.inst == .main_struct_inst) {
4493 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, type_index);
4494 if (!type_gop.found_existing) type_gop.value_ptr.* = try dwarf.addCommonEntry(unit);
4495 var wip_nav: WipNav = .{
4496 .dwarf = dwarf,
4497 .pt = pt,
4498 .unit = unit,
4499 .entry = type_gop.value_ptr.*,
4500 .any_children = false,
4501 .func = .none,
4502 .func_sym_index = undefined,
4503 .func_high_pc = undefined,
4504 .blocks = undefined,
4505 .cfi = undefined,
4506 .debug_frame = .init(dwarf.gpa),
4507 .debug_info = .init(dwarf.gpa),
4508 .debug_line = .init(dwarf.gpa),
4509 .debug_loclists = .init(dwarf.gpa),
4510 .pending_lazy = .empty,
4511 };
4512 defer wip_nav.deinit();
4513
4514 const loaded_struct = ip.loadStructType(type_index);
4515
4516 const diw = &wip_nav.debug_info.writer;
4517 try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .empty_file else .file);
4518 try diw.writeUleb128(file_gop.index);
4519 try wip_nav.strp(loaded_struct.name.toSlice(ip));
4520 if (loaded_struct.field_types.len > 0) {
4521 try diw.writeUleb128(ty.abiSize(zcu));
4522 try diw.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);
4523 for (0..loaded_struct.field_types.len) |field_index| {
4524 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
4525 const field_init = loaded_struct.fieldInit(ip, field_index);
4526 assert(!(is_comptime and field_init == .none));
4527 const field_type: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
4528 const has_runtime_bits, const has_comptime_state = switch (field_init) {
4529 .none => .{ false, false },
4530 else => .{
4531 field_type.hasRuntimeBits(zcu),
4532 field_type.comptimeOnly(zcu) and try field_type.onePossibleValue(pt) == null,
4533 },
4534 };
4535 try wip_nav.abbrevCode(if (is_comptime)
4536 if (has_comptime_state)
4537 .struct_field_comptime_comptime_state
4538 else if (has_runtime_bits)
4539 .struct_field_comptime_runtime_bits
4540 else
4541 .struct_field_comptime
4542 else if (field_init != .none)
4543 if (has_comptime_state)
4544 .struct_field_default_comptime_state
4545 else if (has_runtime_bits)
4546 .struct_field_default_runtime_bits
4547 else
4548 .struct_field
4549 else
4550 .struct_field);
4551 try wip_nav.strp(loaded_struct.fieldName(ip, field_index).toSlice(ip));
4552 try wip_nav.refType(field_type);
4553 if (!is_comptime) {
4554 try diw.writeUleb128(loaded_struct.offsets.get(ip)[field_index]);
4555 try diw.writeUleb128(loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
4556 field_type.abiAlignment(zcu).toByteUnits().?);
4557 }
4558 if (has_comptime_state)
4559 try wip_nav.refValue(.fromInterned(field_init))
4560 else if (has_runtime_bits)
4561 try wip_nav.blockValue(ty_src_loc, .fromInterned(field_init));
4562 }
4563 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
4564 }
4565
4566 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.written());
4567 try wip_nav.updateLazy(ty_src_loc);
4568 } else {
4569 {
4570 // Note that changes to ZIR instruction tracking only need to update this code
4571 // if a newly-tracked instruction can be a type's owner `zir_index`.
4572 comptime assert(Zir.inst_tracking_version == 0);
4573
4574 const decl_inst = file.zir.?.instructions.get(@intFromEnum(inst_info.inst));
4575 const name_strat: Zir.Inst.NameStrategy = switch (decl_inst.tag) {
4576 .struct_init, .struct_init_ref, .struct_init_anon => .anon,
4577 .extended => switch (decl_inst.data.extended.opcode) {
4578 .struct_decl => @as(Zir.Inst.StructDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
4579 .enum_decl => @as(Zir.Inst.EnumDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
4580 .union_decl => @as(Zir.Inst.UnionDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
4581 .opaque_decl => @as(Zir.Inst.OpaqueDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
4582
4583 .reify_enum,
4584 .reify_struct,
4585 .reify_union,
4586 => @enumFromInt(decl_inst.data.extended.small),
4587
4588 else => unreachable,
4589 },
4590 else => unreachable,
4591 };
4592 if (name_strat == .parent) return;
4593 }
4594
4595 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, type_index);
4596 if (!type_gop.found_existing) type_gop.value_ptr.* = try dwarf.addCommonEntry(unit);
4597 var wip_nav: WipNav = .{
4598 .dwarf = dwarf,
4599 .pt = pt,
4600 .unit = unit,
4601 .entry = type_gop.value_ptr.*,
4602 .any_children = false,
4603 .func = .none,
4604 .func_sym_index = undefined,
4605 .func_high_pc = undefined,
4606 .blocks = undefined,
4607 .cfi = undefined,
4608 .debug_frame = .init(dwarf.gpa),
4609 .debug_info = .init(dwarf.gpa),
4610 .debug_line = .init(dwarf.gpa),
4611 .debug_loclists = .init(dwarf.gpa),
4612 .pending_lazy = .empty,
4613 };
4614 defer wip_nav.deinit();
4615 const diw = &wip_nav.debug_info.writer;
4616 const name = try std.fmt.allocPrint(dwarf.gpa, "{f}", .{ty.fmt(pt)});
4617 defer dwarf.gpa.free(name);
4618
4619 switch (ip.indexToKey(type_index)) {
4620 .struct_type => {
4621 const loaded_struct = ip.loadStructType(type_index);
4622 switch (loaded_struct.layout) {
4623 .auto, .@"extern" => {
4624 try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .empty_struct_type else .struct_type);
4625 try diw.writeUleb128(file_gop.index);
4626 try wip_nav.strp(name);
4627 if (loaded_struct.field_types.len == 0) try diw.writeByte(@intFromBool(false)) else {
4628 try diw.writeUleb128(ty.abiSize(zcu));
4629 try diw.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);
4630 for (0..loaded_struct.field_types.len) |field_index| {
4631 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
4632 const field_init = loaded_struct.fieldInit(ip, field_index);
4633 assert(!(is_comptime and field_init == .none));
4634 const field_type: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
4635 const has_runtime_bits, const has_comptime_state = switch (field_init) {
4636 .none => .{ false, false },
4637 else => .{
4638 field_type.hasRuntimeBits(zcu),
4639 field_type.comptimeOnly(zcu) and try field_type.onePossibleValue(pt) == null,
4640 },
4641 };
4642 try wip_nav.abbrevCode(if (is_comptime)
4643 if (has_comptime_state)
4644 .struct_field_comptime_comptime_state
4645 else if (has_runtime_bits)
4646 .struct_field_comptime_runtime_bits
4647 else
4648 .struct_field_comptime
4649 else if (field_init != .none)
4650 if (has_comptime_state)
4651 .struct_field_default_comptime_state
4652 else if (has_runtime_bits)
4653 .struct_field_default_runtime_bits
4654 else
4655 .struct_field
4656 else
4657 .struct_field);
4658 try wip_nav.strp(loaded_struct.fieldName(ip, field_index).toSlice(ip));
4659 try wip_nav.refType(field_type);
4660 if (!is_comptime) {
4661 try diw.writeUleb128(loaded_struct.offsets.get(ip)[field_index]);
4662 try diw.writeUleb128(loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
4663 field_type.abiAlignment(zcu).toByteUnits().?);
4664 }
4665 if (has_comptime_state)
4666 try wip_nav.refValue(.fromInterned(field_init))
4667 else if (has_runtime_bits)
4668 try wip_nav.blockValue(ty_src_loc, .fromInterned(field_init));
4669 }
4670 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
4671 }
4672 },
4673 .@"packed" => {
4674 try wip_nav.abbrevCode(if (loaded_struct.field_types.len > 0) .packed_struct_type else .empty_packed_struct_type);
4675 try diw.writeUleb128(file_gop.index);
4676 try wip_nav.strp(name);
4677 try wip_nav.refType(.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
4678 var field_bit_offset: u16 = 0;
4679 for (0..loaded_struct.field_types.len) |field_index| {
4680 try wip_nav.abbrevCode(.packed_struct_field);
4681 try wip_nav.strp(loaded_struct.fieldName(ip, field_index).toSlice(ip));
4682 const field_type: Type = .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
4683 try wip_nav.refType(field_type);
4684 try diw.writeUleb128(field_bit_offset);
4685 field_bit_offset += @intCast(field_type.bitSize(zcu));
4686 }
4687 if (loaded_struct.field_types.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
4688 },
4689 }
4690 },
4691 .enum_type => {
4692 const loaded_enum = ip.loadEnumType(type_index);
4693 try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .enum_type else .empty_enum_type);
4694 try diw.writeUleb128(file_gop.index);
4695 try wip_nav.strp(name);
4696 try wip_nav.refType(.fromInterned(loaded_enum.tag_ty));
4697 for (0..loaded_enum.names.len) |field_index| {
4698 try wip_nav.enumConstValue(loaded_enum, .{
4699 .sdata = .signed_enum_field,
4700 .udata = .unsigned_enum_field,
4701 .block = .big_enum_field,
4702 }, field_index);
4703 try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip));
4704 }
4705 if (loaded_enum.names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
4706 },
4707 .union_type => {
4708 const loaded_union = ip.loadUnionType(type_index);
4709 try wip_nav.abbrevCode(if (loaded_union.field_types.len > 0) .union_type else .empty_union_type);
4710 try diw.writeUleb128(file_gop.index);
4711 try wip_nav.strp(name);
4712 const union_layout = Type.getUnionLayout(loaded_union, zcu);
4713 try diw.writeUleb128(union_layout.abi_size);
4714 try diw.writeUleb128(union_layout.abi_align.toByteUnits().?);
4715 const loaded_tag = loaded_union.loadTagType(ip);
4716 if (loaded_union.hasTag(ip)) {
4717 try wip_nav.abbrevCode(.tagged_union);
4718 try wip_nav.infoSectionOffset(
4719 .debug_info,
4720 wip_nav.unit,
4721 wip_nav.entry,
4722 @intCast(diw.end + dwarf.sectionOffsetBytes()),
4723 );
4724 {
4725 try wip_nav.abbrevCode(.generated_field);
4726 try wip_nav.strp("tag");
4727 try wip_nav.refType(.fromInterned(loaded_union.enum_tag_ty));
4728 try diw.writeUleb128(union_layout.tagOffset());
4729
4730 for (0..loaded_union.field_types.len) |field_index| {
4731 try wip_nav.enumConstValue(loaded_tag, .{
4732 .sdata = .signed_tagged_union_field,
4733 .udata = .unsigned_tagged_union_field,
4734 .block = .big_tagged_union_field,
4735 }, field_index);
4736 {
4737 try wip_nav.abbrevCode(.struct_field);
4738 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
4739 const field_type: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
4740 try wip_nav.refType(field_type);
4741 try diw.writeUleb128(union_layout.payloadOffset());
4742 try diw.writeUleb128(loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
4743 if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?);
4744 }
4745 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
4746 }
4747 }
4748 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
4749 } else for (0..loaded_union.field_types.len) |field_index| {
4750 try wip_nav.abbrevCode(.untagged_union_field);
4751 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
4752 const field_type: Type = .fromInterned(loaded_union.field_types.get(ip)[field_index]);
4753 try wip_nav.refType(field_type);
4754 try diw.writeUleb128(loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
4755 if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?);
4756 }
4757 if (loaded_union.field_types.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
4758 },
4759 .opaque_type => {
4760 try wip_nav.abbrevCode(.empty_struct_type);
4761 try diw.writeUleb128(file_gop.index);
4762 try wip_nav.strp(name);
4763 try diw.writeByte(@intFromBool(true));
4764 },
4765 else => unreachable,
4766 }
4767 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.written());
4768 try dwarf.debug_loclists.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_loclists.written());
4769 try wip_nav.updateLazy(ty_src_loc);
4770 }
4771}
4772
47734664pub fn updateLineNumber(dwarf: *Dwarf, zcu: *Zcu, zir_index: InternPool.TrackedInst.Index) UpdateError!void {
47744665 const comp = dwarf.bin_file.comp;
47754666 const io = comp.io;
......@@ -4832,14 +4723,15 @@ fn flushWriterError(dwarf: *Dwarf, pt: Zcu.PerThread) (FlushError || Writer.Erro
48324723 const comp = dwarf.bin_file.comp;
48334724 const io = comp.io;
48344725
4726 // Update `anyerror` based on the finished global error set.
48354727 {
4836 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, .anyerror_type);
4837 if (!type_gop.found_existing) type_gop.value_ptr.* = try dwarf.addCommonEntry(.main);
4728 const index = try dwarf.const_pool.get(pt, .{ .dwarf = dwarf }, .anyerror_type);
4729 const unit, const entry = dwarf.values.items[@intFromEnum(index)];
48384730 var wip_nav: WipNav = .{
48394731 .dwarf = dwarf,
48404732 .pt = pt,
4841 .unit = .main,
4842 .entry = type_gop.value_ptr.*,
4733 .unit = unit,
4734 .entry = entry,
48434735 .any_children = false,
48444736 .func = .none,
48454737 .func_sym_index = undefined,
......@@ -4850,7 +4742,6 @@ fn flushWriterError(dwarf: *Dwarf, pt: Zcu.PerThread) (FlushError || Writer.Erro
48504742 .debug_info = .init(dwarf.gpa),
48514743 .debug_line = .init(dwarf.gpa),
48524744 .debug_loclists = .init(dwarf.gpa),
4853 .pending_lazy = .empty,
48544745 };
48554746 defer wip_nav.deinit();
48564747 const diw = &wip_nav.debug_info.writer;
......@@ -4868,7 +4759,7 @@ fn flushWriterError(dwarf: *Dwarf, pt: Zcu.PerThread) (FlushError || Writer.Erro
48684759 }
48694760 if (global_error_set_names.len > 0) try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
48704761 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.written());
4871 try wip_nav.updateLazy(.unneeded);
4762 try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf });
48724763 }
48734764
48744765 for (dwarf.mods.keys(), dwarf.mods.values()) |mod, *mod_info| {
......@@ -5316,6 +5207,8 @@ const AbbrevCode = enum {
53165207 inferred_error_set_type,
53175208 ptr_type,
53185209 ptr_sentinel_type,
5210 ptr_aligned_type,
5211 ptr_aligned_sentinel_type,
53195212 is_const,
53205213 is_volatile,
53215214 array_type,
......@@ -5952,12 +5845,29 @@ const AbbrevCode = enum {
59525845 .tag = .pointer_type,
59535846 .attrs = &.{
59545847 .{ .name, .strp },
5955 .{ .alignment, .udata },
59565848 .{ .address_class, .data1 },
59575849 .{ .type, .ref_addr },
59585850 },
59595851 },
59605852 .ptr_sentinel_type = .{
5853 .tag = .pointer_type,
5854 .attrs = &.{
5855 .{ .name, .strp },
5856 .{ .ZIG_sentinel, .block },
5857 .{ .address_class, .data1 },
5858 .{ .type, .ref_addr },
5859 },
5860 },
5861 .ptr_aligned_type = .{
5862 .tag = .pointer_type,
5863 .attrs = &.{
5864 .{ .name, .strp },
5865 .{ .alignment, .udata },
5866 .{ .address_class, .data1 },
5867 .{ .type, .ref_addr },
5868 },
5869 },
5870 .ptr_aligned_sentinel_type = .{
59615871 .tag = .pointer_type,
59625872 .attrs = &.{
59635873 .{ .name, .strp },
src/link/Elf.zig+2-12
......@@ -1711,23 +1711,13 @@ pub fn updateContainerType(
17111711 self: *Elf,
17121712 pt: Zcu.PerThread,
17131713 ty: InternPool.Index,
1714 success: bool,
17141715) link.File.UpdateContainerTypeError!void {
17151716 if (build_options.skip_non_native and builtin.object_format != .elf) {
17161717 @panic("Attempted to compile for object format that was disabled by build configuration");
17171718 }
1718 const zcu = pt.zcu;
1719 const gpa = zcu.gpa;
1720 return self.zigObjectPtr().?.updateContainerType(pt, ty) catch |err| switch (err) {
1719 return self.zigObjectPtr().?.updateContainerType(pt, ty, success) catch |err| switch (err) {
17211720 error.OutOfMemory => return error.OutOfMemory,
1722 else => |e| {
1723 try zcu.failed_types.putNoClobber(gpa, ty, try Zcu.ErrorMsg.create(
1724 gpa,
1725 zcu.typeSrcLoc(ty),
1726 "failed to update container type: {s}",
1727 .{@errorName(e)},
1728 ));
1729 return error.TypeFailureReported;
1730 },
17311721 };
17321722}
17331723
src/link/Elf/Object.zig+1-1
......@@ -775,7 +775,7 @@ pub fn checkDuplicates(self: *Object, dupes: anytype, elf_file: *Elf) error{OutO
775775
776776 const gop = try dupes.getOrPut(self.symbols_resolver.items[i]);
777777 if (!gop.found_existing) {
778 gop.value_ptr.* = .{};
778 gop.value_ptr.* = .empty;
779779 }
780780 try gop.value_ptr.append(elf_file.base.comp.gpa, self.index);
781781 }
src/link/Elf/ZigObject.zig+6-5
......@@ -84,7 +84,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void {
8484 const ptr_size = elf_file.ptrWidthBytes();
8585
8686 try self.atoms.append(gpa, .{ .extra_index = try self.addAtomExtra(gpa, .{}) }); // null input section
87 try self.relocs.append(gpa, .{}); // null relocs section
87 try self.relocs.append(gpa, .empty); // null relocs section
8888 try self.strtab.buffer.append(gpa, 0);
8989
9090 {
......@@ -546,7 +546,7 @@ fn newAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Atom.Index {
546546 atom_ptr.name_offset = name_off;
547547
548548 const relocs_index: u32 = @intCast(self.relocs.items.len);
549 self.relocs.addOneAssumeCapacity().* = .{};
549 self.relocs.addOneAssumeCapacity().* = .empty;
550550 atom_ptr.relocs_section_index = relocs_index;
551551
552552 return index;
......@@ -730,7 +730,7 @@ pub fn checkDuplicates(self: *ZigObject, dupes: anytype, elf_file: *Elf) error{O
730730
731731 const gop = try dupes.getOrPut(self.symbols_resolver.items[i]);
732732 if (!gop.found_existing) {
733 gop.value_ptr.* = .{};
733 gop.value_ptr.* = .empty;
734734 }
735735 try gop.value_ptr.append(elf_file.base.comp.gpa, self.index);
736736 }
......@@ -1479,7 +1479,7 @@ fn updateTlv(
14791479
14801480 log.debug("updateTlv {f}({d})", .{ nav.fqn.fmt(ip), nav_index });
14811481
1482 const required_alignment = pt.navAlignment(nav_index);
1482 const required_alignment = zcu.navAlignment(nav_index);
14831483
14841484 const sym = self.symbol(sym_index);
14851485 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
......@@ -1719,11 +1719,12 @@ pub fn updateContainerType(
17191719 self: *ZigObject,
17201720 pt: Zcu.PerThread,
17211721 ty: InternPool.Index,
1722 success: bool,
17221723) !void {
17231724 const tracy = trace(@src());
17241725 defer tracy.end();
17251726
1726 if (self.dwarf) |*dwarf| try dwarf.updateContainerType(pt, ty);
1727 if (self.dwarf) |*dwarf| try dwarf.updateContainerType(pt, ty, success);
17271728}
17281729
17291730fn updateLazySymbol(
src/link/Elf2.zig+1-1
......@@ -2906,7 +2906,7 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)
29062906 try elf.nodes.ensureUnusedCapacity(gpa, 1);
29072907 const sec_si = elf.navSection(ip, nav.status.fully_resolved);
29082908 const ni = try elf.mf.addLastChildNode(gpa, sec_si.node(elf), .{
2909 .alignment = pt.navAlignment(nav_index).toStdMem(),
2909 .alignment = zcu.navAlignment(nav_index).toStdMem(),
29102910 .moved = true,
29112911 });
29122912 elf.nodes.appendAssumeCapacity(.{ .nav = nmi });
src/link/MachO/Atom.zig+1-1
......@@ -561,7 +561,7 @@ fn reportUndefSymbol(self: Atom, rel: Relocation, macho_file: *MachO) !bool {
561561 defer macho_file.undefs_mutex.unlock(io);
562562 const gop = try macho_file.undefs.getOrPut(gpa, file.getGlobals()[rel.target]);
563563 if (!gop.found_existing) {
564 gop.value_ptr.* = .{ .refs = .{} };
564 gop.value_ptr.* = .{ .refs = .empty };
565565 }
566566 try gop.value_ptr.refs.append(gpa, .{ .index = self.atom_index, .file = self.file });
567567 return true;
src/link/MachO/ZigObject.zig+7-7
......@@ -3,7 +3,7 @@ data: std.ArrayList(u8) = .empty,
33basename: []const u8,
44index: File.Index,
55
6symtab: std.MultiArrayList(Nlist) = .{},
6symtab: std.MultiArrayList(Nlist) = .empty,
77strtab: StringTable = .{},
88
99symbols: std.ArrayList(Symbol) = .empty,
......@@ -29,7 +29,7 @@ uavs: UavTable = .{},
2929tlv_initializers: TlvInitializerTable = .{},
3030
3131/// A table of relocations.
32relocs: RelocationTable = .{},
32relocs: RelocationTable = .empty,
3333
3434dwarf: ?Dwarf = null,
3535
......@@ -150,7 +150,7 @@ fn newAtom(self: *ZigObject, allocator: Allocator, name: MachO.String, macho_fil
150150 atom.name = name;
151151
152152 const relocs_index = @as(u32, @intCast(self.relocs.items.len));
153 self.relocs.addOneAssumeCapacity().* = .{};
153 self.relocs.addOneAssumeCapacity().* = .empty;
154154 atom.addExtra(.{ .rel_index = relocs_index, .rel_count = 0 }, macho_file);
155155
156156 return index;
......@@ -925,7 +925,7 @@ pub fn updateNav(
925925
926926 const sect_index = try self.getNavOutputSection(macho_file, zcu, nav_index, code);
927927 if (isThreadlocal(macho_file, nav_index))
928 try self.updateTlv(macho_file, pt, nav_index, sym_index, sect_index, code)
928 try self.updateTlv(macho_file, zcu, nav_index, sym_index, sect_index, code)
929929 else
930930 try self.updateNavCode(macho_file, pt, nav_index, sym_index, sect_index, code);
931931
......@@ -1030,13 +1030,13 @@ fn updateNavCode(
10301030fn updateTlv(
10311031 self: *ZigObject,
10321032 macho_file: *MachO,
1033 pt: Zcu.PerThread,
1033 zcu: *Zcu,
10341034 nav_index: InternPool.Nav.Index,
10351035 sym_index: Symbol.Index,
10361036 sect_index: u8,
10371037 code: []const u8,
10381038) !void {
1039 const ip = &pt.zcu.intern_pool;
1039 const ip = &zcu.intern_pool;
10401040 const nav = ip.getNav(nav_index);
10411041
10421042 log.debug("updateTlv {f} (0x{x})", .{ nav.fqn.fmt(ip), nav_index });
......@@ -1045,7 +1045,7 @@ fn updateTlv(
10451045 const init_sym_index = try self.createTlvInitializer(
10461046 macho_file,
10471047 nav.fqn.toSlice(ip),
1048 pt.navAlignment(nav_index),
1048 zcu.navAlignment(nav_index),
10491049 sect_index,
10501050 code,
10511051 );
src/link/MachO/file.zig+1-1
......@@ -258,7 +258,7 @@ pub const File = union(enum) {
258258
259259 const gop = try macho_file.dupes.getOrPut(gpa, file.getGlobals()[i]);
260260 if (!gop.found_existing) {
261 gop.value_ptr.* = .{};
261 gop.value_ptr.* = .empty;
262262 }
263263 try gop.value_ptr.append(gpa, file.getIndex());
264264 }
src/link/Wasm.zig+4-4
......@@ -78,7 +78,7 @@ export_table: bool,
7878/// Output name of the file
7979name: []const u8,
8080/// List of relocatable files to be linked into the final binary.
81objects: std.ArrayList(Object) = .{},
81objects: std.ArrayList(Object) = .empty,
8282
8383func_types: std.AutoArrayHashMapUnmanaged(FunctionType, void) = .empty,
8484/// Provides a mapping of both imports and provided functions to symbol name.
......@@ -278,7 +278,7 @@ any_tls_relocs: bool = false,
278278any_passive_inits: bool = false,
279279
280280/// All MIR instructions for all Zcu functions.
281mir_instructions: std.MultiArrayList(Mir.Inst) = .{},
281mir_instructions: std.MultiArrayList(Mir.Inst) = .empty,
282282/// Corresponds to `mir_instructions`.
283283mir_extra: std.ArrayList(u32) = .empty,
284284/// All local types for all Zcu functions.
......@@ -4226,7 +4226,7 @@ fn convertZcuFnType(
42264226
42274227 if (CodeGen.firstParamSRet(cc, return_type, zcu, target)) {
42284228 try params_buffer.append(gpa, .i32); // memory address is always a 32-bit handle
4229 } else if (return_type.hasRuntimeBitsIgnoreComptime(zcu)) {
4229 } else if (return_type.hasRuntimeBits(zcu)) {
42304230 if (cc == .wasm_mvp) {
42314231 switch (abi.classifyType(return_type, zcu)) {
42324232 .direct => |scalar_ty| {
......@@ -4245,7 +4245,7 @@ fn convertZcuFnType(
42454245 // param types
42464246 for (params) |param_type_ip| {
42474247 const param_type = Zcu.Type.fromInterned(param_type_ip);
4248 if (!param_type.hasRuntimeBitsIgnoreComptime(zcu)) continue;
4248 if (!param_type.hasRuntimeBits(zcu)) continue;
42494249
42504250 switch (cc) {
42514251 .wasm_mvp => {
src/link/Wasm/Flush.zig+3-3
......@@ -154,7 +154,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
154154 .type_index = try wasm.internFunctionType(.auto, &.{int_tag_ty.ip_index}, .slice_const_u8_sentinel_0, target),
155155 .table_index = @intCast(wasm.tag_name_offs.items.len),
156156 } };
157 const tag_names = ip.loadEnumType(data.ip_index).names;
157 const tag_names = ip.loadEnumType(data.ip_index).field_names;
158158 for (tag_names.get(ip)) |tag_name| {
159159 const slice = tag_name.toSlice(ip);
160160 try wasm.tag_name_offs.append(gpa, @intCast(wasm.tag_name_bytes.items.len));
......@@ -1869,7 +1869,7 @@ fn emitTagNameFunction(
18691869 const zcu = comp.zcu.?;
18701870 const ip = &zcu.intern_pool;
18711871 const enum_type = ip.loadEnumType(enum_type_ip);
1872 const tag_values = enum_type.values.get(ip);
1872 const tag_values = enum_type.field_values.get(ip);
18731873
18741874 const slice_abi_size = 8;
18751875 const encoded_alignment = @ctz(@as(u32, 4));
......@@ -1908,7 +1908,7 @@ fn emitTagNameFunction(
19081908 return;
19091909 }
19101910
1911 const int_info = Zcu.Type.intInfo(.fromInterned(enum_type.tag_ty), zcu);
1911 const int_info = Zcu.Type.intInfo(.fromInterned(enum_type.int_tag_type), zcu);
19121912 const outer_block_type: std.wasm.BlockType = switch (int_info.bits) {
19131913 0...32 => .i32,
19141914 33...64 => .i64,
src/link/tapi/parse.zig+1-1
......@@ -530,7 +530,7 @@ const Parser = struct {
530530 fn leaf_value(self: *Parser) ParseError!*Node {
531531 const node = try self.allocator.create(Node.Value);
532532 errdefer self.allocator.destroy(node);
533 node.* = .{ .string_value = .{} };
533 node.* = .{ .string_value = .empty };
534534 node.base.tree = self.tree;
535535 node.base.start = self.token_it.pos;
536536 errdefer node.string_value.deinit(self.allocator);
src/main.zig+9-9
......@@ -979,7 +979,7 @@ fn buildOutputType(
979979 .dirs = undefined,
980980 .object_format = null,
981981 .dynamic_linker = null,
982 .modules = .{},
982 .modules = .empty,
983983 .opts = .{
984984 .is_test = switch (arg_mode) {
985985 .zig_test, .zig_test_obj => true,
......@@ -1006,18 +1006,18 @@ fn buildOutputType(
10061006 .windows_libs = .empty,
10071007 .link_inputs = .empty,
10081008
1009 .c_source_files = .{},
1010 .rc_source_files = .{},
1009 .c_source_files = .empty,
1010 .rc_source_files = .empty,
10111011
1012 .llvm_m_args = .{},
1012 .llvm_m_args = .empty,
10131013 .sysroot = null,
1014 .lib_directories = .{}, // populated by createModule()
1015 .lib_dir_args = .{}, // populated from CLI arg parsing
1014 .lib_directories = .empty, // populated by createModule()
1015 .lib_dir_args = .empty, // populated from CLI arg parsing
10161016 .libc_installation = null,
10171017 .want_native_include_dirs = false,
1018 .frameworks = .{},
1019 .framework_dirs = .{},
1020 .rpath_list = .{},
1018 .frameworks = .empty,
1019 .framework_dirs = .empty,
1020 .rpath_list = .empty,
10211021 .each_lib_rpath = null,
10221022 .libc_paths_file = EnvVar.ZIG_LIBC.get(environ_map),
10231023 .native_system_include_paths = &.{},
src/mutable_value.zig+18-26
......@@ -18,7 +18,7 @@ pub const MutableValue = union(enum) {
1818 opt_payload: SubValue,
1919 /// An aggregate consisting of a single repeated value.
2020 repeated: SubValue,
21 /// An aggregate of `u8` consisting of "plain" bytes (no lazy or undefined elements).
21 /// An aggregate of `u8` consisting of "plain" bytes (no undefined elements).
2222 bytes: Bytes,
2323 /// An aggregate with arbitrary sub-values.
2424 aggregate: Aggregate,
......@@ -97,8 +97,8 @@ pub const MutableValue = union(enum) {
9797 /// * Non-error error unions use `eu_payload`
9898 /// * Non-null optionals use `eu_payload
9999 /// * Slices use `slice`
100 /// * Unions use `un`
101 /// * Aggregates use `repeated` or `bytes` or `aggregate`
100 /// * Unions use `un` (excluding packed unions)
101 /// * Aggregates use `repeated` or `bytes` or `aggregate` (excluding packed structs)
102102 /// If `!allow_bytes`, the `bytes` representation will not be used.
103103 /// If `!allow_repeated`, the `repeated` representation will not be used.
104104 pub fn unintern(
......@@ -209,6 +209,7 @@ pub const MutableValue = union(enum) {
209209 .undef => |ty_ip| switch (Type.fromInterned(ty_ip).zigTypeTag(zcu)) {
210210 .@"struct", .array, .vector => |type_tag| {
211211 const ty = Type.fromInterned(ty_ip);
212 if (type_tag == .@"struct" and ty.containerLayout(zcu) == .@"packed") return;
212213 const opt_sent = ty.sentinel(zcu);
213214 if (type_tag == .@"struct" or opt_sent != null or !allow_repeated) {
214215 const len_no_sent = ip.aggregateTypeLen(ty_ip);
......@@ -241,15 +242,18 @@ pub const MutableValue = union(enum) {
241242 } };
242243 }
243244 },
244 .@"union" => {
245 const payload = try arena.create(MutableValue);
246 const backing_ty = try Type.fromInterned(ty_ip).unionBackingType(pt);
247 payload.* = .{ .interned = try pt.intern(.{ .undef = backing_ty.toIntern() }) };
248 mv.* = .{ .un = .{
249 .ty = ty_ip,
250 .tag = .none,
251 .payload = payload,
252 } };
245 .@"union" => switch (Type.fromInterned(ty_ip).containerLayout(zcu)) {
246 .auto, .@"packed" => {},
247 .@"extern" => {
248 const payload = try arena.create(MutableValue);
249 const backing_ty = try Type.fromInterned(ty_ip).externUnionBackingType(pt);
250 payload.* = .{ .interned = try pt.intern(.{ .undef = backing_ty.toIntern() }) };
251 mv.* = .{ .un = .{
252 .ty = ty_ip,
253 .tag = .none,
254 .payload = payload,
255 } };
256 },
253257 },
254258 .pointer => {
255259 const ptr_ty = ip.indexToKey(ty_ip).ptr_type;
......@@ -415,16 +419,7 @@ pub const MutableValue = union(enum) {
415419 } else if (!is_struct and is_trivial_int and Type.fromInterned(a.ty).childType(zcu).toIntern() == .u8_type) {
416420 // See if we can switch to `bytes` repr
417421 for (a.elems) |e| {
418 switch (e) {
419 else => break,
420 .interned => |ip_index| switch (ip.indexToKey(ip_index)) {
421 else => break,
422 .int => |int| switch (int.storage) {
423 .u64, .i64, .big_int => {},
424 .lazy_align, .lazy_size => break,
425 },
426 },
427 }
422 if (!e.isTrivialInt(zcu)) break;
428423 } else {
429424 const bytes = try arena.alloc(u8, a.elems.len);
430425 for (a.elems, bytes) |elem_val, *b| {
......@@ -494,10 +489,7 @@ pub const MutableValue = union(enum) {
494489 else => false,
495490 .interned => |ip_index| switch (zcu.intern_pool.indexToKey(ip_index)) {
496491 else => false,
497 .int => |int| switch (int.storage) {
498 .u64, .i64, .big_int => true,
499 .lazy_align, .lazy_size => false,
500 },
492 .int => true,
501493 },
502494 };
503495 }
src/print_value.zig+79-42
......@@ -25,10 +25,7 @@ pub fn formatSema(ctx: FormatContext, writer: *Writer) Writer.Error!void {
2525 const sema = ctx.opt_sema.?;
2626 return print(ctx.val, writer, ctx.depth, ctx.pt, sema) catch |err| switch (err) {
2727 error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
28 error.ComptimeBreak, error.ComptimeReturn => unreachable,
29 error.AnalysisFail => unreachable, // TODO: re-evaluate when we use `sema` more fully
30 error.Canceled => @panic("TODO"), // pls stop returning this error mlugg
31 else => |e| return e,
28 error.WriteFailed => |e| return e,
3229 };
3330}
3431
......@@ -36,9 +33,7 @@ pub fn format(ctx: FormatContext, writer: *Writer) Writer.Error!void {
3633 std.debug.assert(ctx.opt_sema == null);
3734 return print(ctx.val, writer, ctx.depth, ctx.pt, null) catch |err| switch (err) {
3835 error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
39 error.ComptimeBreak, error.ComptimeReturn, error.AnalysisFail => unreachable,
40 error.Canceled => @panic("TODO"), // pls stop returning this error mlugg
41 else => |e| return e,
36 error.WriteFailed => |e| return e,
4237 };
4338}
4439
......@@ -48,7 +43,7 @@ pub fn print(
4843 level: u8,
4944 pt: Zcu.PerThread,
5045 opt_sema: ?*Sema,
51) (Writer.Error || Zcu.CompileError)!void {
46) (Writer.Error || Allocator.Error)!void {
5247 const zcu = pt.zcu;
5348 const ip = &zcu.intern_pool;
5449 switch (ip.indexToKey(val.toIntern())) {
......@@ -72,8 +67,12 @@ pub fn print(
7267 .undef => try writer.writeAll("undefined"),
7368 .simple_value => |simple_value| switch (simple_value) {
7469 .void => try writer.writeAll("{}"),
75 .empty_tuple => try writer.writeAll(".{}"),
76 else => try writer.writeAll(@tagName(simple_value)),
70
71 .null,
72 .true,
73 .false,
74 .@"unreachable",
75 => try writer.writeAll(@tagName(simple_value)),
7776 },
7877 .variable => try writer.writeAll("(variable)"),
7978 .@"extern" => |e| try writer.print("(extern '{f}')", .{e.name.fmt(ip)}),
......@@ -81,14 +80,6 @@ pub fn print(
8180 .int => |int| switch (int.storage) {
8281 inline .u64, .i64 => |x| try writer.print("{d}", .{x}),
8382 .big_int => |x| try writer.print("{d}", .{x}),
84 .lazy_align => |ty| if (opt_sema != null) {
85 const a = try Type.fromInterned(ty).abiAlignmentSema(pt);
86 try writer.print("{d}", .{a.toByteUnits() orelse 0});
87 } else try writer.print("@alignOf({f})", .{Type.fromInterned(ty).fmt(pt)}),
88 .lazy_size => |ty| if (opt_sema != null) {
89 const s = try Type.fromInterned(ty).abiSizeSema(pt);
90 try writer.print("{d}", .{s});
91 } else try writer.print("@sizeOf({f})", .{Type.fromInterned(ty).fmt(pt)}),
9283 },
9384 .err => |err| try writer.print("error.{f}", .{
9485 err.name.fmt(ip),
......@@ -104,8 +95,8 @@ pub fn print(
10495 }),
10596 .enum_tag => |enum_tag| {
10697 const enum_type = ip.loadEnumType(val.typeOf(zcu).toIntern());
107 if (enum_type.tagValueIndex(ip, val.toIntern())) |tag_index| {
108 return writer.print(".{f}", .{enum_type.names.get(ip)[tag_index].fmt(ip)});
98 if (enum_type.tagValueIndex(ip, enum_tag.int)) |tag_index| {
99 return writer.print(".{f}", .{enum_type.field_names.get(ip)[tag_index].fmt(ip)});
109100 }
110101 if (level == 0) {
111102 return writer.writeAll("@enumFromInt(...)");
......@@ -114,7 +105,6 @@ pub fn print(
114105 try print(Value.fromInterned(enum_tag.int), writer, level - 1, pt, opt_sema);
115106 try writer.writeAll(")");
116107 },
117 .empty_enum_value => try writer.writeAll("(empty enum value)"),
118108 .float => |float| switch (float.storage) {
119109 inline else => |x| try writer.print("{d}", .{@as(f64, @floatCast(x))}),
120110 },
......@@ -123,7 +113,7 @@ pub fn print(
123113 if (slice.len == .zero_usize) {
124114 return writer.writeAll("&.{}");
125115 }
126 try print(.fromInterned(slice.ptr), writer, level - 1, pt, opt_sema);
116 try print(.fromInterned(slice.ptr), writer, level, pt, opt_sema);
127117 } else {
128118 const print_contents = switch (ip.getBackingAddrTag(slice.ptr).?) {
129119 .field, .arr_elem, .eu_payload, .opt_payload => unreachable,
......@@ -167,7 +157,7 @@ pub fn print(
167157 return;
168158 }
169159 if (un.tag == .none) {
170 const backing_ty = try val.typeOf(zcu).unionBackingType(pt);
160 const backing_ty = try val.typeOf(zcu).externUnionBackingType(pt);
171161 try writer.print("@bitCast(@as({f}, ", .{backing_ty.fmt(pt)});
172162 try print(Value.fromInterned(un.val), writer, level - 1, pt, opt_sema);
173163 try writer.writeAll("))");
......@@ -179,6 +169,35 @@ pub fn print(
179169 try writer.writeAll(" }");
180170 }
181171 },
172 .bitpack => |bitpack| {
173 if (level == 0) {
174 return writer.writeAll(".{ ... }");
175 }
176 const ty: Type = .fromInterned(bitpack.ty);
177 switch (ty.zigTypeTag(zcu)) {
178 .@"struct" => {
179 if (ty.structFieldCount(zcu) == 0) {
180 return writer.writeAll(".{}");
181 }
182 try writer.writeAll(".{ ");
183 const max_len = @min(ty.structFieldCount(zcu), max_aggregate_items);
184 for (0..max_len) |i| {
185 if (i != 0) try writer.writeAll(", ");
186 const field_name = ty.structFieldName(@intCast(i), zcu).unwrap().?;
187 try writer.print(".{f} = ", .{field_name.fmt(ip)});
188 try print(try val.fieldValue(pt, i), writer, level - 1, pt, opt_sema);
189 }
190 try writer.writeAll(" }");
191 return;
192 },
193 .@"union" => {
194 try writer.print("@bitCast(@as({f}, ", .{ty.bitpackBackingInt(zcu).fmt(pt)});
195 try print(.fromInterned(bitpack.backing_int_val), writer, level - 1, pt, opt_sema);
196 try writer.writeAll("))");
197 },
198 else => unreachable,
199 }
200 },
182201 .memoized_call => unreachable,
183202 }
184203}
......@@ -191,7 +210,7 @@ fn printAggregate(
191210 level: u8,
192211 pt: Zcu.PerThread,
193212 opt_sema: ?*Sema,
194) (Writer.Error || Zcu.CompileError)!void {
213) (Writer.Error || Allocator.Error)!void {
195214 if (level == 0) {
196215 if (is_ref) try writer.writeByte('&');
197216 return writer.writeAll(".{ ... }");
......@@ -256,17 +275,26 @@ fn printAggregate(
256275 const len = ty.arrayLen(zcu);
257276
258277 if (is_ref) try writer.writeByte('&');
259 try writer.writeAll(".{ ");
260
261 const max_len = @min(len, max_aggregate_items);
262 for (0..max_len) |i| {
263 if (i != 0) try writer.writeAll(", ");
264 try print(try val.fieldValue(pt, i), writer, level - 1, pt, opt_sema);
265 }
266 if (len > max_aggregate_items) {
267 try writer.writeAll(", ...");
278 switch (len) {
279 0 => try writer.writeAll(".{}"),
280 1 => {
281 try writer.writeAll(".{");
282 try print(try val.fieldValue(pt, 0), writer, level - 1, pt, opt_sema);
283 try writer.writeByte('}');
284 },
285 else => {
286 try writer.writeAll(".{ ");
287 const max_len = @min(len, max_aggregate_items);
288 for (0..max_len) |i| {
289 if (i != 0) try writer.writeAll(", ");
290 try print(try val.fieldValue(pt, i), writer, level - 1, pt, opt_sema);
291 }
292 if (len > max_aggregate_items) {
293 try writer.writeAll(", ...");
294 }
295 try writer.writeAll(" }");
296 },
268297 }
269 return writer.writeAll(" }");
270298}
271299
272300fn printPtr(
......@@ -277,7 +305,7 @@ fn printPtr(
277305 level: u8,
278306 pt: Zcu.PerThread,
279307 opt_sema: ?*Sema,
280) (Writer.Error || Zcu.CompileError)!void {
308) (Writer.Error || Allocator.Error)!void {
281309 const ptr = switch (pt.zcu.intern_pool.indexToKey(ptr_val.toIntern())) {
282310 .undef => return writer.writeAll("undefined"),
283311 .ptr => |ptr| ptr,
......@@ -302,10 +330,7 @@ fn printPtr(
302330
303331 var arena = std.heap.ArenaAllocator.init(pt.zcu.gpa);
304332 defer arena.deinit();
305 const derivation = if (opt_sema) |sema|
306 try ptr_val.pointerDerivationAdvanced(arena.allocator(), pt, true, sema)
307 else
308 try ptr_val.pointerDerivationAdvanced(arena.allocator(), pt, false, null);
333 const derivation = try ptr_val.pointerDerivation(arena.allocator(), pt, opt_sema);
309334
310335 _ = try printPtrDerivation(derivation, writer, pt, want_kind, .{ .print_val = .{
311336 .level = level,
......@@ -442,18 +467,30 @@ pub fn printPtrDerivation(
442467 .uav_ptr => |uav| {
443468 const ty = Value.fromInterned(uav.val).typeOf(zcu);
444469 try writer.print("@as({f}, ", .{ty.fmt(pt)});
445 try print(Value.fromInterned(uav.val), writer, x.level - 1, pt, x.opt_sema);
470 if (x.level == 0) {
471 try writer.writeAll("...");
472 } else {
473 try print(Value.fromInterned(uav.val), writer, x.level - 1, pt, x.opt_sema);
474 }
446475 try writer.writeByte(')');
447476 },
448477 .comptime_alloc_ptr => |info| {
449478 try writer.print("@as({f}, ", .{info.val.typeOf(zcu).fmt(pt)});
450 try print(info.val, writer, x.level - 1, pt, x.opt_sema);
479 if (x.level == 0) {
480 try writer.writeAll("...");
481 } else {
482 try print(info.val, writer, x.level - 1, pt, x.opt_sema);
483 }
451484 try writer.writeByte(')');
452485 },
453486 .comptime_field_ptr => |val| {
454487 const ty = val.typeOf(zcu);
455488 try writer.print("@as({f}, ", .{ty.fmt(pt)});
456 try print(val, writer, x.level - 1, pt, x.opt_sema);
489 if (x.level == 0) {
490 try writer.writeAll("...");
491 } else {
492 try print(val, writer, x.level - 1, pt, x.opt_sema);
493 }
457494 try writer.writeByte(')');
458495 },
459496 else => unreachable,
src/print_zir.zig+115-426
......@@ -548,10 +548,10 @@ const Writer = struct {
548548 .shl_with_overflow,
549549 => try self.writeOverflowArithmetic(stream, extended),
550550
551 .struct_decl => try self.writeStructDecl(stream, extended),
552 .union_decl => try self.writeUnionDecl(stream, extended),
553 .enum_decl => try self.writeEnumDecl(stream, extended),
554 .opaque_decl => try self.writeOpaqueDecl(stream, extended),
551 .struct_decl => try self.writeStructDecl(stream, inst),
552 .union_decl => try self.writeUnionDecl(stream, inst),
553 .enum_decl => try self.writeEnumDecl(stream, inst),
554 .opaque_decl => try self.writeOpaqueDecl(stream, inst),
555555
556556 .tuple_decl => try self.writeTupleDecl(stream, extended),
557557
......@@ -1427,187 +1427,57 @@ const Writer = struct {
14271427 try self.writeSrcNode(stream, inst_data.src_node);
14281428 }
14291429
1430 fn writeStructDecl(self: *Writer, stream: *std.Io.Writer, extended: Zir.Inst.Extended.InstData) !void {
1431 const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
1432
1433 const extra = self.code.extraData(Zir.Inst.StructDecl, extended.operand);
1430 fn writeStructDecl(self: *Writer, stream: *std.Io.Writer, inst: Zir.Inst.Index) !void {
1431 const struct_decl = self.code.getStructDecl(inst);
14341432
14351433 const prev_parent_decl_node = self.parent_decl_node;
1436 self.parent_decl_node = extra.data.src_node;
1434 self.parent_decl_node = struct_decl.src_node;
14371435 defer self.parent_decl_node = prev_parent_decl_node;
14381436
1439 const fields_hash: std.zig.SrcHash = @bitCast([4]u32{
1440 extra.data.fields_hash_0,
1441 extra.data.fields_hash_1,
1442 extra.data.fields_hash_2,
1443 extra.data.fields_hash_3,
1444 });
1445
1437 const fields_hash = self.code.getAssociatedSrcHash(inst).?;
14461438 try stream.print("hash({x}) ", .{&fields_hash});
14471439
1448 var extra_index: usize = extra.end;
1449
1450 const captures_len = if (small.has_captures_len) blk: {
1451 const captures_len = self.code.extra[extra_index];
1452 extra_index += 1;
1453 break :blk captures_len;
1454 } else 0;
1455
1456 const fields_len = if (small.has_fields_len) blk: {
1457 const fields_len = self.code.extra[extra_index];
1458 extra_index += 1;
1459 break :blk fields_len;
1460 } else 0;
1461
1462 const decls_len = if (small.has_decls_len) blk: {
1463 const decls_len = self.code.extra[extra_index];
1464 extra_index += 1;
1465 break :blk decls_len;
1466 } else 0;
1440 try stream.print("{s}, ", .{@tagName(struct_decl.name_strategy)});
14671441
1468 try self.writeFlag(stream, "known_non_opv, ", small.known_non_opv);
1469 try self.writeFlag(stream, "known_comptime_only, ", small.known_comptime_only);
1470
1471 try stream.print("{s}, ", .{@tagName(small.name_strategy)});
1472
1473 extra_index = try self.writeCaptures(stream, extra_index, captures_len);
1474 try stream.writeAll(", ");
1475
1476 if (small.has_backing_int) {
1477 const backing_int_body_len = self.code.extra[extra_index];
1478 extra_index += 1;
1442 if (struct_decl.backing_int_type_body) |backing_int_type_body| {
1443 assert(struct_decl.layout == .@"packed");
14791444 try stream.writeAll("packed(");
1480 if (backing_int_body_len == 0) {
1481 const backing_int_ref: Zir.Inst.Ref = @enumFromInt(self.code.extra[extra_index]);
1482 extra_index += 1;
1483 try self.writeInstRef(stream, backing_int_ref);
1484 } else {
1485 const body = self.code.bodySlice(extra_index, backing_int_body_len);
1486 extra_index += backing_int_body_len;
1487 self.indent += 2;
1488 try self.writeBracedDecl(stream, body);
1489 self.indent -= 2;
1490 }
1445 try self.writeBracedDecl(stream, backing_int_type_body);
14911446 try stream.writeAll("), ");
14921447 } else {
1493 try stream.print("{s}, ", .{@tagName(small.layout)});
1448 try stream.print("{s}, ", .{@tagName(struct_decl.layout)});
14941449 }
14951450
1496 if (decls_len == 0) {
1497 try stream.writeAll("{}, ");
1498 } else {
1499 try stream.writeAll("{\n");
1500 self.indent += 2;
1501 try self.writeBody(stream, self.code.bodySlice(extra_index, decls_len));
1502 self.indent -= 2;
1503 extra_index += decls_len;
1504 try stream.splatByteAll(' ', self.indent);
1505 try stream.writeAll("}, ");
1506 }
1451 try self.writeCaptures(stream, struct_decl.captures, struct_decl.capture_names);
1452 try stream.writeAll(", ");
1453 try self.writeBracedDecl(stream, struct_decl.decls);
1454 try stream.writeAll(", ");
15071455
1508 if (fields_len == 0) {
1509 try stream.writeAll("{}, {}) ");
1456 if (struct_decl.field_names.len == 0) {
1457 try stream.writeAll("{}) ");
15101458 } else {
1511 const bits_per_field = 4;
1512 const fields_per_u32 = 32 / bits_per_field;
1513 const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;
1514 const Field = struct {
1515 type_len: u32 = 0,
1516 align_len: u32 = 0,
1517 init_len: u32 = 0,
1518 type: Zir.Inst.Ref = .none,
1519 name: Zir.NullTerminatedString,
1520 is_comptime: bool,
1521 };
1522 const fields = try self.arena.alloc(Field, fields_len);
1523 {
1524 var bit_bag_index: usize = extra_index;
1525 extra_index += bit_bags_count;
1526 var cur_bit_bag: u32 = undefined;
1527 var field_i: u32 = 0;
1528 while (field_i < fields_len) : (field_i += 1) {
1529 if (field_i % fields_per_u32 == 0) {
1530 cur_bit_bag = self.code.extra[bit_bag_index];
1531 bit_bag_index += 1;
1532 }
1533 const has_align = @as(u1, @truncate(cur_bit_bag)) != 0;
1534 cur_bit_bag >>= 1;
1535 const has_default = @as(u1, @truncate(cur_bit_bag)) != 0;
1536 cur_bit_bag >>= 1;
1537 const is_comptime = @as(u1, @truncate(cur_bit_bag)) != 0;
1538 cur_bit_bag >>= 1;
1539 const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0;
1540 cur_bit_bag >>= 1;
1541
1542 const field_name_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
1543 extra_index += 1;
1544
1545 fields[field_i] = .{
1546 .is_comptime = is_comptime,
1547 .name = field_name_index,
1548 };
1549
1550 if (has_type_body) {
1551 fields[field_i].type_len = self.code.extra[extra_index];
1552 } else {
1553 fields[field_i].type = @enumFromInt(self.code.extra[extra_index]);
1554 }
1555 extra_index += 1;
1556
1557 if (has_align) {
1558 fields[field_i].align_len = self.code.extra[extra_index];
1559 extra_index += 1;
1560 }
1561
1562 if (has_default) {
1563 fields[field_i].init_len = self.code.extra[extra_index];
1564 extra_index += 1;
1565 }
1566 }
1567 }
1568
15691459 try stream.writeAll("{\n");
15701460 self.indent += 2;
15711461
1572 for (fields, 0..) |field, i| {
1462 var it = struct_decl.iterateFields();
1463 while (it.next()) |field| {
15731464 try stream.splatByteAll(' ', self.indent);
15741465 try self.writeFlag(stream, "comptime ", field.is_comptime);
1575 if (field.name != .empty) {
1576 const field_name = self.code.nullTerminatedString(field.name);
1577 try stream.print("{f}: ", .{std.zig.fmtIdP(field_name)});
1578 } else {
1579 try stream.print("@\"{d}\": ", .{i});
1580 }
1581 if (field.type != .none) {
1582 try self.writeInstRef(stream, field.type);
1583 }
1584
1585 if (field.type_len > 0) {
1586 const body = self.code.bodySlice(extra_index, field.type_len);
1587 extra_index += body.len;
1588 self.indent += 2;
1589 try self.writeBracedDecl(stream, body);
1590 self.indent -= 2;
1591 }
1466 const field_name = self.code.nullTerminatedString(field.name);
1467 try stream.print("{f}: ", .{std.zig.fmtIdP(field_name)});
15921468
1593 if (field.align_len > 0) {
1594 const body = self.code.bodySlice(extra_index, field.align_len);
1595 extra_index += body.len;
1596 self.indent += 2;
1469 self.indent += 2;
1470 try self.writeBracedDecl(stream, field.type_body);
1471 if (field.align_body) |body| {
15971472 try stream.writeAll(" align(");
15981473 try self.writeBracedDecl(stream, body);
1599 try stream.writeAll(")");
1600 self.indent -= 2;
1474 try stream.writeByte(')');
16011475 }
1602
1603 if (field.init_len > 0) {
1604 const body = self.code.bodySlice(extra_index, field.init_len);
1605 extra_index += body.len;
1606 self.indent += 2;
1476 if (field.default_body) |body| {
16071477 try stream.writeAll(" = ");
16081478 try self.writeBracedDecl(stream, body);
1609 self.indent -= 2;
16101479 }
1480 self.indent -= 2;
16111481
16121482 try stream.writeAll(",\n");
16131483 }
......@@ -1619,266 +1489,119 @@ const Writer = struct {
16191489 try self.writeSrcNode(stream, .zero);
16201490 }
16211491
1622 fn writeUnionDecl(self: *Writer, stream: *std.Io.Writer, extended: Zir.Inst.Extended.InstData) !void {
1623 const small = @as(Zir.Inst.UnionDecl.Small, @bitCast(extended.small));
1624
1625 const extra = self.code.extraData(Zir.Inst.UnionDecl, extended.operand);
1492 fn writeUnionDecl(self: *Writer, stream: *std.Io.Writer, inst: Zir.Inst.Index) !void {
1493 const union_decl = self.code.getUnionDecl(inst);
16261494
16271495 const prev_parent_decl_node = self.parent_decl_node;
1628 self.parent_decl_node = extra.data.src_node;
1496 self.parent_decl_node = union_decl.src_node;
16291497 defer self.parent_decl_node = prev_parent_decl_node;
16301498
1631 const fields_hash: std.zig.SrcHash = @bitCast([4]u32{
1632 extra.data.fields_hash_0,
1633 extra.data.fields_hash_1,
1634 extra.data.fields_hash_2,
1635 extra.data.fields_hash_3,
1636 });
1637
1499 const fields_hash = self.code.getAssociatedSrcHash(inst).?;
16381500 try stream.print("hash({x}) ", .{&fields_hash});
16391501
1640 var extra_index: usize = extra.end;
1641
1642 const tag_type_ref = if (small.has_tag_type) blk: {
1643 const tag_type_ref = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index]));
1644 extra_index += 1;
1645 break :blk tag_type_ref;
1646 } else .none;
1647
1648 const captures_len = if (small.has_captures_len) blk: {
1649 const captures_len = self.code.extra[extra_index];
1650 extra_index += 1;
1651 break :blk captures_len;
1652 } else 0;
1653
1654 const body_len = if (small.has_body_len) blk: {
1655 const body_len = self.code.extra[extra_index];
1656 extra_index += 1;
1657 break :blk body_len;
1658 } else 0;
1659
1660 const fields_len = if (small.has_fields_len) blk: {
1661 const fields_len = self.code.extra[extra_index];
1662 extra_index += 1;
1663 break :blk fields_len;
1664 } else 0;
1665
1666 const decls_len = if (small.has_decls_len) blk: {
1667 const decls_len = self.code.extra[extra_index];
1668 extra_index += 1;
1669 break :blk decls_len;
1670 } else 0;
1502 try stream.print("{s}, ", .{@tagName(union_decl.name_strategy)});
16711503
1672 try stream.print("{s}, {s}, ", .{
1673 @tagName(small.name_strategy), @tagName(small.layout),
1674 });
1675 try self.writeFlag(stream, "autoenum, ", small.auto_enum_tag);
1504 switch (union_decl.kind) {
1505 .auto => try stream.writeAll("auto, "),
1506 .@"extern" => try stream.writeAll("extern, "),
1507 .@"packed" => try stream.writeAll("packed, "),
1508 .packed_explicit => {
1509 try stream.writeAll("packed(");
1510 try self.writeBracedDecl(stream, union_decl.arg_type_body.?);
1511 try stream.writeAll("), ");
1512 },
1513 .tagged_explicit => {
1514 try stream.writeAll("tagged(");
1515 try self.writeBracedDecl(stream, union_decl.arg_type_body.?);
1516 try stream.writeAll("), ");
1517 },
1518 .tagged_enum => try stream.writeAll("tagged(enum), "),
1519 .tagged_enum_explicit => {
1520 try stream.writeAll("tagged(enum(");
1521 try self.writeBracedDecl(stream, union_decl.arg_type_body.?);
1522 try stream.writeAll(")), ");
1523 },
1524 }
16761525
1677 extra_index = try self.writeCaptures(stream, extra_index, captures_len);
1526 try self.writeCaptures(stream, union_decl.captures, union_decl.capture_names);
1527 try stream.writeAll(", ");
1528 try self.writeBracedDecl(stream, union_decl.decls);
16781529 try stream.writeAll(", ");
16791530
1680 if (decls_len == 0) {
1681 try stream.writeAll("{}");
1531 if (union_decl.field_names.len == 0) {
1532 try stream.writeAll("}) ");
16821533 } else {
16831534 try stream.writeAll("{\n");
16841535 self.indent += 2;
1685 try self.writeBody(stream, self.code.bodySlice(extra_index, decls_len));
1686 self.indent -= 2;
1687 extra_index += decls_len;
1688 try stream.splatByteAll(' ', self.indent);
1689 try stream.writeAll("}");
1690 }
1691
1692 if (tag_type_ref != .none) {
1693 try stream.writeAll(", ");
1694 try self.writeInstRef(stream, tag_type_ref);
1695 }
1696
1697 if (fields_len == 0) {
1698 try stream.writeAll("}) ");
1699 try self.writeSrcNode(stream, .zero);
1700 return;
1701 }
1702 try stream.writeAll(", ");
17031536
1704 const body = self.code.bodySlice(extra_index, body_len);
1705 extra_index += body.len;
1537 var it = union_decl.iterateFields();
1538 while (it.next()) |field| {
1539 try stream.splatByteAll(' ', self.indent);
1540 const field_name = self.code.nullTerminatedString(field.name);
1541 try stream.print("{f}", .{std.zig.fmtIdP(field_name)});
17061542
1707 try self.writeBracedDecl(stream, body);
1708 try stream.writeAll(", {\n");
1543 self.indent += 2;
1544 if (field.type_body) |body| {
1545 try stream.writeAll(": ");
1546 try self.writeBracedDecl(stream, body);
1547 }
1548 if (field.align_body) |body| {
1549 try stream.writeAll(" align(");
1550 try self.writeBracedDecl(stream, body);
1551 try stream.writeByte(')');
1552 }
1553 if (field.value_body) |body| {
1554 try stream.writeAll(" = ");
1555 try self.writeBracedDecl(stream, body);
1556 }
1557 self.indent -= 2;
17091558
1710 self.indent += 2;
1711 const bits_per_field = 4;
1712 const fields_per_u32 = 32 / bits_per_field;
1713 const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable;
1714 const body_end = extra_index;
1715 extra_index += bit_bags_count;
1716 var bit_bag_index: usize = body_end;
1717 var cur_bit_bag: u32 = undefined;
1718 var field_i: u32 = 0;
1719 while (field_i < fields_len) : (field_i += 1) {
1720 if (field_i % fields_per_u32 == 0) {
1721 cur_bit_bag = self.code.extra[bit_bag_index];
1722 bit_bag_index += 1;
1559 try stream.writeAll(",\n");
17231560 }
1724 const has_type = @as(u1, @truncate(cur_bit_bag)) != 0;
1725 cur_bit_bag >>= 1;
1726 const has_align = @as(u1, @truncate(cur_bit_bag)) != 0;
1727 cur_bit_bag >>= 1;
1728 const has_value = @as(u1, @truncate(cur_bit_bag)) != 0;
1729 cur_bit_bag >>= 1;
1730 const unused = @as(u1, @truncate(cur_bit_bag)) != 0;
1731 cur_bit_bag >>= 1;
1732
1733 _ = unused;
1734
1735 const field_name_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]);
1736 const field_name = self.code.nullTerminatedString(field_name_index);
1737 extra_index += 1;
1738
1561 self.indent -= 2;
17391562 try stream.splatByteAll(' ', self.indent);
1740 try stream.print("{f}", .{std.zig.fmtIdP(field_name)});
1741
1742 if (has_type) {
1743 const field_type = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index]));
1744 extra_index += 1;
1745
1746 try stream.writeAll(": ");
1747 try self.writeInstRef(stream, field_type);
1748 }
1749 if (has_align) {
1750 const align_ref = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index]));
1751 extra_index += 1;
1752
1753 try stream.writeAll(" align(");
1754 try self.writeInstRef(stream, align_ref);
1755 try stream.writeAll(")");
1756 }
1757 if (has_value) {
1758 const default_ref = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index]));
1759 extra_index += 1;
1760
1761 try stream.writeAll(" = ");
1762 try self.writeInstRef(stream, default_ref);
1763 }
1764 try stream.writeAll(",\n");
1563 try stream.writeAll("}) ");
17651564 }
1766
1767 self.indent -= 2;
1768 try stream.splatByteAll(' ', self.indent);
1769 try stream.writeAll("}) ");
17701565 try self.writeSrcNode(stream, .zero);
17711566 }
17721567
1773 fn writeEnumDecl(self: *Writer, stream: *std.Io.Writer, extended: Zir.Inst.Extended.InstData) !void {
1774 const small = @as(Zir.Inst.EnumDecl.Small, @bitCast(extended.small));
1775
1776 const extra = self.code.extraData(Zir.Inst.EnumDecl, extended.operand);
1568 fn writeEnumDecl(self: *Writer, stream: *std.Io.Writer, inst: Zir.Inst.Index) !void {
1569 const enum_decl = self.code.getEnumDecl(inst);
17771570
17781571 const prev_parent_decl_node = self.parent_decl_node;
1779 self.parent_decl_node = extra.data.src_node;
1572 self.parent_decl_node = enum_decl.src_node;
17801573 defer self.parent_decl_node = prev_parent_decl_node;
17811574
1782 const fields_hash: std.zig.SrcHash = @bitCast([4]u32{
1783 extra.data.fields_hash_0,
1784 extra.data.fields_hash_1,
1785 extra.data.fields_hash_2,
1786 extra.data.fields_hash_3,
1787 });
1788
1575 const fields_hash = self.code.getAssociatedSrcHash(inst).?;
17891576 try stream.print("hash({x}) ", .{&fields_hash});
17901577
1791 var extra_index: usize = extra.end;
1792
1793 const tag_type_ref = if (small.has_tag_type) blk: {
1794 const tag_type_ref = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index]));
1795 extra_index += 1;
1796 break :blk tag_type_ref;
1797 } else .none;
1798
1799 const captures_len = if (small.has_captures_len) blk: {
1800 const captures_len = self.code.extra[extra_index];
1801 extra_index += 1;
1802 break :blk captures_len;
1803 } else 0;
1804
1805 const body_len = if (small.has_body_len) blk: {
1806 const body_len = self.code.extra[extra_index];
1807 extra_index += 1;
1808 break :blk body_len;
1809 } else 0;
1810
1811 const fields_len = if (small.has_fields_len) blk: {
1812 const fields_len = self.code.extra[extra_index];
1813 extra_index += 1;
1814 break :blk fields_len;
1815 } else 0;
1816
1817 const decls_len = if (small.has_decls_len) blk: {
1818 const decls_len = self.code.extra[extra_index];
1819 extra_index += 1;
1820 break :blk decls_len;
1821 } else 0;
1822
1823 try stream.print("{s}, ", .{@tagName(small.name_strategy)});
1824 try self.writeFlag(stream, "nonexhaustive, ", small.nonexhaustive);
1578 try stream.print("{s}, ", .{@tagName(enum_decl.name_strategy)});
1579 try self.writeFlag(stream, "nonexhaustive, ", enum_decl.nonexhaustive);
1580 if (enum_decl.tag_type_body) |tag_type_body| {
1581 try stream.writeAll("tag(");
1582 try self.writeBracedDecl(stream, tag_type_body);
1583 try stream.writeAll("), ");
1584 }
18251585
1826 extra_index = try self.writeCaptures(stream, extra_index, captures_len);
1586 try self.writeCaptures(stream, enum_decl.captures, enum_decl.capture_names);
1587 try stream.writeAll(", ");
1588 try self.writeBracedDecl(stream, enum_decl.decls);
18271589 try stream.writeAll(", ");
18281590
1829 if (decls_len == 0) {
1830 try stream.writeAll("{}, ");
1591 if (enum_decl.field_names.len == 0) {
1592 try stream.writeAll("{}) ");
18311593 } else {
18321594 try stream.writeAll("{\n");
18331595 self.indent += 2;
1834 try self.writeBody(stream, self.code.bodySlice(extra_index, decls_len));
1835 self.indent -= 2;
1836 extra_index += decls_len;
1837 try stream.splatByteAll(' ', self.indent);
1838 try stream.writeAll("}, ");
1839 }
1840
1841 if (tag_type_ref != .none) {
1842 try self.writeInstRef(stream, tag_type_ref);
1843 try stream.writeAll(", ");
1844 }
1845
1846 const body = self.code.bodySlice(extra_index, body_len);
1847 extra_index += body.len;
1848
1849 try self.writeBracedDecl(stream, body);
1850 if (fields_len == 0) {
1851 try stream.writeAll(", {}) ");
1852 } else {
1853 try stream.writeAll(", {\n");
1854
1855 self.indent += 2;
1856 const bit_bags_count = std.math.divCeil(usize, fields_len, 32) catch unreachable;
1857 const body_end = extra_index;
1858 extra_index += bit_bags_count;
1859 var bit_bag_index: usize = body_end;
1860 var cur_bit_bag: u32 = undefined;
1861 var field_i: u32 = 0;
1862 while (field_i < fields_len) : (field_i += 1) {
1863 if (field_i % 32 == 0) {
1864 cur_bit_bag = self.code.extra[bit_bag_index];
1865 bit_bag_index += 1;
1866 }
1867 const has_tag_value = @as(u1, @truncate(cur_bit_bag)) != 0;
1868 cur_bit_bag >>= 1;
1869
1870 const field_name = self.code.nullTerminatedString(@enumFromInt(self.code.extra[extra_index]));
1871 extra_index += 1;
18721596
1597 var it = enum_decl.iterateFields();
1598 while (it.next()) |field| {
18731599 try stream.splatByteAll(' ', self.indent);
1600 const field_name = self.code.nullTerminatedString(field.name);
18741601 try stream.print("{f}", .{std.zig.fmtIdP(field_name)});
1875
1876 if (has_tag_value) {
1877 const tag_value_ref = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index]));
1878 extra_index += 1;
1879
1602 if (field.value_body) |body| {
18801603 try stream.writeAll(" = ");
1881 try self.writeInstRef(stream, tag_value_ref);
1604 try self.writeBracedDecl(stream, body);
18821605 }
18831606 try stream.writeAll(",\n");
18841607 }
......@@ -1889,47 +1612,18 @@ const Writer = struct {
18891612 try self.writeSrcNode(stream, .zero);
18901613 }
18911614
1892 fn writeOpaqueDecl(
1893 self: *Writer,
1894 stream: *std.Io.Writer,
1895 extended: Zir.Inst.Extended.InstData,
1896 ) !void {
1897 const small = @as(Zir.Inst.OpaqueDecl.Small, @bitCast(extended.small));
1898 const extra = self.code.extraData(Zir.Inst.OpaqueDecl, extended.operand);
1615 fn writeOpaqueDecl(self: *Writer, stream: *std.Io.Writer, inst: Zir.Inst.Index) !void {
1616 const opaque_decl = self.code.getOpaqueDecl(inst);
18991617
19001618 const prev_parent_decl_node = self.parent_decl_node;
1901 self.parent_decl_node = extra.data.src_node;
1619 self.parent_decl_node = opaque_decl.src_node;
19021620 defer self.parent_decl_node = prev_parent_decl_node;
19031621
1904 var extra_index: usize = extra.end;
1905
1906 const captures_len = if (small.has_captures_len) blk: {
1907 const captures_len = self.code.extra[extra_index];
1908 extra_index += 1;
1909 break :blk captures_len;
1910 } else 0;
1911
1912 const decls_len = if (small.has_decls_len) blk: {
1913 const decls_len = self.code.extra[extra_index];
1914 extra_index += 1;
1915 break :blk decls_len;
1916 } else 0;
1917
1918 try stream.print("{s}, ", .{@tagName(small.name_strategy)});
1919
1920 extra_index = try self.writeCaptures(stream, extra_index, captures_len);
1622 try stream.print("{s}, ", .{@tagName(opaque_decl.name_strategy)});
1623 try self.writeCaptures(stream, opaque_decl.captures, opaque_decl.capture_names);
19211624 try stream.writeAll(", ");
1922
1923 if (decls_len == 0) {
1924 try stream.writeAll("{}) ");
1925 } else {
1926 try stream.writeAll("{\n");
1927 self.indent += 2;
1928 try self.writeBody(stream, self.code.bodySlice(extra_index, decls_len));
1929 self.indent -= 2;
1930 try stream.splatByteAll(' ', self.indent);
1931 try stream.writeAll("}) ");
1932 }
1625 try self.writeBracedDecl(stream, opaque_decl.decls);
1626 try stream.writeAll(") ");
19331627 try self.writeSrcNode(stream, .zero);
19341628 }
19351629
......@@ -2588,14 +2282,11 @@ const Writer = struct {
25882282 return stream.print("%{d}", .{@intFromEnum(inst)});
25892283 }
25902284
2591 fn writeCaptures(self: *Writer, stream: *std.Io.Writer, extra_index: usize, captures_len: u32) !usize {
2592 if (captures_len == 0) {
2593 try stream.writeAll("{}");
2594 return extra_index;
2285 fn writeCaptures(self: *Writer, stream: *std.Io.Writer, captures: []const Zir.Inst.Capture, capture_names: []const Zir.NullTerminatedString) !void {
2286 if (captures.len == 0) {
2287 assert(capture_names.len == 0);
2288 return stream.writeAll("{}");
25952289 }
2596
2597 const captures: []const Zir.Inst.Capture = @ptrCast(self.code.extra[extra_index..][0..captures_len]);
2598 const capture_names: []const Zir.NullTerminatedString = @ptrCast(self.code.extra[extra_index + captures_len ..][0..captures_len]);
25992290 for (captures, capture_names) |capture, name| {
26002291 try stream.writeAll("{ ");
26012292 if (name != .empty) {
......@@ -2604,8 +2295,6 @@ const Writer = struct {
26042295 }
26052296 try self.writeCapture(stream, capture);
26062297 }
2607
2608 return extra_index + 2 * captures_len;
26092298 }
26102299
26112300 fn writeCapture(self: *Writer, stream: *std.Io.Writer, capture: Zir.Inst.Capture) !void {
stage1/zig.h+9-1
......@@ -151,6 +151,14 @@
151151#define zig_has_attribute(attribute) 0
152152#endif
153153
154#if __STDC_VERSION__ >= 201112L
155#define zig_static_assert(cond, msg) _Static_assert(cond, msg)
156#elif zig_has_attribute(unused)
157#define zig_static_assert(cond, _) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[!!(cond)] __attribute__((unused))
158#else
159#define zig_static_assert(cond, _) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[!!(cond)]
160#endif
161
154162#if __STDC_VERSION__ >= 202311L
155163#define zig_threadlocal thread_local
156164#elif __STDC_VERSION__ >= 201112L
......@@ -259,7 +267,7 @@
259267#endif
260268
261269#if zig_has_attribute(packed) || defined(zig_tinyc)
262#define zig_packed(definition) __attribute__((packed)) definition
270#define zig_packed(definition) definition __attribute__((packed))
263271#elif defined(zig_msvc)
264272#define zig_packed(definition) __pragma(pack(1)) definition __pragma(pack())
265273#else
stage1/zig1.wasm
Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ
test/behavior.zig-1
......@@ -24,7 +24,6 @@ test {
2424 _ = @import("behavior/duplicated_test_names.zig");
2525 _ = @import("behavior/defer.zig");
2626 _ = @import("behavior/destructure.zig");
27 _ = @import("behavior/empty_union.zig");
2827 _ = @import("behavior/enum.zig");
2928 _ = @import("behavior/error.zig");
3029 _ = @import("behavior/eval.zig");
test/behavior/align.zig+47-10
......@@ -18,6 +18,7 @@ test "global variable alignment" {
1818test "large alignment of local constant" {
1919 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
2020 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // flaky
21 if (builtin.zig_backend == .stage2_c and builtin.target.abi == .msvc) return error.SkipZigTest;
2122
2223 const x: f32 align(128) = 12.34;
2324 try std.testing.expect(@intFromPtr(&x) % 128 == 0);
......@@ -30,13 +31,41 @@ test "slicing array of length 1 can not assume runtime index is always zero" {
3031 var runtime_index: usize = 1;
3132 _ = &runtime_index;
3233 const slice = @as(*align(4) [1]u8, &foo)[runtime_index..];
33 try expect(@TypeOf(slice) == []u8);
34 try expect(@TypeOf(slice) == []align(1) u8);
3435 try expect(slice.len == 0);
3536 try expect(@as(u2, @truncate(@intFromPtr(slice.ptr) - 1)) == 0);
3637}
3738
38test "default alignment allows unspecified in type syntax" {
39 try expect(*u32 == *align(@alignOf(u32)) u32);
39test "implicitly-aligned pointer is coercible to equivalent explicitly-aligned pointer" {
40 const A = *u32;
41 const B = *align(@alignOf(u32)) u32;
42
43 comptime assert(A != B);
44
45 const static = struct {
46 fn doTheTest() !void {
47 var buf: u32 = 123;
48
49 const ptr: A = &buf;
50 const coerced_ptr: B = ptr;
51
52 try expect(ptr == coerced_ptr);
53 try expect(ptr.* == 123);
54 try expect(coerced_ptr.* == 123);
55
56 const ptr_ptr: *const A = &ptr;
57 const coerced_ptr_ptr: *const B = ptr_ptr;
58
59 try expect(ptr_ptr == coerced_ptr_ptr);
60 try expect(ptr_ptr.* == &buf);
61 try expect(coerced_ptr_ptr.* == &buf);
62 try expect(ptr_ptr.*.* == 123);
63 try expect(coerced_ptr_ptr.*.* == 123);
64 }
65 };
66
67 try static.doTheTest();
68 try comptime static.doTheTest();
4069}
4170
4271test "implicitly decreasing pointer alignment" {
......@@ -307,11 +336,15 @@ test "runtime-known array index has best alignment possible" {
307336 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
308337
309338 // take full advantage of over-alignment
310 var array align(4) = [_]u8{ 1, 2, 3, 4 };
339 var array align(4) = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };
311340 comptime assert(@TypeOf(&array[0]) == *align(4) u8);
312 comptime assert(@TypeOf(&array[1]) == *u8);
341 comptime assert(@TypeOf(&array[1]) == *align(1) u8);
313342 comptime assert(@TypeOf(&array[2]) == *align(2) u8);
314 comptime assert(@TypeOf(&array[3]) == *u8);
343 comptime assert(@TypeOf(&array[3]) == *align(1) u8);
344 comptime assert(@TypeOf(&array[4]) == *align(4) u8);
345 comptime assert(@TypeOf(&array[5]) == *align(1) u8);
346 comptime assert(@TypeOf(&array[6]) == *align(2) u8);
347 comptime assert(@TypeOf(&array[7]) == *align(1) u8);
315348
316349 // because align is too small but we still figure out to use 2
317350 var bigger align(2) = [_]u64{ 1, 2, 3, 4 };
......@@ -332,10 +365,14 @@ test "runtime-known array index has best alignment possible" {
332365 try testIndex(smaller[runtime_zero..].ptr, 3, *align(2) u32);
333366
334367 // has to use ABI alignment because index known at runtime only
335 try testIndex2(&array, 0, *u8);
336 try testIndex2(&array, 1, *u8);
337 try testIndex2(&array, 2, *u8);
338 try testIndex2(&array, 3, *u8);
368 try testIndex2(&array, 0, *align(1) u8);
369 try testIndex2(&array, 1, *align(1) u8);
370 try testIndex2(&array, 2, *align(1) u8);
371 try testIndex2(&array, 3, *align(1) u8);
372 try testIndex2(&array, 4, *align(1) u8);
373 try testIndex2(&array, 5, *align(1) u8);
374 try testIndex2(&array, 6, *align(1) u8);
375 try testIndex2(&array, 7, *align(1) u8);
339376}
340377fn testIndex(smaller: [*]align(2) u32, index: usize, comptime T: type) !void {
341378 comptime assert(@TypeOf(&smaller[index]) == T);
test/behavior/alignof.zig+5
......@@ -39,3 +39,8 @@ test "correct alignment for elements and slices of aligned array" {
3939 try expect(@alignOf(@TypeOf(&buf[start..end])) == @alignOf(*u8));
4040 try expect(@alignOf(@TypeOf(&buf[start])) == @alignOf(*u8));
4141}
42
43test "@alignOf(anyerror!noreturn)" {
44 try expect(@alignOf(anyerror!noreturn) == @alignOf(anyerror));
45 try expect(@alignOf(anyerror!anyerror!noreturn) == @alignOf(anyerror));
46}
test/behavior/array.zig-22
......@@ -539,28 +539,6 @@ test "sentinel element count towards the ABI size calculation" {
539539 try comptime S.doTheTest();
540540}
541541
542test "zero-sized array with recursive type definition" {
543 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
544 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
545
546 const U = struct {
547 fn foo(comptime T: type, comptime n: usize) type {
548 return struct {
549 s: [n]T,
550 x: usize = n,
551 };
552 }
553 };
554
555 const S = struct {
556 list: U.foo(@This(), 0),
557 };
558
559 var t: S = .{ .list = .{ .s = undefined } };
560 _ = &t;
561 try expect(@as(usize, 0) == t.list.x);
562}
563
564542test "type coercion of anon struct literal to array" {
565543 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
566544 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
test/behavior/bitcast.zig-32
......@@ -350,9 +350,6 @@ test "comptime @bitCast packed struct to int and back" {
350350 iint_neg2: i3 = -2,
351351 float: f32 = 3.14,
352352 @"enum": enum(u2) { A, B = 1, C, D } = .B,
353 vectorb: @Vector(3, bool) = .{ true, false, true },
354 vectori: @Vector(2, u8) = .{ 127, 42 },
355 vectorf: @Vector(2, f16) = .{ 3.14, 2.71 },
356353 };
357354 const Int = @typeInfo(S).@"struct".backing_integer.?;
358355
......@@ -511,35 +508,6 @@ test "@bitCast of packed struct of bools all false" {
511508 try expect(@as(u8, @as(u4, @bitCast(p))) == 0);
512509}
513510
514test "@bitCast of packed struct containing pointer" {
515 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
516 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
517 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
518 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
519 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
520
521 const S = struct {
522 const A = packed struct {
523 ptr: *const u32,
524 };
525
526 const B = packed struct {
527 ptr: *const i32,
528 };
529
530 fn doTheTest() !void {
531 const x: u32 = 123;
532 var a: A = undefined;
533 a = .{ .ptr = &x };
534 const b: B = @bitCast(a);
535 try expect(b.ptr.* == 123);
536 }
537 };
538
539 try S.doTheTest();
540 try comptime S.doTheTest();
541}
542
543511test "@bitCast of extern struct containing pointer" {
544512 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
545513 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/call.zig+5-6
......@@ -551,19 +551,18 @@ test "generic function pointer can be called" {
551551
552552test "value returned from comptime function is comptime known" {
553553 const S = struct {
554 fn fields(comptime T: type) switch (@typeInfo(T)) {
555 .@"struct" => []const std.builtin.Type.StructField,
554 fn fieldCount(comptime T: type) switch (@typeInfo(T)) {
555 .@"struct" => comptime_int,
556556 else => unreachable,
557557 } {
558558 return switch (@typeInfo(T)) {
559 .@"struct" => |info| info.fields,
559 .@"struct" => |info| info.fields.len,
560560 else => unreachable,
561561 };
562562 }
563563 };
564 const fields_list = S.fields(@TypeOf(.{}));
565 if (fields_list.len != 0)
566 @compileError("Argument count mismatch");
564 const fields_len = S.fieldCount(@TypeOf(.{}));
565 comptime assert(fields_len == 0);
567566}
568567
569568test "registers get overwritten when ignoring return" {
test/behavior/empty_union.zig deleted-66
......@@ -1,66 +0,0 @@
1const builtin = @import("builtin");
2const std = @import("std");
3const expect = std.testing.expect;
4
5test "switch on empty enum" {
6 const E = enum {};
7 var e: E = undefined;
8 _ = &e;
9 switch (e) {}
10}
11
12test "switch on empty enum with a specified tag type" {
13 const E = enum(u8) {};
14 var e: E = undefined;
15 _ = &e;
16 switch (e) {}
17}
18
19test "switch on empty auto numbered tagged union" {
20 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
21
22 const U = union(enum(u8)) {};
23 var u: U = undefined;
24 _ = &u;
25 switch (u) {}
26}
27
28test "switch on empty tagged union" {
29 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
30
31 const E = enum {};
32 const U = union(E) {};
33 var u: U = undefined;
34 _ = &u;
35 switch (u) {}
36}
37
38test "empty union" {
39 const U = union {};
40 try expect(@sizeOf(U) == 0);
41 try expect(@alignOf(U) == 1);
42}
43
44test "empty extern union" {
45 const U = extern union {};
46 try expect(@sizeOf(U) == 0);
47 try expect(@alignOf(U) == 1);
48}
49
50test "empty union passed as argument" {
51 const U = union(enum) {
52 fn f(u: @This()) void {
53 switch (u) {}
54 }
55 };
56 U.f(@as(U, undefined));
57}
58
59test "empty enum passed as argument" {
60 const E = enum {
61 fn f(e: @This()) void {
62 switch (e) {}
63 }
64 };
65 E.f(@as(E, undefined));
66}
test/behavior/enum.zig+38-16
......@@ -823,15 +823,6 @@ test "enum with one member and u1 tag type @intFromEnum" {
823823 try expect(@intFromEnum(Enum.Test) == 0);
824824}
825825
826test "enum with comptime_int tag type" {
827 const Enum = enum(comptime_int) {
828 One = 3,
829 Two = 2,
830 Three = 1,
831 };
832 comptime assert(Tag(Enum) == comptime_int);
833}
834
835826test "enum with one member default to u0 tag type" {
836827 const E0 = enum { X };
837828 comptime assert(Tag(E0) == u0);
......@@ -1274,13 +1265,6 @@ fn getLazyInitialized(param: enum(u8) {
12741265 return @intFromEnum(param);
12751266}
12761267
1277test "Non-exhaustive enum backed by comptime_int" {
1278 const E = enum(comptime_int) { a, b, c, _ };
1279 comptime var e: E = .a;
1280 e = @as(E, @enumFromInt(378089457309184723749));
1281 try expect(@intFromEnum(e) == 378089457309184723749);
1282}
1283
12841268test "matching captures causes enum equivalence" {
12851269 const S = struct {
12861270 fn Nonexhaustive(comptime I: type) type {
......@@ -1347,3 +1331,41 @@ test "comptime @enumFromInt with signed arithmetic" {
13471331 comptime assert(x == .bar);
13481332 comptime assert(@intFromEnum(x) == 0);
13491333}
1334
1335test "switch on empty enum" {
1336 const E = enum {};
1337 var e: E = undefined;
1338 _ = &e;
1339 switch (e) {}
1340}
1341
1342test "switch on empty enum with a specified tag type" {
1343 const E = enum(u8) {};
1344 var e: E = undefined;
1345 _ = &e;
1346 switch (e) {}
1347}
1348
1349test "empty enum passed as argument" {
1350 const E = enum {
1351 fn f(e: @This()) void {
1352 switch (e) {}
1353 }
1354 };
1355 E.f(@as(E, undefined));
1356}
1357
1358test "enum int tag type uses declaration inside the enum" {
1359 const static = struct {
1360 const E = enum(E.IntTag) {
1361 const IntTag = u8;
1362 a,
1363 b,
1364 c,
1365 };
1366 };
1367 try expect(@sizeOf(static.E) == @sizeOf(u8));
1368 const val: static.E = .b;
1369 try expect(val == .b);
1370 try expect(@intFromEnum(val) == 1);
1371}
test/behavior/error.zig+33
......@@ -1109,3 +1109,36 @@ test "'if' ignores error via local while 'else' ignores error directly" {
11091109 try S.testOne(false);
11101110 try S.testOne(true);
11111111}
1112
1113test "@errorCast into own inferred error set" {
1114 const static = struct {
1115 fn foo(b: bool) !void {
1116 if (b) {
1117 return @errorCast(error.Bad);
1118 }
1119 }
1120 };
1121 try static.foo(false);
1122 if (static.foo(true)) {
1123 return error.ExpectedError;
1124 } else |err| {
1125 try expect(err == error.Bad);
1126 }
1127
1128 const errors = @typeInfo(@typeInfo(@TypeOf(static.foo(false))).error_union.error_set).error_set.?;
1129 comptime assert(errors.len == 1);
1130 comptime assert(std.mem.eql(u8, errors[0].name, "Bad"));
1131}
1132
1133test "@errorCast into other inferred error set" {
1134 const static = struct {
1135 fn foo() !void {
1136 return error.Bad;
1137 }
1138 };
1139 const Ies = @typeInfo(@TypeOf(static.foo())).error_union.error_set;
1140 const err: Ies = @errorCast(error.Bad);
1141 try expect(err == error.Bad);
1142 const non_err: Ies!u32 = @errorCast(@as(error{}!u32, 123));
1143 try expect(try non_err == 123);
1144}
test/behavior/eval.zig-121
......@@ -719,13 +719,6 @@ fn testVarInsideInlineLoop(args: anytype) !void {
719719 }
720720}
721721
722test "*align(1) u16 is the same as *align(1:0:2) u16" {
723 comptime {
724 try expect(*align(1:0:2) u16 == *align(1) u16);
725 try expect(*align(2:0:2) u16 == *u16);
726 }
727}
728
729722test "array concatenation of function calls" {
730723 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
731724 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -1081,120 +1074,6 @@ test "comptime break operand passing through runtime switch converted to runtime
10811074 try comptime S.doTheTest('b');
10821075}
10831076
1084test "no dependency loop for alignment of self struct" {
1085 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1086 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1087 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1088
1089 const S = struct {
1090 fn doTheTest() !void {
1091 var a: namespace.A = undefined;
1092 a.d = .{ .g = &buf };
1093 a.d.g[3] = 42;
1094 a.d.g[3] += 1;
1095 try expect(a.d.g[3] == 43);
1096 }
1097
1098 var buf: [10]u8 align(@alignOf([*]u8)) = undefined;
1099
1100 const namespace = struct {
1101 const B = struct { a: A };
1102 const A = C(B);
1103 };
1104
1105 pub fn C(comptime B: type) type {
1106 return struct {
1107 d: D(F) = .{},
1108
1109 const F = struct { b: B };
1110 };
1111 }
1112
1113 pub fn D(comptime F: type) type {
1114 return struct {
1115 g: [*]align(@alignOf(F)) u8 = undefined,
1116 };
1117 }
1118 };
1119 try S.doTheTest();
1120}
1121
1122test "no dependency loop for alignment of self bare union" {
1123 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1124 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1125 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1126
1127 const S = struct {
1128 fn doTheTest() !void {
1129 var a: namespace.A = undefined;
1130 a.d = .{ .g = &buf };
1131 a.d.g[3] = 42;
1132 a.d.g[3] += 1;
1133 try expect(a.d.g[3] == 43);
1134 }
1135
1136 var buf: [10]u8 align(@alignOf([*]u8)) = undefined;
1137
1138 const namespace = struct {
1139 const B = union { a: A, b: void };
1140 const A = C(B);
1141 };
1142
1143 pub fn C(comptime B: type) type {
1144 return struct {
1145 d: D(F) = .{},
1146
1147 const F = struct { b: B };
1148 };
1149 }
1150
1151 pub fn D(comptime F: type) type {
1152 return struct {
1153 g: [*]align(@alignOf(F)) u8 = undefined,
1154 };
1155 }
1156 };
1157 try S.doTheTest();
1158}
1159
1160test "no dependency loop for alignment of self tagged union" {
1161 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1162 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1163 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1164
1165 const S = struct {
1166 fn doTheTest() !void {
1167 var a: namespace.A = undefined;
1168 a.d = .{ .g = &buf };
1169 a.d.g[3] = 42;
1170 a.d.g[3] += 1;
1171 try expect(a.d.g[3] == 43);
1172 }
1173
1174 var buf: [10]u8 align(@alignOf([*]u8)) = undefined;
1175
1176 const namespace = struct {
1177 const B = union(enum) { a: A, b: void };
1178 const A = C(B);
1179 };
1180
1181 pub fn C(comptime B: type) type {
1182 return struct {
1183 d: D(F) = .{},
1184
1185 const F = struct { b: B };
1186 };
1187 }
1188
1189 pub fn D(comptime F: type) type {
1190 return struct {
1191 g: [*]align(@alignOf(F)) u8 = undefined,
1192 };
1193 }
1194 };
1195 try S.doTheTest();
1196}
1197
11981077test "equality of pointers to comptime const" {
11991078 const a: i32 = undefined;
12001079 comptime assert(&a == &a);
test/behavior/generics.zig+1-4
......@@ -339,7 +339,7 @@ test "generic instantiation of tagged union with only one field" {
339339 try expect(S.foo(.{ .s = "ab" }) == 2);
340340}
341341
342test "nested generic function" {
342test "generic parameter type is function type" {
343343 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
344344
345345 const S = struct {
......@@ -349,10 +349,7 @@ test "nested generic function" {
349349 fn bar(a: u32) anyerror!void {
350350 try expect(a == 123);
351351 }
352
353 fn g(_: *const fn (anytype) void) void {}
354352 };
355 try expect(@typeInfo(@TypeOf(S.g)).@"fn".is_generic);
356353 try S.foo(u32, S.bar, 123);
357354}
358355
test/behavior/packed-struct.zig+1-99
......@@ -438,27 +438,6 @@ test "nested packed struct field pointers" {
438438 try expectEqual(6, ptr_p1_b.*);
439439}
440440
441test "load pointer from packed struct" {
442 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
443 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
444 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
445 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
446 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
447
448 const A = struct {
449 index: u16,
450 };
451 const B = packed struct {
452 x: *A,
453 y: u32,
454 };
455 var a: A = .{ .index = 123 };
456 const b_list: []const B = &.{.{ .x = &a, .y = 99 }};
457 for (b_list) |b| {
458 try expect(b.x.index == 123);
459 }
460}
461
462441test "@intFromPtr on a packed struct field" {
463442 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
464443 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -601,19 +580,6 @@ test "packed struct fields modification" {
601580 try expect(@as(u16, @bitCast(Small.p)) == 0x1313);
602581}
603582
604test "optional pointer in packed struct" {
605 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
606 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
607 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
608 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
609 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
610
611 const T = packed struct { ptr: ?*const u8 };
612 var n: u8 = 0;
613 const x = T{ .ptr = &n };
614 try expect(x.ptr.? == &n);
615}
616
617583test "nested packed struct field access test" {
618584 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
619585 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO packed structs larger than 64 bits
......@@ -854,7 +820,7 @@ test "packed struct passed to callconv(.c) function" {
854820 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
855821
856822 const S = struct {
857 const Packed = packed struct {
823 const Packed = packed struct(u64) {
858824 a: u16,
859825 b: bool = true,
860826 c: bool = true,
......@@ -1042,48 +1008,6 @@ test "packed struct acts as a namespace" {
10421008 try expect(foo == .fizz);
10431009}
10441010
1045test "pointer loaded correctly from packed struct" {
1046 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1047 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1048 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1049 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
1050 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1051
1052 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows) return error.SkipZigTest; // crashes MSVC
1053
1054 const RAM = struct {
1055 data: [0xFFFF + 1]u8,
1056 fn new() !@This() {
1057 return .{ .data = [_]u8{0} ** 0x10000 };
1058 }
1059 fn get(self: *@This(), addr: u16) u8 {
1060 return self.data[addr];
1061 }
1062 };
1063
1064 const CPU = packed struct {
1065 interrupts: bool,
1066 ram: *RAM,
1067 fn new(ram: *RAM) !@This() {
1068 return .{
1069 .ram = ram,
1070 .interrupts = false,
1071 };
1072 }
1073 fn tick(self: *@This()) !void {
1074 const queued_interrupts = self.ram.get(0xFFFF) & self.ram.get(0xFF0F);
1075 if (self.interrupts and queued_interrupts != 0) {
1076 self.interrupts = false;
1077 }
1078 }
1079 };
1080
1081 var ram = try RAM.new();
1082 var cpu = try CPU.new(&ram);
1083 try cpu.tick();
1084 try std.testing.expect(cpu.interrupts == false);
1085}
1086
10871011test "assignment to non-byte-aligned field in packed struct" {
10881012 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
10891013 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
......@@ -1227,13 +1151,6 @@ test "2-byte packed struct argument in C calling convention" {
12271151 }
12281152}
12291153
1230test "packed struct contains optional pointer" {
1231 const foo: packed struct {
1232 a: ?*@This() = null,
1233 } = .{};
1234 try expect(foo.a == null);
1235}
1236
12371154test "packed struct equality" {
12381155 const Foo = packed struct {
12391156 a: u4,
......@@ -1297,21 +1214,6 @@ test "assign packed struct initialized with RLS to packed struct literal field"
12971214 try expect(outer.x == x);
12981215}
12991216
1300test "byte-aligned packed relocation" {
1301 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1302 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
1303 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1304 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
1305 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1306
1307 const S = struct {
1308 var global: u8 align(2) = 0;
1309 var packed_value: packed struct { x: u8, y: *align(2) u8 } = .{ .x = 111, .y = &global };
1310 };
1311 try expect(S.packed_value.x == 111);
1312 try expect(S.packed_value.y == &S.global);
1313}
1314
13151217test "packed struct store of comparison result" {
13161218 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
13171219 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
test/behavior/packed-union.zig+18-8
......@@ -1,6 +1,7 @@
11const std = @import("std");
22const builtin = @import("builtin");
33const assert = std.debug.assert;
4const expect = std.testing.expect;
45const expectEqual = std.testing.expectEqual;
56
67test "flags in packed union" {
......@@ -178,14 +179,23 @@ test "assigning to non-active field at comptime" {
178179 }
179180}
180181
181test "comptime packed union of pointers" {
182 const U = packed union {
183 a: *const u32,
184 b: *const [1]u32,
185 };
182test "packed union with explicit backing integer" {
183 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
184 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
185 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
186186
187 const x: u32 = 123;
188 const u: U = .{ .a = &x };
187 const U = packed union(i32) {
188 raw: i32,
189 unsigned_halves: packed struct { low: u16, high: u16 },
189190
190 comptime assert(u.b[0] == 123);
191 fn check(val: @This()) !void {
192 try expect(@as(i32, @bitCast(val)) == -2);
193 try expect(@as(u32, @bitCast(val)) == 0xFFFFFFFE);
194 try expect(val.raw == -2);
195 try expect(val.unsigned_halves.low == 0xFFFE);
196 try expect(val.unsigned_halves.high == 0xFFFF);
197 }
198 };
199 try U.check(.{ .raw = -2 });
200 try comptime U.check(.{ .raw = -2 });
191201}
test/behavior/sizeof_and_typeof.zig+1-41
......@@ -11,13 +11,6 @@ test "@sizeOf and @TypeOf" {
1111const x: u16 = 13;
1212const z: @TypeOf(x) = 19;
1313
14test "@sizeOf on compile-time types" {
15 try expect(@sizeOf(comptime_int) == 0);
16 try expect(@sizeOf(comptime_float) == 0);
17 try expect(@sizeOf(@TypeOf(.hi)) == 0);
18 try expect(@sizeOf(@TypeOf(type)) == 0);
19}
20
2114test "@TypeOf() with multiple arguments" {
2215 {
2316 var var_1: u32 = undefined;
......@@ -127,21 +120,6 @@ test "@bitOffsetOf" {
127120 try expect(@offsetOf(A, "g") * 8 == @bitOffsetOf(A, "g"));
128121}
129122
130test "@sizeOf(T) == 0 doesn't force resolving struct size" {
131 const S = struct {
132 const Foo = struct {
133 y: if (@sizeOf(Foo) == 0) u64 else u32,
134 };
135 const Bar = struct {
136 x: i32,
137 y: if (0 == @sizeOf(Bar)) u64 else u32,
138 };
139 };
140
141 try expect(@sizeOf(S.Foo) == 4);
142 try expect(@sizeOf(S.Bar) == 8);
143}
144
145123test "@TypeOf() has no runtime side effects" {
146124 const S = struct {
147125 fn foo(comptime T: type, ptr: *T) T {
......@@ -265,10 +243,6 @@ test "lazy size cast to float" {
265243 }
266244}
267245
268test "bitSizeOf comptime_int" {
269 try expect(@bitSizeOf(comptime_int) == 0);
270}
271
272246test "runtime instructions inside typeof in comptime only scope" {
273247 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
274248 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -336,20 +310,6 @@ test "peer type resolution with @TypeOf doesn't trigger dependency loop check" {
336310 try std.testing.expect(t.next == null);
337311}
338312
339test "@sizeOf reified union zero-size payload fields" {
340 comptime {
341 try std.testing.expect(0 == @sizeOf(@Union(.auto, null, &.{}, &.{}, &.{})));
342 try std.testing.expect(0 == @sizeOf(@Union(.auto, null, &.{"a"}, &.{void}, &.{.{}})));
343 if (builtin.mode == .Debug or builtin.mode == .ReleaseSafe) {
344 try std.testing.expect(1 == @sizeOf(@Union(.auto, null, &.{ "a", "b" }, &.{ void, void }, &.{ .{}, .{} })));
345 try std.testing.expect(1 == @sizeOf(@Union(.auto, null, &.{ "a", "b", "c" }, &.{ void, void, void }, &.{ .{}, .{}, .{} })));
346 } else {
347 try std.testing.expect(0 == @sizeOf(@Union(.auto, null, &.{ "a", "b" }, &.{ void, void }, &.{ .{}, .{} })));
348 try std.testing.expect(0 == @sizeOf(@Union(.auto, null, &.{ "a", "b", "c" }, &.{ void, void, void }, &.{ .{}, .{}, .{} })));
349 }
350 }
351}
352
353313const FILE = extern struct {
354314 dummy_field: u8,
355315};
......@@ -391,7 +351,7 @@ test "Extern function calls in @TypeOf" {
391351
392352 extern fn s_do_thing([*c]const @This(), b: c_int) c_short;
393353 };
394 const E = struct {
354 const E = extern struct {
395355 export fn s_do_thing(a: [*c]const @This(), b: c_int) c_short {
396356 _ = a;
397357 _ = b;
test/behavior/slice.zig+1-1
......@@ -160,7 +160,7 @@ test "slice of type" {
160160
161161test "pass a slice of types to a function" {
162162 const S = struct {
163 fn checkTypesSlice(types_slice: []const type) !void {
163 fn checkTypesSlice(comptime types_slice: []const type) !void {
164164 try expect(types_slice.len == 2);
165165 try expect(types_slice[0] == anyerror);
166166 try expect(types_slice[1] == bool);
test/behavior/struct.zig+73-1
......@@ -2177,7 +2177,7 @@ test "avoid unused field function body compile error" {
21772177
21782178test "pass a pointer to a comptime-only struct field to a function" {
21792179 const S = struct {
2180 fn checkField(field_ptr: *const type) !void {
2180 fn checkField(comptime field_ptr: *const type) !void {
21812181 try expect(field_ptr.* == u42);
21822182 }
21832183 };
......@@ -2233,3 +2233,75 @@ test "overaligned extern struct fields" {
22332233 try expect(std.mem.isAligned(@intFromPtr(&e.c), @alignOf(u32)));
22342234 try expect(std.mem.isAligned(@intFromPtr(&e.d), @alignOf(B)));
22352235}
2236
2237test "runtime-known slice of comptime-only struct" {
2238 const Mixed = struct { index: u32, T: type };
2239
2240 const static = struct {
2241 fn doTheTest(index_offset: usize, s: []const Mixed) !void {
2242 for (s, index_offset..) |*mixed, index| {
2243 try expect(mixed.index == index);
2244 }
2245 }
2246 };
2247
2248 try static.doTheTest(10, &.{
2249 .{ .index = 10, .T = u8 },
2250 .{ .index = 11, .T = noreturn },
2251 .{ .index = 12, .T = *opaque {} },
2252 .{ .index = 13, .T = undefined },
2253 .{ .index = 14, .T = @TypeOf(undefined) },
2254 .{ .index = 15, .T = Mixed },
2255 });
2256}
2257
2258test "struct contains aligned pointer to itself through type decl" {
2259 const Slab = struct {
2260 const Ptr = *align(64) const @This();
2261 next: Ptr,
2262 };
2263 // We intentionally use `Slab.Ptr` before `Slab`.
2264 var ptr: Slab.Ptr = undefined;
2265 var slab: Slab align(64) = undefined;
2266 ptr = &slab;
2267 slab.next = ptr;
2268
2269 try expect(ptr == &slab);
2270 try expect(slab.next == &slab);
2271 try expect(slab.next.next == &slab);
2272 try expect(slab.next.next.next == &slab);
2273}
2274
2275test "struct contains underaligned field with overaligned pointer to itself" {
2276 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
2277 const S = struct {
2278 ptr: *align(8) @This() align(1),
2279 };
2280 var val: S align(8) = undefined;
2281 val.ptr = &val;
2282 try expect(val.ptr == &val);
2283 try expect(val.ptr.ptr == &val);
2284 try expect(val.ptr.ptr.ptr == &val);
2285}
2286
2287test "struct contains pointer to function accepting that struct" {
2288 const S = struct {
2289 const FnPtr = ?*const fn (@This()) void;
2290 fn_ptr: FnPtr,
2291 };
2292 const dummy_fn_ptr: S.FnPtr = @ptrFromInt(0x100000);
2293 const dummy_s: S = .{ .fn_ptr = dummy_fn_ptr };
2294 try expect(dummy_s.fn_ptr == dummy_fn_ptr);
2295 try expect(@TypeOf(dummy_s.fn_ptr.?) == *const fn (S) void);
2296}
2297
2298test "struct queries typeinfo of struct containing pointer back to first struct" {
2299 const static = struct {
2300 const A = struct { b: *B };
2301 const B = struct { a: T: {
2302 _ = @typeInfo(A);
2303 break :T u32;
2304 } };
2305 };
2306 _ = @as(static.A, undefined);
2307}
test/behavior/struct_contains_slice_of_itself.zig+1-1
......@@ -8,7 +8,7 @@ const Node = struct {
88
99const NodeAligned = struct {
1010 payload: i32,
11 children: []align(@alignOf(NodeAligned)) NodeAligned,
11 children: []align(1) NodeAligned,
1212};
1313
1414test "struct contains slice of itself" {
test/behavior/switch.zig+5-6
......@@ -645,7 +645,7 @@ test "switch prong pointer capture alignment" {
645645 }
646646
647647 switch (u) {
648 .a, .c => |*p| comptime assert(@TypeOf(p) == *const u8),
648 .a, .c => |*p| comptime assert(@TypeOf(p) == *align(1) const u8),
649649 .b => |*p| {
650650 _ = p;
651651 return error.TestFailed;
......@@ -1141,24 +1141,23 @@ test "decl literals as switch cases" {
11411141 try comptime E.doTheTest(.foo);
11421142}
11431143
1144// TODO audit after #15909 and/or #19855 are decided/implemented
1144// TODO audit after #15909 and/or #19855 are decided/implemented.
1145// When we do that, consider adding an 'error{}' case if possible.
11451146test "switch with uninstantiable union fields" {
11461147 const U = union(enum) {
11471148 ok: void,
11481149 a: noreturn,
11491150 b: noreturn,
1150 c: error{},
11511151
11521152 fn doTheTest(u: @This()) void {
11531153 switch (u) {
11541154 .ok => {},
11551155 .a => comptime unreachable,
11561156 .b => comptime unreachable,
1157 .c => comptime unreachable,
11581157 }
11591158 switch (u) {
11601159 .ok => {},
1161 .a, .b, .c => comptime unreachable,
1160 .a, .b => comptime unreachable,
11621161 }
11631162 switch (u) {
11641163 .ok => {},
......@@ -1166,7 +1165,7 @@ test "switch with uninstantiable union fields" {
11661165 }
11671166 switch (u) {
11681167 .a => comptime unreachable,
1169 .ok, .b, .c => {},
1168 .ok, .b => {},
11701169 }
11711170 }
11721171 };
test/behavior/tuple.zig+11
......@@ -592,3 +592,14 @@ test "array of tuples that end with a zero-bit field followed by padding" {
592592 try expect(S.foo[1][1] == 4);
593593 try expect(S.foo[1][2] == {});
594594}
595
596test "call function at comptime through container-level const tuple" {
597 const static = struct {
598 const MyTuple = struct { (fn () u32) };
599 const val: MyTuple = .{foo};
600 fn foo() u32 {
601 return 1234;
602 }
603 };
604 comptime assert(static.val[0]() == 1234);
605}
test/behavior/tuple_declarations.zig+2-2
......@@ -22,13 +22,13 @@ test "tuple declaration type info" {
2222 try expect(info.fields[0].type == u32);
2323 try expect(info.fields[0].defaultValue() == 1);
2424 try expect(info.fields[0].is_comptime);
25 try expect(info.fields[0].alignment == @alignOf(u32));
25 try expect(info.fields[0].alignment == null);
2626
2727 try expectEqualStrings(info.fields[1].name, "1");
2828 try expect(info.fields[1].type == []const u8);
2929 try expect(info.fields[1].defaultValue() == null);
3030 try expect(!info.fields[1].is_comptime);
31 try expect(info.fields[1].alignment == @alignOf([]const u8));
31 try expect(info.fields[1].alignment == null);
3232 }
3333}
3434
test/behavior/type.zig+2-2
......@@ -278,13 +278,13 @@ test "Type.Union from regular enum" {
278278test "Type.Union from empty regular enum" {
279279 const E = enum {};
280280 const U = @Union(.auto, E, &.{}, &.{}, &.{});
281 try testing.expectEqual(@sizeOf(U), 0);
281 try testing.expectEqual(@typeInfo(U).@"union".fields.len, 0);
282282}
283283
284284test "Type.Union from empty Type.Enum" {
285285 const E = @Enum(u0, .exhaustive, &.{}, &.{});
286286 const U = @Union(.auto, E, &.{}, &.{}, &.{});
287 try testing.expectEqual(@sizeOf(U), 0);
287 try testing.expectEqual(@typeInfo(U).@"union".fields.len, 0);
288288}
289289
290290test "Type.Fn" {
test/behavior/type_info.zig+8-8
......@@ -82,7 +82,7 @@ fn testPointer() !void {
8282 try expect(u32_ptr_info.pointer.size == .one);
8383 try expect(u32_ptr_info.pointer.is_const == false);
8484 try expect(u32_ptr_info.pointer.is_volatile == false);
85 try expect(u32_ptr_info.pointer.alignment == @alignOf(u32));
85 try expect(u32_ptr_info.pointer.alignment == null);
8686 try expect(u32_ptr_info.pointer.child == u32);
8787 try expect(u32_ptr_info.pointer.sentinel() == null);
8888}
......@@ -99,7 +99,7 @@ fn testUnknownLenPtr() !void {
9999 try expect(u32_ptr_info.pointer.is_const == true);
100100 try expect(u32_ptr_info.pointer.is_volatile == true);
101101 try expect(u32_ptr_info.pointer.sentinel() == null);
102 try expect(u32_ptr_info.pointer.alignment == @alignOf(f64));
102 try expect(u32_ptr_info.pointer.alignment == null);
103103 try expect(u32_ptr_info.pointer.child == f64);
104104}
105105
......@@ -130,7 +130,7 @@ fn testSlice() !void {
130130 try expect(u32_slice_info.pointer.size == .slice);
131131 try expect(u32_slice_info.pointer.is_const == false);
132132 try expect(u32_slice_info.pointer.is_volatile == false);
133 try expect(u32_slice_info.pointer.alignment == 4);
133 try expect(u32_slice_info.pointer.alignment == null);
134134 try expect(u32_slice_info.pointer.child == u32);
135135}
136136
......@@ -266,9 +266,9 @@ fn testUnion() !void {
266266 try expect(notag_union_info.@"union".tag_type == null);
267267 try expect(notag_union_info.@"union".layout == .auto);
268268 try expect(notag_union_info.@"union".fields.len == 2);
269 try expect(notag_union_info.@"union".fields[0].alignment == @alignOf(void));
269 try expect(notag_union_info.@"union".fields[0].alignment == null);
270270 try expect(notag_union_info.@"union".fields[1].type == u32);
271 try expect(notag_union_info.@"union".fields[1].alignment == @alignOf(u32));
271 try expect(notag_union_info.@"union".fields[1].alignment == null);
272272
273273 const TestExternUnion = extern union {
274274 foo: *anyopaque,
......@@ -292,7 +292,7 @@ fn testStruct() !void {
292292 const unpacked_struct_info = @typeInfo(TestStruct);
293293 try expect(unpacked_struct_info.@"struct".is_tuple == false);
294294 try expect(unpacked_struct_info.@"struct".backing_integer == null);
295 try expect(unpacked_struct_info.@"struct".fields[0].alignment == @alignOf(u32));
295 try expect(unpacked_struct_info.@"struct".fields[0].alignment == null);
296296 try expect(unpacked_struct_info.@"struct".fields[0].defaultValue().? == 4);
297297 try expect(mem.eql(u8, "foobar", unpacked_struct_info.@"struct".fields[1].defaultValue().?));
298298}
......@@ -314,11 +314,11 @@ fn testPackedStruct() !void {
314314 try expect(struct_info.@"struct".layout == .@"packed");
315315 try expect(struct_info.@"struct".backing_integer == u128);
316316 try expect(struct_info.@"struct".fields.len == 4);
317 try expect(struct_info.@"struct".fields[0].alignment == 0);
317 try expect(struct_info.@"struct".fields[0].alignment == null);
318318 try expect(struct_info.@"struct".fields[2].type == f32);
319319 try expect(struct_info.@"struct".fields[2].defaultValue() == null);
320320 try expect(struct_info.@"struct".fields[3].defaultValue().? == 4);
321 try expect(struct_info.@"struct".fields[3].alignment == 0);
321 try expect(struct_info.@"struct".fields[3].alignment == null);
322322 try expect(struct_info.@"struct".decls.len == 1);
323323}
324324
test/behavior/union.zig+20-53
......@@ -148,6 +148,7 @@ const err = @as(anyerror!Agg, Agg{
148148const array = [_]Value{ v1, v2, v1, v2 };
149149
150150test "unions embedded in aggregate types" {
151 if (builtin.zig_backend == .stage2_c and builtin.target.abi == .msvc) return error.SkipZigTest;
151152 switch (array[1]) {
152153 Value.Array => |arr| try expect(arr[4] == 3),
153154 else => unreachable,
......@@ -217,26 +218,6 @@ test "union with specified enum tag" {
217218 try comptime doTest();
218219}
219220
220test "packed union generates correctly aligned type" {
221 // This test will be removed after the following accepted proposal is implemented:
222 // https://github.com/ziglang/zig/issues/24657
223 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
224 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
225 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
226 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
227 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
228
229 const U = packed union {
230 f1: *const fn () error{TestUnexpectedResult}!void,
231 f2: usize,
232 };
233 var foo = [_]U{
234 U{ .f1 = doTest },
235 U{ .f2 = 0 },
236 };
237 try foo[0].f1();
238}
239
240221fn doTest() error{TestUnexpectedResult}!void {
241222 try expect((try bar(Payload{ .A = 1234 })) == -10);
242223}
......@@ -359,12 +340,12 @@ test "simple union(enum(u32))" {
359340 try expect(@intFromEnum(@as(Tag(MultipleChoice), x)) == 60);
360341}
361342
362const PackedPtrOrInt = packed union {
363 ptr: *u8,
364 int: usize,
365};
366343test "packed union size" {
367 comptime assert(@sizeOf(PackedPtrOrInt) == @sizeOf(usize));
344 const U = packed union {
345 signed: isize,
346 unsigned: usize,
347 };
348 comptime assert(@sizeOf(U) == @sizeOf(usize));
368349}
369350
370351const ZeroBits = union {
......@@ -703,25 +684,23 @@ test "union with only 1 field casted to its enum type which has enum value speci
703684 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
704685
705686 const Literal = union(enum) {
706 Number: f64,
707 Bool: bool,
687 number: f64,
688 bool: bool,
708689 };
709690
710 const ExprTag = enum(comptime_int) {
711 Literal = 33,
712 };
691 const ExprTag = enum(u32) { literal = 33 };
692 const Expr = union(ExprTag) { literal: Literal };
713693
714 const Expr = union(ExprTag) {
715 Literal: Literal,
716 };
694 comptime assert(Tag(ExprTag) == u32);
717695
718 var e = Expr{ .Literal = Literal{ .Bool = true } };
719 _ = &e;
720 comptime assert(Tag(ExprTag) == comptime_int);
721 const t = comptime @as(ExprTag, e);
722 try expect(t == Expr.Literal);
723 try expect(@intFromEnum(t) == 33);
696 var e: Expr = undefined;
697 e = .{ .literal = .{ .bool = true } };
698
699 const t: ExprTag = e;
700 comptime assert(t == Expr.literal);
724701 comptime assert(@intFromEnum(t) == 33);
702 try expect(t == Expr.literal);
703 try expect(@intFromEnum(t) == 33);
725704}
726705
727706test "@intFromEnum works on unions" {
......@@ -893,15 +872,6 @@ test "union no tag with struct member" {
893872 u.foo();
894873}
895874
896test "union with comptime_int tag" {
897 const Union = union(enum(comptime_int)) {
898 X: u32,
899 Y: u16,
900 Z: u8,
901 };
902 comptime assert(Tag(Tag(Union)) == comptime_int);
903}
904
905875test "extern union doesn't trigger field check at comptime" {
906876 const U = extern union {
907877 x: u32,
......@@ -1031,7 +1001,7 @@ test "containers with single-field enums" {
10311001 try comptime S.doTheTest();
10321002}
10331003
1034test "@unionInit on union with tag but no fields" {
1004test "@unionInit on union with u8 tag but no fields" {
10351005 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10361006 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
10371007
......@@ -1047,10 +1017,6 @@ test "@unionInit on union with tag but no fields" {
10471017 }
10481018 };
10491019
1050 comptime {
1051 assert(@sizeOf(Data) == 1);
1052 }
1053
10541020 fn doTheTest() !void {
10551021 var data: Data = .{ .no_op = {} };
10561022 _ = &data;
......@@ -2057,6 +2023,7 @@ test "runtime union init, most-aligned field != largest" {
20572023 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
20582024 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
20592025 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2026 if (builtin.zig_backend == .stage2_c and builtin.target.abi == .msvc) return error.SkipZigTest;
20602027
20612028 const U = union(enum) {
20622029 x: u128,
test/c_abi/main.zig+2-2
......@@ -718,7 +718,7 @@ export fn zig_med_struct_ints(s: MedStructInts) void {
718718 expect(s.z == 3) catch @panic("test failure");
719719}
720720
721const SmallPackedStruct = packed struct {
721const SmallPackedStruct = packed struct(u8) {
722722 a: u2,
723723 b: u2,
724724 c: u2,
......@@ -744,7 +744,7 @@ test "C ABI small packed struct" {
744744 try expect(s2.d == 3);
745745}
746746
747const BigPackedStruct = packed struct {
747const BigPackedStruct = packed struct(u128) {
748748 a: u64,
749749 b: u64,
750750};
test/cases/compile_errors/@import_zon_bad_type.zig+4-4
......@@ -116,13 +116,13 @@ export fn testMutablePointer() void {
116116// tmp.zig:85:26: note: ZON does not allow nested optionals
117117// tmp.zig:90:29: error: type '*i32' is not available in ZON
118118// tmp.zig:90:29: note: ZON does not allow mutable pointers
119// neg_inf.zon:1:1: error: expected type '@EnumLiteral()'
120// tmp.zig:37:38: note: imported here
121119// neg_inf.zon:1:1: error: expected type '?u8'
122120// tmp.zig:57:28: note: imported here
121// neg_inf.zon:1:1: error: expected type '@EnumLiteral()'
122// tmp.zig:37:38: note: imported here
123123// neg_inf.zon:1:1: error: expected type 'tmp.E'
124124// tmp.zig:63:26: note: imported here
125// neg_inf.zon:1:1: error: expected type 'tmp.U'
126// tmp.zig:69:26: note: imported here
127125// neg_inf.zon:1:1: error: expected type 'tmp.EU'
128126// tmp.zig:75:27: note: imported here
127// neg_inf.zon:1:1: error: expected type 'tmp.U'
128// tmp.zig:69:26: note: imported here
test/cases/compile_errors/@import_zon_opt_in_err.zig+10-10
......@@ -58,25 +58,25 @@ export fn testVector() void {
5858// error
5959// imports=zon/vec2.zon
6060//
61// vec2.zon:1:2: error: expected type '?f32'
62// tmp.zig:2:29: note: imported here
6361// vec2.zon:1:2: error: expected type '*const ?f32'
6462// tmp.zig:7:36: note: imported here
6563// vec2.zon:1:2: error: expected type '?*const f32'
6664// tmp.zig:12:36: note: imported here
65// vec2.zon:1:2: error: expected type '?@EnumLiteral()'
66// tmp.zig:33:39: note: imported here
67// vec2.zon:1:2: error: expected type '?@Vector(3, f32)'
68// tmp.zig:54:41: note: imported here
69// vec2.zon:1:2: error: expected type '?[1]u8'
70// tmp.zig:38:31: note: imported here
71// vec2.zon:1:2: error: expected type '?[]const u8'
72// tmp.zig:49:36: note: imported here
6773// vec2.zon:1:2: error: expected type '?bool'
6874// tmp.zig:17:30: note: imported here
75// vec2.zon:1:2: error: expected type '?f32'
76// tmp.zig:2:29: note: imported here
6977// vec2.zon:1:2: error: expected type '?i32'
7078// tmp.zig:22:29: note: imported here
7179// vec2.zon:1:2: error: expected type '?tmp.Enum'
7280// tmp.zig:28:30: note: imported here
73// vec2.zon:1:2: error: expected type '?@EnumLiteral()'
74// tmp.zig:33:39: note: imported here
75// vec2.zon:1:2: error: expected type '?[1]u8'
76// tmp.zig:38:31: note: imported here
7781// vec2.zon:1:2: error: expected type '?tmp.Union'
7882// tmp.zig:44:31: note: imported here
79// vec2.zon:1:2: error: expected type '?[]const u8'
80// tmp.zig:49:36: note: imported here
81// vec2.zon:1:2: error: expected type '?@Vector(3, f32)'
82// tmp.zig:54:41: note: imported here
test/cases/compile_errors/@import_zon_opt_in_err_struct.zig+4-4
......@@ -13,7 +13,7 @@ export fn testTuple() void {
1313// error
1414// imports=zon/nan.zon
1515//
16//nan.zon:1:1: error: expected type '?tmp.Struct'
17//tmp.zig:3:32: note: imported here
18//nan.zon:1:1: error: expected type '?struct { bool }'
19//tmp.zig:9:31: note: imported here
16// nan.zon:1:1: error: expected type '?struct { bool }'
17// tmp.zig:9:31: note: imported here
18// nan.zon:1:1: error: expected type '?tmp.Struct'
19// tmp.zig:3:32: note: imported here
test/cases/compile_errors/@intFromPtr_with_bad_type.zig deleted-9
......@@ -1,9 +0,0 @@
1const x = 42;
2const y = @intFromPtr(&x);
3pub export fn entry() void {
4 _ = y;
5}
6
7// error
8//
9// :2:23: error: comptime-only type 'comptime_int' has no pointer address
test/cases/compile_errors/AstGen_comptime_known_struct_is_resolved_before_error.zig deleted-17
......@@ -1,17 +0,0 @@
1const S1 = struct {
2 a: S2,
3};
4const S2 = struct {
5 b: fn () void,
6};
7pub export fn entry() void {
8 var s: S1 = undefined;
9 _ = &s;
10}
11
12// error
13//
14// :8:12: error: variable of type 'tmp.S1' must be const or comptime
15// :2:8: note: struct requires comptime because of this field
16// :5:8: note: struct requires comptime because of this field
17// :5:8: note: use '*const fn () void' for a function pointer type
test/cases/compile_errors/C_pointer_pointing_to_non_C_ABI_compatible_type_or_has_align_attr.zig deleted-12
......@@ -1,12 +0,0 @@
1const Foo = struct { a: u32 };
2export fn a() void {
3 const T = [*c]Foo;
4 const t: T = undefined;
5 _ = t;
6}
7
8// error
9//
10// :3:19: error: C pointers cannot point to non-C-ABI-compatible type 'tmp.Foo'
11// :3:19: note: only extern structs and ABI sized packed structs are extern compatible
12// :1:13: note: struct declared here
test/cases/compile_errors/aggregate_too_large.zig+7-9
......@@ -12,16 +12,14 @@ const U = union {
1212 b: [1 << 32]u8,
1313};
1414
15const V = union {
16 a: u32,
17 b: T,
18};
19
2015comptime {
21 _ = S;
22 _ = T;
23 _ = U;
24 _ = V;
16 _ = @as(S, undefined);
17}
18comptime {
19 _ = @as(T, undefined);
20}
21comptime {
22 _ = @as(U, undefined);
2523}
2624
2725// error
test/cases/compile_errors/alignOf_bad_type.zig+8-2
......@@ -1,7 +1,13 @@
1export fn entry() usize {
1export fn entry0() usize {
22 return @alignOf(noreturn);
33}
4const S = struct { a: u32, b: noreturn };
5export fn entry1() usize {
6 return @alignOf(S);
7}
48
59// error
610//
7// :2:21: error: no align available for type 'noreturn'
11// :2:21: error: no align available for uninstantiable type 'noreturn'
12// :6:21: error: no align available for uninstantiable type 'tmp.S'
13// :4:11: note: struct declared here
test/cases/compile_errors/align_zero.zig+4-4
......@@ -30,11 +30,11 @@ export fn g() void {
3030}
3131
3232export fn h() void {
33 _ = struct { field: i32 align(0) };
33 _ = @as(struct { field: i32 align(0) }, undefined);
3434}
3535
3636export fn i() void {
37 _ = union { field: i32 align(0) };
37 _ = @as(union { field: i32 align(0) }, undefined);
3838}
3939
4040export fn j() void {
......@@ -54,7 +54,7 @@ export fn k() void {
5454// :20:30: error: alignment must be >= 1
5555// :25:16: error: alignment must be >= 1
5656// :29:17: error: alignment must be >= 1
57// :33:35: error: alignment must be >= 1
58// :37:34: error: alignment must be >= 1
57// :33:39: error: alignment must be >= 1
58// :37:38: error: alignment must be >= 1
5959// :41:51: error: alignment must be >= 1
6060// :45:25: error: alignment must be >= 1
test/cases/compile_errors/assign_inline_fn_to_non-comptime_var.zig deleted-10
......@@ -1,10 +0,0 @@
1export fn entry() void {
2 var a = &b;
3 _ = &a;
4}
5inline fn b() void {}
6
7// error
8//
9// :2:9: error: variable of type '*const fn () callconv(.@"inline") void' must be const or comptime
10// :2:9: note: function has inline calling convention
test/cases/compile_errors/bit_ptr_non_packed.zig+6-2
......@@ -16,7 +16,11 @@ export fn entry3() void {
1616// error
1717//
1818// :3:23: error: bit-pointer cannot refer to value of type 'tmp.entry1.S'
19// :3:23: note: only packed structs layout are allowed in packed types
19// :3:23: note: non-packed structs do not have a bit-packed representation
20// :2:22: note: struct declared here
2021// :8:36: error: bit-pointer cannot refer to value of type 'tmp.entry2.S'
21// :8:36: note: only packed structs layout are allowed in packed types
22// :8:36: note: non-packed structs do not have a bit-packed representation
23// :7:15: note: struct declared here
2224// :13:23: error: bit-pointer cannot refer to value of type 'tmp.entry3.E'
25// :12:15: note: integer tag type of enum is inferred
26// :12:15: note: consider explicitly specifying the integer tag type
test/cases/compile_errors/bitsize_of_packed_struct_checks_backing_int_ty.zig+3-1
......@@ -8,4 +8,6 @@ pub export fn entry() void {
88
99// error
1010//
11// :1:27: error: backing integer type 'u32' has bit size 32 but the struct fields have a total bit size of 1
11// :1:20: error: backing integer bit width does not match total bit width of fields
12// :1:27: note: backing integer 'u32' has bit width '32'
13// :1:20: note: struct fields have total bit width '1'
test/cases/compile_errors/c_pointer_to_void.zig deleted-9
......@@ -1,9 +0,0 @@
1export fn entry() void {
2 const a: [*c]void = undefined;
3 _ = a;
4}
5
6// error
7//
8// :2:18: error: C pointers cannot point to non-C-ABI-compatible type 'void'
9// :2:18: note: 'void' is a zero bit type; for C 'void' use 'anyopaque'
test/cases/compile_errors/call_runtime_known_inline_fn_ptr.zig created+11
......@@ -0,0 +1,11 @@
1export fn entry() void {
2 var a = &b;
3 a = a;
4 a();
5}
6inline fn b() void {}
7
8// error
9//
10// :4:5: error: unable to resolve comptime value
11// :4:5: note: function being called inline must be comptime-known
test/cases/compile_errors/coerce_int_to_float.zig+6-6
......@@ -40,13 +40,13 @@ export fn entry() void {
4040
4141// error
4242//
43// :6:20: error: expected type 'f16', found 'u12'
43// :6:20: error: expected type 'f128', found 'i115'
44// :6:20: error: expected type 'f128', found 'u114'
4445// :6:20: error: expected type 'f16', found 'i13'
45// :6:20: error: expected type 'f32', found 'u25'
46// :6:20: error: expected type 'f16', found 'u12'
4647// :6:20: error: expected type 'f32', found 'i26'
47// :6:20: error: expected type 'f64', found 'u54'
48// :6:20: error: expected type 'f32', found 'u25'
4849// :6:20: error: expected type 'f64', found 'i55'
49// :6:20: error: expected type 'f80', found 'u65'
50// :6:20: error: expected type 'f64', found 'u54'
5051// :6:20: error: expected type 'f80', found 'i66'
51// :6:20: error: expected type 'f128', found 'u114'
52// :6:20: error: expected type 'f128', found 'i115'
52// :6:20: error: expected type 'f80', found 'u65'
test/cases/compile_errors/comptime_var_referenced_by_type.zig+1-1
......@@ -21,6 +21,6 @@ comptime {
2121// error
2222//
2323// :7:16: error: captured value contains reference to comptime var
24// :7:16: note: 'wrapper' points to '@as(*const tmp.Wrapper, @ptrCast(&v0)).*', where
24// :7:16: note: 'wrapper' points to 'v0', where
2525// :16:5: note: 'v0.ptr' points to comptime var declared here
2626// :17:29: note: called at comptime here
test/cases/compile_errors/direct_struct_loop.zig+1-1
......@@ -7,4 +7,4 @@ export fn entry() usize {
77
88// error
99//
10// :1:11: error: struct 'tmp.A' depends on itself
10// :2:8: error: type 'tmp.A' depends on itself for field declared here
test/cases/compile_errors/directly_embedding_opaque_type_in_struct_and_union.zig+4-2
......@@ -26,9 +26,11 @@ export fn d() void {
2626
2727// error
2828//
29// :3:8: error: opaque types have unknown size and therefore cannot be directly embedded in structs
29// :3:8: error: cannot directly embed opaque type 'tmp.O' in struct
30// :3:8: note: opaque types have unknown size
3031// :1:11: note: opaque declared here
31// :7:10: error: opaque types have unknown size and therefore cannot be directly embedded in unions
32// :7:10: error: cannot directly embed opaque type 'tmp.O' in union
33// :7:10: note: opaque types have unknown size
3234// :1:11: note: opaque declared here
3335// :18:24: error: cannot cast to opaque type 'tmp.O'
3436// :1:11: note: opaque declared here
test/cases/compile_errors/empty_extern_union.zig created+8
......@@ -0,0 +1,8 @@
1export fn foo() void {
2 const U = extern union {};
3 _ = @as(U, undefined);
4}
5
6// error
7//
8// :2:22: error: extern union has no fields
test/cases/compile_errors/empty_packed_union.zig created+8
......@@ -0,0 +1,8 @@
1export fn foo() void {
2 const U = packed union {};
3 _ = @as(U, undefined);
4}
5
6// error
7//
8// :2:22: error: packed union has no fields
test/cases/compile_errors/enum_backed_by_comptime_int.zig created+8
......@@ -0,0 +1,8 @@
1const E = enum(comptime_int) { a };
2comptime {
3 _ = E.a;
4}
5
6// error
7//
8// :1:16: error: expected integer tag type, found 'comptime_int'
test/cases/compile_errors/enum_backed_by_comptime_int_must_be_casted_from_comptime_value.zig deleted-12
......@@ -1,12 +0,0 @@
1export fn entry() void {
2 const Tag = enum(comptime_int) { a, b };
3
4 var v: u32 = 0;
5 _ = &v;
6 _ = @as(Tag, @enumFromInt(v));
7}
8
9// error
10//
11// :6:31: error: unable to resolve comptime value
12// :6:31: note: value casted to enum with 'comptime_int' tag type must be comptime-known
test/cases/compile_errors/enum_backed_by_comptime_int_must_be_comptime.zig deleted-9
......@@ -1,9 +0,0 @@
1pub export fn entry() void {
2 const E = enum(comptime_int) { a, b, c, _ };
3 var e: E = .a;
4 _ = &e;
5}
6
7// error
8//
9// :3:12: error: variable of type 'tmp.entry.E' must be const or comptime
test/cases/compile_errors/enum_field_value_references_enum.zig+4-8
......@@ -1,15 +1,11 @@
11pub const Foo = enum(c_int) {
2 A = Foo.B,
3 C = D,
4
5 pub const B = 0;
2 a = 10,
3 b = @intFromEnum(Foo.a) - 1,
64};
75export fn entry() void {
8 const s: Foo = Foo.E;
9 _ = s;
6 _ = @as(Foo, .a);
107}
11const D = 1;
128
139// error
1410//
15// :1:5: error: dependency loop detected
11// :3:25: error: type 'tmp.Foo' depends on itself for field usage here
test/cases/compile_errors/enum_field_value_references_nonexistent_circular.zig+1-1
......@@ -10,4 +10,4 @@ const D = 1;
1010
1111// error
1212//
13// :1:5: error: dependency loop detected
13// :2:12: error: type 'tmp.Foo' depends on itself for field usage here
test/cases/compile_errors/enum_uses_own_typeinfo.zig created+15
......@@ -0,0 +1,15 @@
1const E = enum(u9) {
2 const a_val: @typeInfo(E).@"enum".tag_type = 0;
3 a = a_val,
4};
5comptime {
6 _ = E.a;
7}
8
9// error
10//
11// error: dependency loop with length 3
12// :3:9: note: type 'tmp.E' uses value of declaration 'tmp.E.a_val' here
13// :2:50: note: value of declaration 'tmp.E.a_val' uses type of declaration 'tmp.E.a_val' here
14// :2:18: note: type of declaration 'tmp.E.a_val' depends on type 'tmp.E' for type information query here
15// note: eliminate any one of these dependencies to break the loop
test/cases/compile_errors/enum_value_already_taken.zig+2-2
......@@ -12,5 +12,5 @@ export fn entry() void {
1212
1313// error
1414//
15// :6:9: error: enum tag value 60 already taken
16// :4:9: note: other occurrence here
15// :6:9: error: enum tag value '60' for field 'E' already taken
16// :4:9: note: previous occurrence in field 'C'
test/cases/compile_errors/error_set_membership.zig+2-1
......@@ -26,5 +26,6 @@ pub fn main() Error!void {
2626// error
2727// target=x86_64-linux
2828//
29// :23:29: error: expected type 'error{InvalidCharacter}', found '@typeInfo(@typeInfo(@TypeOf(tmp.fooey)).@"fn".return_type.?).error_union.error_set'
29// :23:29: error: expected type 'error{InvalidCharacter}!void', found '@typeInfo(@typeInfo(@TypeOf(tmp.fooey)).@"fn".return_type.?).error_union.error_set'
3030// :23:29: note: 'error.InvalidDirection' not a member of destination error set
31// :22:20: note: function return type declared here
test/cases/compile_errors/exported_enum_without_explicit_integer_tag_type.zig+2-2
......@@ -11,6 +11,6 @@ comptime {
1111//
1212// :3:5: error: unable to export type 'type'
1313// :7:5: error: unable to export type 'tmp.E'
14// :7:5: note: enum tag type 'u1' is not extern compatible
15// :7:5: note: only integers with 0, 8, 16, 32, 64 and 128 bits are extern compatible
14// :1:11: note: integer tag type of enum is inferred
15// :1:11: note: consider explicitly specifying the integer tag type
1616// :1:11: note: enum declared here
test/cases/compile_errors/extern_struct_with_extern-compatible_but_inferred_integer_tag_type.zig deleted-45
......@@ -1,45 +0,0 @@
1// zig fmt: off
2pub const E = enum {
3@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",
4@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23",
5@"24",@"25",@"26",@"27",@"28",@"29",@"30",@"31",@"32",@"33",@"34",
6@"35",@"36",@"37",@"38",@"39",@"40",@"41",@"42",@"43",@"44",@"45",
7@"46",@"47",@"48",@"49",@"50",@"51",@"52",@"53",@"54",@"55",@"56",
8@"57",@"58",@"59",@"60",@"61",@"62",@"63",@"64",@"65",@"66",@"67",
9@"68",@"69",@"70",@"71",@"72",@"73",@"74",@"75",@"76",@"77",@"78",
10@"79",@"80",@"81",@"82",@"83",@"84",@"85",@"86",@"87",@"88",@"89",
11@"90",@"91",@"92",@"93",@"94",@"95",@"96",@"97",@"98",@"99",@"100",
12@"101",@"102",@"103",@"104",@"105",@"106",@"107",@"108",@"109",
13@"110",@"111",@"112",@"113",@"114",@"115",@"116",@"117",@"118",
14@"119",@"120",@"121",@"122",@"123",@"124",@"125",@"126",@"127",
15@"128",@"129",@"130",@"131",@"132",@"133",@"134",@"135",@"136",
16@"137",@"138",@"139",@"140",@"141",@"142",@"143",@"144",@"145",
17@"146",@"147",@"148",@"149",@"150",@"151",@"152",@"153",@"154",
18@"155",@"156",@"157",@"158",@"159",@"160",@"161",@"162",@"163",
19@"164",@"165",@"166",@"167",@"168",@"169",@"170",@"171",@"172",
20@"173",@"174",@"175",@"176",@"177",@"178",@"179",@"180",@"181",
21@"182",@"183",@"184",@"185",@"186",@"187",@"188",@"189",@"190",
22@"191",@"192",@"193",@"194",@"195",@"196",@"197",@"198",@"199",
23@"200",@"201",@"202",@"203",@"204",@"205",@"206",@"207",@"208",
24@"209",@"210",@"211",@"212",@"213",@"214",@"215",@"216",@"217",
25@"218",@"219",@"220",@"221",@"222",@"223",@"224",@"225",@"226",
26@"227",@"228",@"229",@"230",@"231",@"232",@"233",@"234",@"235",
27@"236",@"237",@"238",@"239",@"240",@"241",@"242",@"243",@"244",
28@"245",@"246",@"247",@"248",@"249",@"250",@"251",@"252",@"253",
29@"254",@"255", @"256"
30};
31// zig fmt: on
32pub const S = extern struct {
33 e: E,
34};
35export fn entry() void {
36 const s: S = undefined;
37 _ = s;
38}
39
40// error
41//
42// :33:8: error: extern structs cannot contain fields of type 'tmp.E'
43// :33:8: note: enum tag type 'u9' is not extern compatible
44// :33:8: note: only integers with 0 or power of two bits are extern compatible
45// :2:15: note: enum declared here
test/cases/compile_errors/extern_struct_with_non-extern-compatible_integer_tag_type.zig+2-2
......@@ -10,6 +10,6 @@ export fn entry() void {
1010// error
1111//
1212// :3:8: error: extern structs cannot contain fields of type 'tmp.E'
13// :3:8: note: enum tag type 'u31' is not extern compatible
14// :3:8: note: only integers with 0 or power of two bits are extern compatible
13// :1:15: note: enum tag type 'u31' is not extern compatible
14// :1:15: note: only integers with 0 or power of two bits are extern compatible
1515// :1:15: note: enum declared here
test/cases/compile_errors/fn_body_in_struct_runtime_known.zig created+17
......@@ -0,0 +1,17 @@
1const S1 = struct {
2 a: S2,
3};
4const S2 = struct {
5 b: fn () void,
6};
7pub export fn entry() void {
8 var s: S1 = undefined;
9 _ = &s;
10}
11
12// error
13//
14// :8:12: error: variable of type 'tmp.S1' must be const or comptime
15// :2:8: note: struct requires comptime because of this field
16// :5:8: note: struct requires comptime because of this field
17// :5:8: note: use '*const fn () void' for a function pointer type
test/cases/compile_errors/fn_type_returning_pointer_to_itself.zig created+8
......@@ -0,0 +1,8 @@
1const MyFn = fn () ?*const MyFn;
2comptime {
3 _ = MyFn;
4}
5
6// error
7//
8// :1:28: error: value of declaration 'tmp.MyFn' depends on itself here
test/cases/compile_errors/function_ptr_alignment.zig+1-1
......@@ -11,5 +11,5 @@ comptime {
1111// error
1212// target=x86_64-linux
1313//
14// :8:41: error: expected type '*align(2) const fn () void', found '*const fn () void'
14// :8:41: error: expected type '*align(2) const fn () void', found '*align(1) const fn () void'
1515// :8:41: note: pointer alignment '1' cannot cast into pointer alignment '2'
test/cases/compile_errors/function_with_non-extern_non-packed_enum_parameter.zig+2-2
......@@ -7,6 +7,6 @@ export fn entry(foo: Foo) void {
77// target=x86_64-linux
88//
99// :2:17: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'x86_64_sysv'
10// :2:17: note: enum tag type 'u2' is not extern compatible
11// :2:17: note: only integers with 0, 8, 16, 32, 64 and 128 bits are extern compatible
10// :1:13: note: integer tag type of enum is inferred
11// :1:13: note: consider explicitly specifying the integer tag type
1212// :1:13: note: enum declared here
test/cases/compile_errors/function_with_non-extern_non-packed_struct_parameter.zig+1-1
......@@ -11,5 +11,5 @@ export fn entry(foo: Foo) void {
1111// target=x86_64-linux
1212//
1313// :6:17: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'x86_64_sysv'
14// :6:17: note: only extern structs and ABI sized packed structs are extern compatible
14// :6:17: note: struct with automatic layout has no guaranteed in-memory representation
1515// :1:13: note: struct declared here
test/cases/compile_errors/function_with_non-extern_non-packed_union_parameter.zig+1-1
......@@ -11,5 +11,5 @@ export fn entry(foo: Foo) void {
1111// target=x86_64-linux
1212//
1313// :6:17: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'x86_64_sysv'
14// :6:17: note: only extern unions and ABI sized packed unions are extern compatible
14// :6:17: note: union with automatic layout has no guaranteed in-memory representation
1515// :1:13: note: union declared here
test/cases/compile_errors/generic_function_returning_opaque_type.zig+1-1
......@@ -11,6 +11,6 @@ export fn bar() void {
1111
1212// error
1313//
14// :1:30: error: opaque return type 'anyopaque' not allowed
1415// :1:30: error: opaque return type 'tmp.MyOpaque' not allowed
1516// :4:18: note: opaque declared here
16// :1:30: error: opaque return type 'anyopaque' not allowed
test/cases/compile_errors/implicit_backing_type_in_extern_context.zig created+51
......@@ -0,0 +1,51 @@
1const PackedStruct = packed struct { x: u32 };
2const PackedUnion = packed union { x: u32 };
3
4/// This enum has 256 fields, so `u8` will be its inferred tag type.
5const Enum = enum {
6 // zig fmt: off
7 _00, _01, _02, _03, _04, _05, _06, _07, _08, _09, _0a, _0b, _0c, _0d, _0e, _0f,
8 _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _1a, _1b, _1c, _1d, _1e, _1f,
9 _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _2a, _2b, _2c, _2d, _2e, _2f,
10 _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _3a, _3b, _3c, _3d, _3e, _3f,
11 _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _4a, _4b, _4c, _4d, _4e, _4f,
12 _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _5a, _5b, _5c, _5d, _5e, _5f,
13 _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _6a, _6b, _6c, _6d, _6e, _6f,
14 _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, _7a, _7b, _7c, _7d, _7e, _7f,
15 _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _8a, _8b, _8c, _8d, _8e, _8f,
16 _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, _9a, _9b, _9c, _9d, _9e, _9f,
17 _a0, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8, _a9, _aa, _ab, _ac, _ad, _ae, _af,
18 _b0, _b1, _b2, _b3, _b4, _b5, _b6, _b7, _b8, _b9, _ba, _bb, _bc, _bd, _be, _bf,
19 _c0, _c1, _c2, _c3, _c4, _c5, _c6, _c7, _c8, _c9, _ca, _cb, _cc, _cd, _ce, _cf,
20 _d0, _d1, _d2, _d3, _d4, _d5, _d6, _d7, _d8, _d9, _da, _db, _dc, _dd, _de, _df,
21 _e0, _e1, _e2, _e3, _e4, _e5, _e6, _e7, _e8, _e9, _ea, _eb, _ec, _ed, _ee, _ef,
22 _f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _fa, _fb, _fc, _fd, _fe, _ff,
23 // zig fmt: on
24};
25
26const Extern0 = extern struct { val: PackedStruct };
27const Extern1 = extern struct { val: PackedUnion };
28const Extern2 = extern struct { val: Enum };
29
30comptime {
31 _ = @as(Extern0, undefined);
32}
33comptime {
34 _ = @as(Extern1, undefined);
35}
36comptime {
37 _ = @as(Extern2, undefined);
38}
39
40// error
41//
42// :26:38: error: extern structs cannot contain fields of type 'tmp.PackedStruct'
43// :26:38: note: inferred backing integer of packed struct has unspecified signedness
44// :1:29: note: struct declared here
45// :27:38: error: extern structs cannot contain fields of type 'tmp.PackedUnion'
46// :27:38: note: inferred backing integer of packed union has unspecified signedness
47// :2:28: note: union declared here
48// :28:38: error: extern structs cannot contain fields of type 'tmp.Enum'
49// :5:14: note: integer tag type of enum is inferred
50// :5:14: note: consider explicitly specifying the integer tag type
51// :5:14: note: enum declared here
test/cases/compile_errors/indexing_an_array_of_size_zero.zig+1-1
......@@ -6,4 +6,4 @@ export fn foo() void {
66
77// error
88//
9// :3:27: error: indexing into empty array is not allowed
9// :3:27: error: cannot index into empty array
test/cases/compile_errors/indexing_an_array_of_size_zero_with_runtime_index.zig+1-1
......@@ -8,4 +8,4 @@ export fn foo() void {
88
99// error
1010//
11// :5:27: error: indexing into empty array is not allowed
11// :5:27: error: cannot index into empty array
test/cases/compile_errors/indirect_struct_loop.zig+5-1
......@@ -13,4 +13,8 @@ export fn entry() usize {
1313
1414// error
1515//
16// :1:11: error: struct 'tmp.A' depends on itself
16// error: dependency loop with length 3
17// :2:8: note: type 'tmp.A' depends on type 'tmp.B' for field declared here
18// :5:8: note: type 'tmp.B' depends on type 'tmp.C' for field declared here
19// :8:8: note: type 'tmp.C' depends on type 'tmp.A' for field declared here
20// note: eliminate any one of these dependencies to break the loop
test/cases/compile_errors/initialize_empty_union.zig created+81
......@@ -0,0 +1,81 @@
1const EnumInferred = enum {};
2const EnumExplicit = enum(u8) {};
3const EnumNonexhaustive = enum(u8) { _ };
4
5const U0 = union {};
6const U1 = union(enum) {};
7const U2 = union(enum(u8)) {};
8const U3 = union(EnumInferred) {};
9const U4 = union(EnumExplicit) {};
10const U5 = union(EnumNonexhaustive) {};
11
12export fn init0() void {
13 _ = @as(U0, undefined);
14}
15export fn init1() void {
16 _ = @as(U1, undefined);
17}
18export fn init2() void {
19 _ = @as(U2, undefined);
20}
21export fn init3() void {
22 _ = @as(U3, undefined);
23}
24export fn init4() void {
25 _ = @as(U4, undefined);
26}
27export fn init5() void {
28 _ = @as(U5, undefined);
29}
30
31export fn deref0(ptr: *const U0) void {
32 _ = ptr.*;
33}
34export fn deref1(ptr: *const U1) void {
35 _ = ptr.*;
36}
37export fn deref2(ptr: *const U2) void {
38 _ = ptr.*;
39}
40export fn deref3(ptr: *const U3) void {
41 _ = ptr.*;
42}
43export fn deref4(ptr: *const U4) void {
44 _ = ptr.*;
45}
46export fn deref5(ptr: *const U5) void {
47 _ = ptr.*;
48}
49
50// error
51//
52// :13:17: error: expected type 'tmp.U0', found '@TypeOf(undefined)'
53// :13:17: note: cannot coerce to uninstantiable type 'tmp.U0'
54// :5:12: note: union declared here
55// :16:17: error: expected type 'tmp.U1', found '@TypeOf(undefined)'
56// :16:17: note: cannot coerce to uninstantiable type 'tmp.U1'
57// :6:12: note: union declared here
58// :19:17: error: expected type 'tmp.U2', found '@TypeOf(undefined)'
59// :19:17: note: cannot coerce to uninstantiable type 'tmp.U2'
60// :7:12: note: union declared here
61// :22:17: error: expected type 'tmp.U3', found '@TypeOf(undefined)'
62// :22:17: note: cannot coerce to uninstantiable type 'tmp.U3'
63// :8:12: note: union declared here
64// :25:17: error: expected type 'tmp.U4', found '@TypeOf(undefined)'
65// :25:17: note: cannot coerce to uninstantiable type 'tmp.U4'
66// :9:12: note: union declared here
67// :28:17: error: expected type 'tmp.U5', found '@TypeOf(undefined)'
68// :28:17: note: cannot coerce to uninstantiable type 'tmp.U5'
69// :10:12: note: union declared here
70// :32:12: error: cannot load uninstantiable type 'tmp.U0'
71// :5:12: note: union declared here
72// :35:12: error: cannot load uninstantiable type 'tmp.U1'
73// :6:12: note: union declared here
74// :38:12: error: cannot load uninstantiable type 'tmp.U2'
75// :7:12: note: union declared here
76// :41:12: error: cannot load uninstantiable type 'tmp.U3'
77// :8:12: note: union declared here
78// :44:12: error: cannot load uninstantiable type 'tmp.U4'
79// :9:12: note: union declared here
80// :47:12: error: cannot load uninstantiable type 'tmp.U5'
81// :10:12: note: union declared here
test/cases/compile_errors/instantiating_an_undefined_value_for_an_invalid_struct_that_contains_itself.zig+1-1
......@@ -10,4 +10,4 @@ export fn entry() usize {
1010
1111// error
1212//
13// :1:13: error: struct 'tmp.Foo' depends on itself
13// :2:8: error: type 'tmp.Foo' depends on itself for field declared here
test/cases/compile_errors/instantiating_an_undefined_value_for_an_invalid_union_that_contains_itself.zig+1-1
......@@ -10,4 +10,4 @@ export fn entry() usize {
1010
1111// error
1212//
13// :1:13: error: union 'tmp.Foo' depends on itself
13// :2:8: error: type 'tmp.Foo' depends on itself for field declared here
test/cases/compile_errors/invalid_dependency_on_struct_size.zig+12-10
......@@ -1,16 +1,18 @@
1comptime {
2 const S = struct {
3 const Foo = struct {
4 y: Bar,
5 };
6 const Bar = struct {
7 y: if (@sizeOf(Foo) == 0) u64 else void,
8 };
1const S = struct {
2 const Foo = struct {
3 y: Bar,
94 };
10
5 const Bar = struct {
6 y: if (@sizeOf(Foo) == 0) u64 else void,
7 };
8};
9comptime {
1110 _ = @sizeOf(S.Foo) + 1;
1211}
1312
1413// error
1514//
16// :6:21: error: struct layout depends on it having runtime bits
15// error: dependency loop with length 2
16// :3:12: note: type 'tmp.S.Foo' depends on type 'tmp.S.Bar' for field declared here
17// :6:24: note: type 'tmp.S.Bar' depends on type 'tmp.S.Foo' for size query here
18// note: eliminate any one of these dependencies to break the loop
test/cases/compile_errors/invalid_optional_type_in_extern_struct.zig+2-2
......@@ -2,10 +2,10 @@ const stroo = extern struct {
22 moo: ?[*c]u8,
33};
44export fn testf(fluff: *stroo) void {
5 _ = fluff;
5 _ = fluff.*;
66}
77
88// error
99//
1010// :2:10: error: extern structs cannot contain fields of type '?[*c]u8'
11// :2:10: note: only pointer like optionals are extern compatible
11// :2:10: note: non-pointer optionals have no guaranteed in-memory representation
test/cases/compile_errors/invalid_pointer_arithmetic.zig+1-7
......@@ -26,11 +26,6 @@ comptime {
2626 _ = x - y;
2727}
2828
29comptime {
30 const x: [*]u0 = @ptrFromInt(1);
31 _ = x + 1;
32}
33
3429comptime {
3530 const x: *u0 = @ptrFromInt(1);
3631 const y: *u0 = @ptrFromInt(2);
......@@ -46,5 +41,4 @@ comptime {
4641// :12:11: error: invalid operands to binary expression: 'pointer' and 'pointer'
4742// :20:11: error: incompatible pointer arithmetic operands '[*]u8' and '[*]u16'
4843// :26:11: error: incompatible pointer arithmetic operands '*u8' and '*u16'
49// :31:11: error: pointer arithmetic requires element type 'u0' to have runtime bits
50// :37:11: error: pointer arithmetic requires element type 'u0' to have runtime bits
44// :32:11: error: pointer subtraction requires element type 'u0' to have runtime bits
test/cases/compile_errors/invalid_type_in_builtin_extern.zig+10-4
......@@ -1,16 +1,22 @@
11const x = @extern(*comptime_int, .{ .name = "foo" });
22const y = @extern(*fn (u8) u8, .{ .name = "bar" });
3pub export fn entry() void {
3const z = @extern(*fn (u8) callconv(.c) u8, .{ .name = "bar" });
4comptime {
45 _ = x;
56}
6pub export fn entry2() void {
7comptime {
78 _ = y;
89}
10comptime {
11 _ = z;
12}
913
1014// error
1115//
1216// :1:19: error: extern symbol cannot have type '*comptime_int'
13// :1:19: note: pointer to comptime-only type 'comptime_int'
17// :1:19: note: pointer element type 'comptime_int' is not extern compatible
1418// :2:19: error: extern symbol cannot have type '*fn (u8) u8'
15// :2:19: note: pointer to extern function must be 'const'
19// :2:19: note: pointer element type 'fn (u8) u8' is not extern compatible
1620// :2:19: note: extern function must specify calling convention
21// :3:19: error: extern symbol cannot have type '*fn (u8) callconv(.c) u8'
22// :3:19: note: pointer to extern function must be 'const'
test/cases/compile_errors/non-const_variables_of_things_that_require_const_variables.zig+18-23
......@@ -1,49 +1,44 @@
1export fn entry1() void {
2 var m2 = &2;
3 _ = &m2;
4}
5export fn entry2() void {
1export fn entry0() void {
62 var a = undefined;
73 _ = &a;
84}
9export fn entry3() void {
5export fn entry1() void {
106 var b = 1;
117 _ = &b;
128}
13export fn entry4() void {
9export fn entry2() void {
1410 var c = 1.0;
1511 _ = &c;
1612}
17export fn entry5() void {
13export fn entry3() void {
1814 var d = null;
1915 _ = &d;
2016}
21export fn entry6(opaque_: *Opaque) void {
17export fn entry4(opaque_: *Opaque) void {
2218 var e = opaque_.*;
2319 _ = &e;
2420}
25export fn entry7() void {
21export fn entry5() void {
2622 var f = i32;
2723 _ = &f;
2824}
2925const Opaque = opaque {};
30export fn entry8() void {
26export fn entry6() void {
3127 var e: Opaque = undefined;
3228 _ = &e;
3329}
3430
3531// error
3632//
37// :2:9: error: variable of type '*const comptime_int' must be const or comptime
38// :6:9: error: variable of type '@TypeOf(undefined)' must be const or comptime
39// :10:9: error: variable of type 'comptime_int' must be const or comptime
33// :2:9: error: variable of type '@TypeOf(undefined)' must be const or comptime
34// :6:9: error: variable of type 'comptime_int' must be const or comptime
35// :6:9: note: to modify this variable at runtime, it must be given an explicit fixed-size number type
36// :10:9: error: variable of type 'comptime_float' must be const or comptime
4037// :10:9: note: to modify this variable at runtime, it must be given an explicit fixed-size number type
41// :14:9: error: variable of type 'comptime_float' must be const or comptime
42// :14:9: note: to modify this variable at runtime, it must be given an explicit fixed-size number type
43// :18:9: error: variable of type '@TypeOf(null)' must be const or comptime
44// :22:20: error: cannot load opaque type 'tmp.Opaque'
45// :29:16: note: opaque declared here
46// :26:9: error: variable of type 'type' must be const or comptime
47// :26:9: note: types are not available at runtime
48// :31:12: error: non-extern variable with opaque type 'tmp.Opaque'
49// :29:16: note: opaque declared here
38// :14:9: error: variable of type '@TypeOf(null)' must be const or comptime
39// :18:20: error: cannot load opaque type 'tmp.Opaque'
40// :25:16: note: opaque declared here
41// :22:9: error: variable of type 'type' must be const or comptime
42// :22:9: note: types are not available at runtime
43// :27:12: error: non-extern variable with opaque type 'tmp.Opaque'
44// :25:16: note: opaque declared here
test/cases/compile_errors/non-exhaustive_enum_marker_assigned_a_value.zig-11
......@@ -3,18 +3,7 @@ const A = enum {
33 b,
44 _ = 1,
55};
6const B = enum {
7 a,
8 b,
9 _,
10};
11comptime {
12 _ = A;
13 _ = B;
14}
156
167// error
178//
189// :4:9: error: '_' is used to mark an enum as non-exhaustive and cannot be assigned a value
19// :6:11: error: non-exhaustive enum missing integer tag type
20// :9:5: note: marked non-exhaustive here
test/cases/compile_errors/non-exhaustive_enum_missing_tag_type.zig created+10
......@@ -0,0 +1,10 @@
1const E = enum {
2 a,
3 b,
4 _,
5};
6
7// error
8//
9// :1:11: error: non-exhaustive enum missing integer tag type
10// :4:5: note: marked non-exhaustive here
test/cases/compile_errors/non-exhaustive_enum_specifies_every_value.zig+1-1
......@@ -4,7 +4,7 @@ const C = enum(u1) {
44 _,
55};
66pub export fn entry() void {
7 _ = C;
7 _ = C.a;
88}
99
1010// error
test/cases/compile_errors/non-inline_for_loop_on_a_type_that_requires_comptime.zig+1-1
......@@ -11,6 +11,6 @@ export fn entry() void {
1111
1212// error
1313//
14// :7:10: error: values of type '[2]tmp.Foo' must be comptime-known, but index value is runtime-known
14// :7:10: error: values of type 'tmp.Foo' must be comptime-known, but index value is runtime-known
1515// :3:8: note: struct requires comptime because of this field
1616// :3:8: note: types are not available at runtime
test/cases/compile_errors/non_constant_expression_in_array_size.zig+1-1
......@@ -14,4 +14,4 @@ export fn entry() usize {
1414//
1515// :6:12: error: unable to resolve comptime value
1616// :2:12: note: called at comptime from here
17// :1:13: note: types must be comptime-known
17// :2:8: note: struct field types must be comptime-known
test/cases/compile_errors/noreturn_struct_field.zig deleted-10
......@@ -1,10 +0,0 @@
1const S = struct {
2 s: noreturn,
3};
4comptime {
5 _ = @typeInfo(S);
6}
7
8// error
9//
10// :2:8: error: struct fields cannot be 'noreturn'
test/cases/compile_errors/old_fn_ptr_in_extern_context.zig-6
......@@ -4,15 +4,9 @@ const S = extern struct {
44comptime {
55 _ = @sizeOf(S) == 1;
66}
7comptime {
8 _ = [*c][4]fn () callconv(.c) void;
9}
107
118// error
129//
1310// :2:8: error: extern structs cannot contain fields of type 'fn () callconv(.c) void'
1411// :2:8: note: type has no guaranteed in-memory representation
1512// :2:8: note: use '*const ' to make a function pointer type
16// :8:13: error: C pointers cannot point to non-C-ABI-compatible type '[4]fn () callconv(.c) void'
17// :8:13: note: type has no guaranteed in-memory representation
18// :8:13: note: use '*const ' to make a function pointer type
test/cases/compile_errors/overflow_in_enum_value_allocation.zig+1-1
......@@ -9,4 +9,4 @@ pub export fn entry() void {
99
1010// error
1111//
12// :3:5: error: enumeration value '256' too large for type 'u8'
12// :3:5: error: enum tag value '256' too large for type 'u8'
test/cases/compile_errors/packed_struct_backing_int_wrong.zig+6-2
......@@ -44,8 +44,12 @@ export fn entry7() void {
4444
4545// error
4646//
47// :2:31: error: backing integer type 'u32' has bit size 32 but the struct fields have a total bit size of 29
48// :9:31: error: backing integer type 'i31' has bit size 31 but the struct fields have a total bit size of 32
47// :2:24: error: backing integer bit width does not match total bit width of fields
48// :2:31: note: backing integer 'u32' has bit width '32'
49// :2:24: note: struct fields have total bit width '29'
50// :9:24: error: backing integer bit width does not match total bit width of fields
51// :9:31: note: backing integer 'i31' has bit width '31'
52// :9:24: note: struct fields have total bit width '32'
4953// :17:31: error: expected backing integer type, found 'void'
5054// :23:31: error: expected backing integer type, found 'void'
5155// :27:31: error: expected backing integer type, found 'noreturn'
test/cases/compile_errors/packed_struct_uses_own_size.zig created+10
......@@ -0,0 +1,10 @@
1const S = packed struct {
2 x: @Int(.unsigned, @sizeOf(S)),
3};
4comptime {
5 _ = @as(S, undefined);
6}
7
8// error
9//
10// :2:32: error: type 'tmp.S' depends on itself for size query here
test/cases/compile_errors/packed_struct_uses_own_typeinfo.zig created+13
......@@ -0,0 +1,13 @@
1const S = packed struct(u16) {
2 a: bool,
3 b: bool,
4 _padding: @Int(.unsigned, 17 - @typeInfo(S).Struct.fields.len) = 0,
5};
6
7comptime {
8 _ = @as(S, .{ .a = true, .b = true });
9}
10
11// error
12//
13// :4:36: error: type 'tmp.S' depends on itself for type information query here
test/cases/compile_errors/packed_struct_with_fields_of_not_allowed_types.zig+23-12
......@@ -76,30 +76,41 @@ export fn entry14() void {
7676 x: E,
7777 });
7878}
79export fn entry15() void {
80 _ = @sizeOf(packed struct {
81 x: *const u32,
82 });
83}
7984
8085// error
8186//
8287// :3:12: error: packed structs cannot contain fields of type 'anyerror'
83// :3:12: note: type has no guaranteed in-memory representation
88// :3:12: note: type does not have a bit-packed representation
8489// :8:12: error: packed structs cannot contain fields of type '[2]u24'
85// :8:12: note: type has no guaranteed in-memory representation
90// :8:12: note: type does not have a bit-packed representation
8691// :13:20: error: packed structs cannot contain fields of type 'anyerror!u32'
87// :13:20: note: type has no guaranteed in-memory representation
92// :13:20: note: type does not have a bit-packed representation
8893// :18:12: error: packed structs cannot contain fields of type 'tmp.S'
89// :18:12: note: only packed structs layout are allowed in packed types
94// :18:12: note: non-packed structs do not have a bit-packed representation
9095// :56:11: note: struct declared here
9196// :23:12: error: packed structs cannot contain fields of type 'tmp.U'
92// :23:12: note: only packed unions layout are allowed in packed types
97// :23:12: note: non-packed unions do not have a bit-packed representation
9398// :59:18: note: union declared here
9499// :28:12: error: packed structs cannot contain fields of type '?anyerror'
95// :28:12: note: type has no guaranteed in-memory representation
100// :28:12: note: type does not have a bit-packed representation
96101// :38:12: error: packed structs cannot contain fields of type 'fn () void'
97// :38:12: note: type has no guaranteed in-memory representation
98// :38:12: note: use '*const ' to make a function pointer type
102// :38:12: note: type does not have a bit-packed representation
103// :43:12: error: packed structs cannot contain fields of type '*const fn () void'
104// :43:12: note: pointers cannot be directly bitpacked
105// :43:12: note: consider using 'usize' and '@intFromPtr'
99106// :65:31: error: packed structs cannot contain fields of type '[]u8'
100// :65:31: note: slices have no guaranteed in-memory representation
107// :65:31: note: slices do not have a bit-packed representation
101108// :70:12: error: packed structs cannot contain fields of type '*type'
102// :70:12: note: comptime-only pointer has no guaranteed in-memory representation
103// :70:12: note: types are not available at runtime
109// :70:12: note: pointers cannot be directly bitpacked
110// :70:12: note: consider using 'usize' and '@intFromPtr'
104111// :76:12: error: packed structs cannot contain fields of type 'tmp.entry14.E'
105// :74:15: note: enum declared here
112// :74:15: note: integer tag type of enum is inferred
113// :74:15: note: consider explicitly specifying the integer tag type
114// :81:12: error: packed structs cannot contain fields of type '*const u32'
115// :81:12: note: pointers cannot be directly bitpacked
116// :81:12: note: consider using 'usize' and '@intFromPtr'
test/cases/compile_errors/packed_union_fields_mismatch.zig+6-4
......@@ -1,12 +1,14 @@
11export fn entry1() void {
2 _ = packed union {
2 const U = packed union {
33 a: u1,
44 b: u2,
55 };
6 _ = @as(U, undefined);
67}
78
89// error
910//
10// :2:16: error: packed union has fields with mismatching bit sizes
11// :3:12: note: 1 bits here
12// :4:12: note: 2 bits here
11// :4:12: error: field bit width does not match earlier field
12// :4:12: note: field type 'u2' has bit width '2'
13// :3:12: note: other field type 'u1' has bit width '1'
14// :4:12: note: all fields in a packed union must have the same bit width
test/cases/compile_errors/packed_union_given_enum_tag_type.zig deleted-18
......@@ -1,18 +0,0 @@
1const Letter = enum {
2 A,
3 B,
4 C,
5};
6const Payload = packed union(Letter) {
7 A: i32,
8 B: f64,
9 C: bool,
10};
11export fn entry() void {
12 const a: Payload = .{ .A = 1234 };
13 _ = a;
14}
15
16// error
17//
18// :6:30: error: packed union does not support enum tag type
test/cases/compile_errors/packed_union_with_automatic_layout_field.zig deleted-18
......@@ -1,18 +0,0 @@
1const Foo = struct {
2 a: u32,
3 b: f32,
4};
5const Payload = packed union {
6 A: Foo,
7 B: bool,
8};
9export fn entry() void {
10 const a: Payload = .{ .B = true };
11 _ = a;
12}
13
14// error
15//
16// :6:8: error: packed unions cannot contain fields of type 'tmp.Foo'
17// :6:8: note: only packed structs layout are allowed in packed types
18// :1:13: note: struct declared here
test/cases/compile_errors/packed_union_with_fields_of_not_allowed_types.zig created+21
......@@ -0,0 +1,21 @@
1const S = struct { a: u32 };
2export fn entry0() void {
3 _ = @sizeOf(packed union {
4 foo: S,
5 bar: bool,
6 });
7}
8export fn entry1() void {
9 _ = @sizeOf(packed union {
10 x: *const u32,
11 });
12}
13
14// error
15//
16// :4:14: error: packed unions cannot contain fields of type 'tmp.S'
17// :4:14: note: non-packed structs do not have a bit-packed representation
18// :1:11: note: struct declared here
19// :10:12: error: packed unions cannot contain fields of type '*const u32'
20// :10:12: note: pointers cannot be directly bitpacked
21// :10:12: note: consider using 'usize' and '@intFromPtr'
test/cases/compile_errors/pointer_in_bitpack.zig created+22
......@@ -0,0 +1,22 @@
1const S = packed struct {
2 ptr: *u32,
3};
4export fn foo() void {
5 _ = @as(S, undefined);
6}
7
8const U = packed union {
9 ptr: *u32,
10};
11export fn bar() void {
12 _ = @as(U, undefined);
13}
14
15// error
16//
17// :2:10: error: packed structs cannot contain fields of type '*u32'
18// :2:10: note: pointers cannot be directly bitpacked
19// :2:10: note: consider using 'usize' and '@intFromPtr'
20// :9:10: error: packed unions cannot contain fields of type '*u32'
21// :9:10: note: pointers cannot be directly bitpacked
22// :9:10: note: consider using 'usize' and '@intFromPtr'
test/cases/compile_errors/reify_enum_with_duplicate_field.zig+4-3
......@@ -1,8 +1,9 @@
11export fn entry() void {
2 _ = @Enum(u32, .nonexhaustive, &.{ "A", "A" }, &.{ 0, 1 });
2 const E = @Enum(u32, .nonexhaustive, &.{ "A", "A" }, &.{ 0, 1 });
3 _ = @as(E, undefined);
34}
45
56// error
67//
7// :2:36: error: duplicate enum field 'A'
8// :2:36: note: other field here
8// :2:42: error: duplicate enum field 'A' at index '1'
9// :2:42: note: previous field at index '0'
test/cases/compile_errors/reify_enum_with_duplicate_tag_value.zig+4-3
......@@ -1,8 +1,9 @@
11export fn entry() void {
2 _ = @Enum(u32, .nonexhaustive, &.{ "A", "B" }, &.{ 10, 10 });
2 const E = @Enum(u32, .nonexhaustive, &.{ "a", "b" }, &.{ 10, 10 });
3 _ = E.a;
34}
45
56// error
67//
7// :2:52: error: enum tag value 10 already taken
8// :2:52: note: other enum tag value here
8// :2:58: error: enum tag value '10' for field 'b' already taken
9// :2:58: note: previous occurrence in field 'a'
test/cases/compile_errors/reify_type_for_exhaustive_enum_with_non-integer_tag_type.zig+1-1
......@@ -5,4 +5,4 @@ export fn entry() void {
55
66// error
77//
8// :1:19: error: tag type must be an integer type
8// :1:19: error: expected integer tag type, found 'bool'
test/cases/compile_errors/reify_type_for_tagged_packed_union.zig deleted-11
......@@ -1,11 +0,0 @@
1const Tag = @Enum(u2, .exhaustive, &.{ "signed", "unsigned" }, &.{ 0, 1 });
2const Packed = @Union(.@"packed", Tag, &.{ "signed", "unsigned" }, &.{ i32, u32 }, &@splat(.{}));
3
4export fn entry() void {
5 const tagged: Packed = .{ .signed = -1 };
6 _ = tagged;
7}
8
9// error
10//
11// :2:35: error: packed union does not support enum tag type
test/cases/compile_errors/reify_type_for_tagged_union_with_extra_enum_field.zig+2-3
......@@ -7,6 +7,5 @@ export fn entry() void {
77
88// error
99//
10// :2:35: error: 1 enum fields missing in union
11// :1:13: note: field 'arst' missing, declared here
12// :1:13: note: enum declared here
10// :2:16: error: enum field 'arst' missing from union
11// :1:36: note: enum field here
test/cases/compile_errors/reify_type_for_tagged_union_with_no_union_fields.zig+2-4
......@@ -7,7 +7,5 @@ export fn entry() void {
77
88// error
99//
10// :2:35: error: 2 enum fields missing in union
11// :1:13: note: field 'signed' missing, declared here
12// :1:13: note: field 'unsigned' missing, declared here
13// :1:13: note: enum declared here
10// :2:16: error: enum field 'signed' missing from union
11// :1:36: note: enum field here
test/cases/compile_errors/reify_type_for_union_with_opaque_field.zig+5-3
......@@ -1,9 +1,11 @@
1const Untagged = @Union(.auto, null, &.{"foo"}, &.{opaque {}}, &.{.{}});
1const Opaque = opaque {};
2const Untagged = @Union(.auto, null, &.{"foo"}, &.{Opaque}, &.{.{}});
23export fn entry() usize {
34 return @sizeOf(Untagged);
45}
56
67// error
78//
8// :1:49: error: opaque types have unknown size and therefore cannot be directly embedded in unions
9// :1:52: note: opaque declared here
9// :2:49: error: cannot directly embed opaque type 'tmp.Opaque' in union
10// :2:49: note: opaque types have unknown size
11// :1:16: note: opaque declared here
test/cases/compile_errors/reify_type_with_invalid_field_alignment.zig+6-2
......@@ -2,7 +2,11 @@ comptime {
22 _ = @Union(.auto, null, &.{"foo"}, &.{usize}, &.{.{ .@"align" = 3 }});
33}
44comptime {
5 _ = @Struct(.auto, null, &.{"a"}, &.{u32}, &.{.{ .@"comptime" = true, .@"align" = 5 }});
5 _ = @Struct(.auto, null, &.{"a"}, &.{u32}, &.{.{
6 .@"comptime" = true,
7 .@"align" = 5,
8 .default_value_ptr = &@as(u32, 0),
9 }});
610}
711comptime {
812 _ = @Pointer(.many, .{ .@"align" = 7 }, u8, null);
......@@ -12,4 +16,4 @@ comptime {
1216//
1317// :2:51: error: alignment value '3' is not a power of two
1418// :5:48: error: alignment value '5' is not a power of two
15// :8:26: error: alignment value '7' is not a power of two
19// :12:26: error: alignment value '7' is not a power of two
test/cases/compile_errors/resolve_inferred_error_set_of_generic_fn.zig+1-2
......@@ -12,5 +12,4 @@ export fn entry() void {
1212
1313// error
1414//
15// :10:15: error: unable to resolve inferred error set of generic function
16// :1:1: note: generic function declared here
15// :1:1: error: cannot resolve inferred error set of generic function type 'fn (anytype) @typeInfo(@typeInfo(@TypeOf(tmp.foo)).@"fn".return_type.?).error_union.error_set!void'
test/cases/compile_errors/runtime_@ptrFromInt_to_comptime_only_type.zig+2-3
......@@ -10,6 +10,5 @@ pub export fn callbackFin(id: c_int, arg: ?*anyopaque) void {
1010
1111// error
1212//
13// :5:54: error: pointer to comptime-only type '?*tmp.GuSettings' must be comptime-known, but operand is runtime-known
14// :2:10: note: struct requires comptime because of this field
15// :2:10: note: use '*const fn (c_int) callconv(.c) void' for a function pointer type
13// :6:19: error: cannot load comptime-only type '?fn (c_int) callconv(.c) void'
14// :6:20: note: pointer of type '*?fn (c_int) callconv(.c) void' is runtime-known
test/cases/compile_errors/runtime_index_into_comptime_only_many_ptr.zig+3-3
......@@ -1,10 +1,10 @@
11var rt: usize = 0;
22export fn foo() void {
33 const x: [*]const type = &.{ u8, u16 };
4 _ = &x[rt];
4 _ = x[rt];
55}
66
77// error
88//
9// :4:12: error: values of type '[*]const type' must be comptime-known, but index value is runtime-known
10// :4:11: note: types are not available at runtime
9// :4:11: error: values of type 'type' must be comptime-known, but index value is runtime-known
10// :4:10: note: types are not available at runtime
test/cases/compile_errors/runtime_index_into_comptime_type_slice.zig+1-2
......@@ -12,7 +12,6 @@ export fn entry() void {
1212
1313// error
1414//
15// :9:54: error: values of type '[]const builtin.Type.StructField' must be comptime-known, but index value is runtime-known
15// :9:54: error: values of type 'builtin.Type.StructField' must be comptime-known, but index value is runtime-known
1616// : note: struct requires comptime because of this field
1717// : note: types are not available at runtime
18// : struct requires comptime because of this field
test/cases/compile_errors/runtime_indexing_comptime_array.zig+3-3
......@@ -24,9 +24,9 @@ pub export fn entry3() void {
2424}
2525// error
2626//
27// :7:10: error: values of type '[2]fn () void' must be comptime-known, but index value is runtime-known
27// :7:10: error: values of type 'fn () void' must be comptime-known, but index value is runtime-known
2828// :7:10: note: use '*const fn () void' for a function pointer type
29// :15:18: error: values of type '[2]fn () void' must be comptime-known, but index value is runtime-known
29// :15:18: error: values of type 'fn () void' must be comptime-known, but index value is runtime-known
3030// :15:17: note: use '*const fn () void' for a function pointer type
31// :22:19: error: values of type '[2]fn () void' must be comptime-known, but index value is runtime-known
31// :22:19: error: values of type 'fn () void' must be comptime-known, but index value is runtime-known
3232// :22:18: note: use '*const fn () void' for a function pointer type
test/cases/compile_errors/runtime_operation_in_comptime_scope.zig+4-4
......@@ -25,13 +25,13 @@ var rt: u32 = undefined;
2525//
2626// :19:8: error: unable to evaluate comptime expression
2727// :19:5: note: operation is runtime due to this operand
28// :6:8: note: called at comptime from here
29// :5:1: note: 'comptime' keyword forces comptime evaluation
30// :19:8: error: unable to evaluate comptime expression
31// :19:5: note: operation is runtime due to this operand
2832// :14:8: note: called at comptime from here
2933// :10:12: note: called at comptime from here
3034// :10:12: note: call to function with comptime-only return type 'type' is evaluated at comptime
3135// :13:10: note: return type declared here
3236// :10:12: note: types are not available at runtime
3337// :2:8: note: called inline here
34// :19:8: error: unable to evaluate comptime expression
35// :19:5: note: operation is runtime due to this operand
36// :6:8: note: called at comptime from here
37// :5:1: note: 'comptime' keyword forces comptime evaluation
test/cases/compile_errors/self_referential_struct_requires_comptime.zig-1
......@@ -12,4 +12,3 @@ pub export fn entry() void {
1212// :6:12: error: variable of type 'tmp.S' must be const or comptime
1313// :2:8: note: struct requires comptime because of this field
1414// :2:8: note: use '*const fn () void' for a function pointer type
15// :3:8: note: struct requires comptime because of this field
test/cases/compile_errors/self_referential_union_requires_comptime.zig-1
......@@ -12,4 +12,3 @@ pub export fn entry() void {
1212// :6:12: error: variable of type 'tmp.U' must be const or comptime
1313// :2:8: note: union requires comptime because of this field
1414// :2:8: note: use '*const fn () void' for a function pointer type
15// :3:8: note: union requires comptime because of this field
test/cases/compile_errors/simple_struct_loop.zig created+16
......@@ -0,0 +1,16 @@
1const A = struct {
2 b: B,
3};
4const B = struct {
5 a: A,
6};
7comptime {
8 _ = @as(A, undefined);
9}
10
11// error
12//
13// error: dependency loop with length 2
14// :2:8: note: type 'tmp.A' depends on type 'tmp.B' for field declared here
15// :5:8: note: type 'tmp.B' depends on type 'tmp.A' for field declared here
16// note: eliminate any one of these dependencies to break the loop
test/cases/compile_errors/sizeOf_bad_type.zig+26-2
......@@ -1,7 +1,31 @@
1export fn entry() usize {
1export fn entry0() usize {
22 return @sizeOf(@TypeOf(null));
33}
4export fn entry1() usize {
5 return @sizeOf(comptime_int);
6}
7export fn entry2() usize {
8 return @sizeOf(noreturn);
9}
10const S3 = struct { a: u32, b: comptime_int };
11export fn entry3() usize {
12 return @sizeOf(S3);
13}
14const S4 = struct { a: u32, b: noreturn };
15export fn entry4() usize {
16 return @sizeOf(S4);
17}
18export fn entry5() usize {
19 return @sizeOf([1]fn () void);
20}
421
522// error
623//
7// :2:20: error: no size available for type '@TypeOf(null)'
24// :2:20: error: no size available for comptime-only type '@TypeOf(null)'
25// :5:20: error: no size available for comptime-only type 'comptime_int'
26// :8:20: error: no size available for uninstantiable type 'noreturn'
27// :12:20: error: no size available for comptime-only type 'tmp.S3'
28// :10:12: note: struct declared here
29// :16:20: error: no size available for uninstantiable type 'tmp.S4'
30// :14:12: note: struct declared here
31// :19:20: error: no size available for comptime-only type '[1]fn () void'
test/cases/compile_errors/sizeof_alignof_empty_union.zig created+75
......@@ -0,0 +1,75 @@
1const EnumInferred = enum {};
2const EnumExplicit = enum(u8) {};
3const EnumNonexhaustive = enum(u8) { _ };
4
5const U0 = union {};
6const U1 = union(enum) {};
7const U2 = union(enum(u8)) {};
8const U3 = union(EnumInferred) {};
9const U4 = union(EnumExplicit) {};
10const U5 = union(EnumNonexhaustive) {};
11
12export fn size0() void {
13 _ = @sizeOf(U0);
14}
15export fn size1() void {
16 _ = @sizeOf(U1);
17}
18export fn size2() void {
19 _ = @sizeOf(U2);
20}
21export fn size3() void {
22 _ = @sizeOf(U3);
23}
24export fn size4() void {
25 _ = @sizeOf(U4);
26}
27export fn size5() void {
28 _ = @sizeOf(U5);
29}
30
31export fn align0() void {
32 _ = @alignOf(U0);
33}
34export fn align1() void {
35 _ = @alignOf(U1);
36}
37export fn align2() void {
38 _ = @alignOf(U2);
39}
40export fn align3() void {
41 _ = @alignOf(U3);
42}
43export fn align4() void {
44 _ = @alignOf(U4);
45}
46export fn align5() void {
47 _ = @alignOf(U5);
48}
49
50// error
51//
52// :13:17: error: no size available for uninstantiable type 'tmp.U0'
53// :5:12: note: union declared here
54// :16:17: error: no size available for uninstantiable type 'tmp.U1'
55// :6:12: note: union declared here
56// :19:17: error: no size available for uninstantiable type 'tmp.U2'
57// :7:12: note: union declared here
58// :22:17: error: no size available for uninstantiable type 'tmp.U3'
59// :8:12: note: union declared here
60// :25:17: error: no size available for uninstantiable type 'tmp.U4'
61// :9:12: note: union declared here
62// :28:17: error: no size available for uninstantiable type 'tmp.U5'
63// :10:12: note: union declared here
64// :32:18: error: no align available for uninstantiable type 'tmp.U0'
65// :5:12: note: union declared here
66// :35:18: error: no align available for uninstantiable type 'tmp.U1'
67// :6:12: note: union declared here
68// :38:18: error: no align available for uninstantiable type 'tmp.U2'
69// :7:12: note: union declared here
70// :41:18: error: no align available for uninstantiable type 'tmp.U3'
71// :8:12: note: union declared here
72// :44:18: error: no align available for uninstantiable type 'tmp.U4'
73// :9:12: note: union declared here
74// :47:18: error: no align available for uninstantiable type 'tmp.U5'
75// :10:12: note: union declared here
test/cases/compile_errors/slice_used_as_extern_fn_param.zig+1-1
......@@ -1,6 +1,6 @@
11extern fn Text(str: []const u8, num: i32) callconv(.c) void;
22export fn entry() void {
3 _ = Text;
3 Text(undefined, undefined);
44}
55
66// error
test/cases/compile_errors/specify_enum_tag_type_that_is_too_small.zig+9-9
......@@ -1,9 +1,9 @@
11const Small = enum(u2) {
2 One,
3 Two,
4 Three,
5 Four,
6 Five,
2 one,
3 two,
4 three,
5 four,
6 five,
77};
88
99const SmallUnion = union(enum(u2)) {
......@@ -14,13 +14,13 @@ const SmallUnion = union(enum(u2)) {
1414};
1515
1616comptime {
17 _ = Small;
17 _ = Small.one;
1818}
1919comptime {
20 _ = SmallUnion;
20 _ = SmallUnion.one;
2121}
2222
2323// error
2424//
25// :6:5: error: enumeration value '4' too large for type 'u2'
26// :13:5: error: enumeration value '4' too large for type 'u2'
25// :6:5: error: enum tag value '4' too large for type 'u2'
26// :13:5: error: enum tag value '4' too large for type 'u2'
test/cases/compile_errors/store_comptime_only_type_to_runtime_pointer.zig+2-9
......@@ -21,22 +21,15 @@ export fn e() void {
2121 p.* = undefined;
2222}
2323
24export fn f() void {
25 const p: **comptime_int = @ptrFromInt(16); // double pointer ('*comptime_int' is comptime-only)
26 p.* = undefined;
27}
28
2924// error
3025//
3126// :3:9: error: cannot store comptime-only type 'fn () void' at runtime
3227// :3:6: note: operation is runtime due to this pointer
3328// :7:11: error: expected type 'anyopaque', found '@TypeOf(undefined)'
34// :7:11: note: cannot coerce to 'anyopaque'
29// :7:11: note: cannot coerce to uninstantiable type 'anyopaque'
3530// :11:12: error: cannot load opaque type 'anyopaque'
3631// :16:11: error: expected type 'tmp.Opaque', found '@TypeOf(undefined)'
37// :16:11: note: cannot coerce to 'tmp.Opaque'
32// :16:11: note: cannot coerce to uninstantiable type 'tmp.Opaque'
3833// :14:16: note: opaque declared here
3934// :21:9: error: cannot store comptime-only type 'comptime_int' at runtime
4035// :21:6: note: operation is runtime due to this pointer
41// :26:9: error: cannot store comptime-only type '*comptime_int' at runtime
42// :26:6: note: operation is runtime due to this pointer
test/cases/compile_errors/struct_depends_on_itself_via_non_initial_field.zig+2-2
......@@ -4,9 +4,9 @@ const A = struct {
44};
55
66comptime {
7 _ = A;
7 _ = @as(A, undefined);
88}
99
1010// error
1111//
12// :1:11: error: struct 'tmp.A' depends on itself
12// :3:21: error: type 'tmp.A' depends on itself for size query here
test/cases/compile_errors/struct_depends_on_itself_via_optional_field.zig+4-1
......@@ -12,4 +12,7 @@ export fn entry() void {
1212
1313// error
1414//
15// :1:17: error: struct 'tmp.LhsExpr' depends on itself
15// error: dependency loop with length 2
16// :2:14: note: type 'tmp.LhsExpr' depends on type 'tmp.AstObject' for field declared here
17// :5:14: note: type 'tmp.AstObject' depends on type 'tmp.LhsExpr' for field declared here
18// note: eliminate any one of these dependencies to break the loop
test/cases/compile_errors/struct_depends_on_pointer_alignment.zig deleted-11
......@@ -1,11 +0,0 @@
1const S = struct {
2 next: ?*align(1) S align(128),
3};
4
5export fn entry() usize {
6 return @alignOf(S);
7}
8
9// error
10//
11// :1:11: error: struct layout depends on being pointer aligned
test/cases/compile_errors/struct_field_queries_hasfield_of_itself.zig created+14
......@@ -0,0 +1,14 @@
1const Foo = packed struct {
2 bar: (T: {
3 _ = @hasField(Foo, "bar");
4 break :T void;
5 }),
6};
7
8comptime {
9 _ = @as(Foo, undefined);
10}
11
12// error
13//
14// :3:23: error: type 'tmp.Foo' depends on itself for field query here
test/cases/compile_errors/struct_uses_reified_type_which_queries_struct_alignment.zig created+13
......@@ -0,0 +1,13 @@
1const A = struct { b: *B };
2const B = @Struct(.auto, null, &.{"x"}, &.{A}, &.{.{ .@"align" = @alignOf(A) }});
3comptime {
4 _ = @as(A, undefined);
5 _ = @as(B, undefined);
6}
7
8// error
9//
10// error: dependency loop with length 2
11// :1:24: note: type 'tmp.A' uses value of declaration 'tmp.B' here
12// :2:75: note: value of declaration 'tmp.B' depends on type 'tmp.A' for alignment query here
13// note: eliminate any one of these dependencies to break the loop
test/cases/compile_errors/struct_uses_sizeof_self_as_array_len.zig created+10
......@@ -0,0 +1,10 @@
1const S = struct {
2 a: *[@sizeOf(S)]u8,
3};
4comptime {
5 _ = @as(S, undefined);
6}
7
8// error
9//
10// :2:18: error: type 'tmp.S' depends on itself for size query here
test/cases/compile_errors/too_big_packed_struct.zig+1-1
......@@ -8,4 +8,4 @@ pub export fn entry() void {
88
99// error
1010//
11// :2:22: error: size of packed struct '131070' exceeds maximum bit width of 65535
11// :2:22: error: packed struct bit width '131070' exceeds maximum bit width of 65535
test/cases/compile_errors/top_level_decl_dependency_loop.zig+6-1
......@@ -7,4 +7,9 @@ export fn entry() void {
77
88// error
99//
10// :1:1: error: dependency loop detected
10// error: dependency loop with length 4
11// :1:23: note: value of declaration 'tmp.a' uses type of declaration 'tmp.a' here
12// :1:18: note: type of declaration 'tmp.a' uses value of declaration 'tmp.b' here
13// :2:23: note: value of declaration 'tmp.b' uses type of declaration 'tmp.b' here
14// :2:18: note: type of declaration 'tmp.b' uses value of declaration 'tmp.a' here
15// note: eliminate any one of these dependencies to break the loop
test/cases/compile_errors/unable_to_evaluate_comptime_expr.zig-19
......@@ -16,22 +16,6 @@ pub export fn entry2() void {
1616 _ = b;
1717}
1818
19const Int = @typeInfo(bar).@"struct".backing_integer.?;
20
21const foo = enum(Int) {
22 c = @bitCast(bar{
23 .name = "test",
24 }),
25};
26
27const bar = packed struct {
28 name: [*:0]const u8,
29};
30
31pub export fn entry3() void {
32 _ = @field(foo, "c");
33}
34
3519// error
3620//
3721// :7:13: error: unable to evaluate comptime expression
......@@ -40,6 +24,3 @@ pub export fn entry3() void {
4024// :13:13: error: unable to evaluate comptime expression
4125// :13:16: note: operation is runtime due to this operand
4226// :13:13: note: initializer of container-level variable must be comptime-known
43// :22:9: error: unable to evaluate comptime expression
44// :22:21: note: operation is runtime due to this operand
45// :21:13: note: enum field values must be comptime-known
test/cases/compile_errors/undef_arith_is_illegal.zig+1508-1508
......@@ -192,50 +192,30 @@ const std = @import("std");
192192// :65:17: error: use of undefined value here causes illegal behavior
193193// :65:17: error: use of undefined value here causes illegal behavior
194194// :65:17: error: use of undefined value here causes illegal behavior
195// :65:17: note: when computing vector element at index '0'
196195// :65:17: error: use of undefined value here causes illegal behavior
197// :65:17: note: when computing vector element at index '0'
198196// :65:17: error: use of undefined value here causes illegal behavior
199// :65:17: note: when computing vector element at index '0'
200197// :65:17: error: use of undefined value here causes illegal behavior
201// :65:17: note: when computing vector element at index '0'
202198// :65:17: error: use of undefined value here causes illegal behavior
203// :65:17: note: when computing vector element at index '1'
204199// :65:17: error: use of undefined value here causes illegal behavior
205// :65:17: note: when computing vector element at index '1'
206200// :65:17: error: use of undefined value here causes illegal behavior
207// :65:17: note: when computing vector element at index '0'
208201// :65:17: error: use of undefined value here causes illegal behavior
209// :65:17: note: when computing vector element at index '0'
210202// :65:17: error: use of undefined value here causes illegal behavior
211// :65:17: note: when computing vector element at index '0'
212203// :65:17: error: use of undefined value here causes illegal behavior
213// :65:17: note: when computing vector element at index '0'
214204// :65:17: error: use of undefined value here causes illegal behavior
215205// :65:17: error: use of undefined value here causes illegal behavior
216206// :65:17: error: use of undefined value here causes illegal behavior
217// :65:17: note: when computing vector element at index '0'
218207// :65:17: error: use of undefined value here causes illegal behavior
219// :65:17: note: when computing vector element at index '0'
220208// :65:17: error: use of undefined value here causes illegal behavior
221// :65:17: note: when computing vector element at index '0'
222209// :65:17: error: use of undefined value here causes illegal behavior
223// :65:17: note: when computing vector element at index '0'
224210// :65:17: error: use of undefined value here causes illegal behavior
225// :65:17: note: when computing vector element at index '1'
226211// :65:17: error: use of undefined value here causes illegal behavior
227// :65:17: note: when computing vector element at index '1'
228212// :65:17: error: use of undefined value here causes illegal behavior
229// :65:17: note: when computing vector element at index '0'
230213// :65:17: error: use of undefined value here causes illegal behavior
231// :65:17: note: when computing vector element at index '0'
232214// :65:17: error: use of undefined value here causes illegal behavior
233215// :65:17: note: when computing vector element at index '0'
234216// :65:17: error: use of undefined value here causes illegal behavior
235217// :65:17: note: when computing vector element at index '0'
236218// :65:17: error: use of undefined value here causes illegal behavior
237// :65:17: error: use of undefined value here causes illegal behavior
238// :65:17: error: use of undefined value here causes illegal behavior
239219// :65:17: note: when computing vector element at index '0'
240220// :65:17: error: use of undefined value here causes illegal behavior
241221// :65:17: note: when computing vector element at index '0'
......@@ -244,10 +224,6 @@ const std = @import("std");
244224// :65:17: error: use of undefined value here causes illegal behavior
245225// :65:17: note: when computing vector element at index '0'
246226// :65:17: error: use of undefined value here causes illegal behavior
247// :65:17: note: when computing vector element at index '1'
248// :65:17: error: use of undefined value here causes illegal behavior
249// :65:17: note: when computing vector element at index '1'
250// :65:17: error: use of undefined value here causes illegal behavior
251227// :65:17: note: when computing vector element at index '0'
252228// :65:17: error: use of undefined value here causes illegal behavior
253229// :65:17: note: when computing vector element at index '0'
......@@ -256,7 +232,9 @@ const std = @import("std");
256232// :65:17: error: use of undefined value here causes illegal behavior
257233// :65:17: note: when computing vector element at index '0'
258234// :65:17: error: use of undefined value here causes illegal behavior
235// :65:17: note: when computing vector element at index '0'
259236// :65:17: error: use of undefined value here causes illegal behavior
237// :65:17: note: when computing vector element at index '0'
260238// :65:17: error: use of undefined value here causes illegal behavior
261239// :65:17: note: when computing vector element at index '0'
262240// :65:17: error: use of undefined value here causes illegal behavior
......@@ -266,9 +244,9 @@ const std = @import("std");
266244// :65:17: error: use of undefined value here causes illegal behavior
267245// :65:17: note: when computing vector element at index '0'
268246// :65:17: error: use of undefined value here causes illegal behavior
269// :65:17: note: when computing vector element at index '1'
247// :65:17: note: when computing vector element at index '0'
270248// :65:17: error: use of undefined value here causes illegal behavior
271// :65:17: note: when computing vector element at index '1'
249// :65:17: note: when computing vector element at index '0'
272250// :65:17: error: use of undefined value here causes illegal behavior
273251// :65:17: note: when computing vector element at index '0'
274252// :65:17: error: use of undefined value here causes illegal behavior
......@@ -278,7 +256,9 @@ const std = @import("std");
278256// :65:17: error: use of undefined value here causes illegal behavior
279257// :65:17: note: when computing vector element at index '0'
280258// :65:17: error: use of undefined value here causes illegal behavior
259// :65:17: note: when computing vector element at index '0'
281260// :65:17: error: use of undefined value here causes illegal behavior
261// :65:17: note: when computing vector element at index '0'
282262// :65:17: error: use of undefined value here causes illegal behavior
283263// :65:17: note: when computing vector element at index '0'
284264// :65:17: error: use of undefined value here causes illegal behavior
......@@ -288,9 +268,9 @@ const std = @import("std");
288268// :65:17: error: use of undefined value here causes illegal behavior
289269// :65:17: note: when computing vector element at index '0'
290270// :65:17: error: use of undefined value here causes illegal behavior
291// :65:17: note: when computing vector element at index '1'
271// :65:17: note: when computing vector element at index '0'
292272// :65:17: error: use of undefined value here causes illegal behavior
293// :65:17: note: when computing vector element at index '1'
273// :65:17: note: when computing vector element at index '0'
294274// :65:17: error: use of undefined value here causes illegal behavior
295275// :65:17: note: when computing vector element at index '0'
296276// :65:17: error: use of undefined value here causes illegal behavior
......@@ -300,7 +280,9 @@ const std = @import("std");
300280// :65:17: error: use of undefined value here causes illegal behavior
301281// :65:17: note: when computing vector element at index '0'
302282// :65:17: error: use of undefined value here causes illegal behavior
283// :65:17: note: when computing vector element at index '0'
303284// :65:17: error: use of undefined value here causes illegal behavior
285// :65:17: note: when computing vector element at index '0'
304286// :65:17: error: use of undefined value here causes illegal behavior
305287// :65:17: note: when computing vector element at index '0'
306288// :65:17: error: use of undefined value here causes illegal behavior
......@@ -310,9 +292,9 @@ const std = @import("std");
310292// :65:17: error: use of undefined value here causes illegal behavior
311293// :65:17: note: when computing vector element at index '0'
312294// :65:17: error: use of undefined value here causes illegal behavior
313// :65:17: note: when computing vector element at index '1'
295// :65:17: note: when computing vector element at index '0'
314296// :65:17: error: use of undefined value here causes illegal behavior
315// :65:17: note: when computing vector element at index '1'
297// :65:17: note: when computing vector element at index '0'
316298// :65:17: error: use of undefined value here causes illegal behavior
317299// :65:17: note: when computing vector element at index '0'
318300// :65:17: error: use of undefined value here causes illegal behavior
......@@ -322,7 +304,9 @@ const std = @import("std");
322304// :65:17: error: use of undefined value here causes illegal behavior
323305// :65:17: note: when computing vector element at index '0'
324306// :65:17: error: use of undefined value here causes illegal behavior
307// :65:17: note: when computing vector element at index '0'
325308// :65:17: error: use of undefined value here causes illegal behavior
309// :65:17: note: when computing vector element at index '0'
326310// :65:17: error: use of undefined value here causes illegal behavior
327311// :65:17: note: when computing vector element at index '0'
328312// :65:17: error: use of undefined value here causes illegal behavior
......@@ -332,9 +316,9 @@ const std = @import("std");
332316// :65:17: error: use of undefined value here causes illegal behavior
333317// :65:17: note: when computing vector element at index '0'
334318// :65:17: error: use of undefined value here causes illegal behavior
335// :65:17: note: when computing vector element at index '1'
319// :65:17: note: when computing vector element at index '0'
336320// :65:17: error: use of undefined value here causes illegal behavior
337// :65:17: note: when computing vector element at index '1'
321// :65:17: note: when computing vector element at index '0'
338322// :65:17: error: use of undefined value here causes illegal behavior
339323// :65:17: note: when computing vector element at index '0'
340324// :65:17: error: use of undefined value here causes illegal behavior
......@@ -344,7 +328,9 @@ const std = @import("std");
344328// :65:17: error: use of undefined value here causes illegal behavior
345329// :65:17: note: when computing vector element at index '0'
346330// :65:17: error: use of undefined value here causes illegal behavior
331// :65:17: note: when computing vector element at index '0'
347332// :65:17: error: use of undefined value here causes illegal behavior
333// :65:17: note: when computing vector element at index '0'
348334// :65:17: error: use of undefined value here causes illegal behavior
349335// :65:17: note: when computing vector element at index '0'
350336// :65:17: error: use of undefined value here causes illegal behavior
......@@ -354,9 +340,9 @@ const std = @import("std");
354340// :65:17: error: use of undefined value here causes illegal behavior
355341// :65:17: note: when computing vector element at index '0'
356342// :65:17: error: use of undefined value here causes illegal behavior
357// :65:17: note: when computing vector element at index '1'
343// :65:17: note: when computing vector element at index '0'
358344// :65:17: error: use of undefined value here causes illegal behavior
359// :65:17: note: when computing vector element at index '1'
345// :65:17: note: when computing vector element at index '0'
360346// :65:17: error: use of undefined value here causes illegal behavior
361347// :65:17: note: when computing vector element at index '0'
362348// :65:17: error: use of undefined value here causes illegal behavior
......@@ -366,7 +352,9 @@ const std = @import("std");
366352// :65:17: error: use of undefined value here causes illegal behavior
367353// :65:17: note: when computing vector element at index '0'
368354// :65:17: error: use of undefined value here causes illegal behavior
355// :65:17: note: when computing vector element at index '0'
369356// :65:17: error: use of undefined value here causes illegal behavior
357// :65:17: note: when computing vector element at index '0'
370358// :65:17: error: use of undefined value here causes illegal behavior
371359// :65:17: note: when computing vector element at index '0'
372360// :65:17: error: use of undefined value here causes illegal behavior
......@@ -376,9 +364,9 @@ const std = @import("std");
376364// :65:17: error: use of undefined value here causes illegal behavior
377365// :65:17: note: when computing vector element at index '0'
378366// :65:17: error: use of undefined value here causes illegal behavior
379// :65:17: note: when computing vector element at index '1'
367// :65:17: note: when computing vector element at index '0'
380368// :65:17: error: use of undefined value here causes illegal behavior
381// :65:17: note: when computing vector element at index '1'
369// :65:17: note: when computing vector element at index '0'
382370// :65:17: error: use of undefined value here causes illegal behavior
383371// :65:17: note: when computing vector element at index '0'
384372// :65:17: error: use of undefined value here causes illegal behavior
......@@ -388,7 +376,9 @@ const std = @import("std");
388376// :65:17: error: use of undefined value here causes illegal behavior
389377// :65:17: note: when computing vector element at index '0'
390378// :65:17: error: use of undefined value here causes illegal behavior
379// :65:17: note: when computing vector element at index '0'
391380// :65:17: error: use of undefined value here causes illegal behavior
381// :65:17: note: when computing vector element at index '0'
392382// :65:17: error: use of undefined value here causes illegal behavior
393383// :65:17: note: when computing vector element at index '0'
394384// :65:17: error: use of undefined value here causes illegal behavior
......@@ -402,35 +392,45 @@ const std = @import("std");
402392// :65:17: error: use of undefined value here causes illegal behavior
403393// :65:17: note: when computing vector element at index '1'
404394// :65:17: error: use of undefined value here causes illegal behavior
405// :65:17: note: when computing vector element at index '0'
395// :65:17: note: when computing vector element at index '1'
406396// :65:17: error: use of undefined value here causes illegal behavior
407// :65:17: note: when computing vector element at index '0'
397// :65:17: note: when computing vector element at index '1'
408398// :65:17: error: use of undefined value here causes illegal behavior
409// :65:17: note: when computing vector element at index '0'
399// :65:17: note: when computing vector element at index '1'
410400// :65:17: error: use of undefined value here causes illegal behavior
411// :65:17: note: when computing vector element at index '0'
401// :65:17: note: when computing vector element at index '1'
412402// :65:17: error: use of undefined value here causes illegal behavior
403// :65:17: note: when computing vector element at index '1'
413404// :65:17: error: use of undefined value here causes illegal behavior
405// :65:17: note: when computing vector element at index '1'
414406// :65:17: error: use of undefined value here causes illegal behavior
415// :65:17: note: when computing vector element at index '0'
407// :65:17: note: when computing vector element at index '1'
416408// :65:17: error: use of undefined value here causes illegal behavior
417// :65:17: note: when computing vector element at index '0'
409// :65:17: note: when computing vector element at index '1'
418410// :65:17: error: use of undefined value here causes illegal behavior
419// :65:17: note: when computing vector element at index '0'
411// :65:17: note: when computing vector element at index '1'
420412// :65:17: error: use of undefined value here causes illegal behavior
421// :65:17: note: when computing vector element at index '0'
413// :65:17: note: when computing vector element at index '1'
422414// :65:17: error: use of undefined value here causes illegal behavior
423415// :65:17: note: when computing vector element at index '1'
424416// :65:17: error: use of undefined value here causes illegal behavior
425417// :65:17: note: when computing vector element at index '1'
426418// :65:17: error: use of undefined value here causes illegal behavior
427// :65:17: note: when computing vector element at index '0'
419// :65:17: note: when computing vector element at index '1'
428420// :65:17: error: use of undefined value here causes illegal behavior
429// :65:17: note: when computing vector element at index '0'
421// :65:17: note: when computing vector element at index '1'
430422// :65:17: error: use of undefined value here causes illegal behavior
431// :65:17: note: when computing vector element at index '0'
423// :65:17: note: when computing vector element at index '1'
432424// :65:17: error: use of undefined value here causes illegal behavior
433// :65:17: note: when computing vector element at index '0'
425// :65:17: note: when computing vector element at index '1'
426// :65:17: error: use of undefined value here causes illegal behavior
427// :65:17: note: when computing vector element at index '1'
428// :65:17: error: use of undefined value here causes illegal behavior
429// :65:17: note: when computing vector element at index '1'
430// :65:17: error: use of undefined value here causes illegal behavior
431// :65:17: note: when computing vector element at index '1'
432// :65:17: error: use of undefined value here causes illegal behavior
433// :65:17: note: when computing vector element at index '1'
434434// :65:21: error: use of undefined value here causes illegal behavior
435435// :65:21: note: when computing vector element at index '0'
436436// :65:21: error: use of undefined value here causes illegal behavior
......@@ -478,50 +478,30 @@ const std = @import("std");
478478// :69:27: error: use of undefined value here causes illegal behavior
479479// :69:27: error: use of undefined value here causes illegal behavior
480480// :69:27: error: use of undefined value here causes illegal behavior
481// :69:27: note: when computing vector element at index '0'
482481// :69:27: error: use of undefined value here causes illegal behavior
483// :69:27: note: when computing vector element at index '0'
484482// :69:27: error: use of undefined value here causes illegal behavior
485// :69:27: note: when computing vector element at index '0'
486483// :69:27: error: use of undefined value here causes illegal behavior
487// :69:27: note: when computing vector element at index '0'
488484// :69:27: error: use of undefined value here causes illegal behavior
489// :69:27: note: when computing vector element at index '1'
490485// :69:27: error: use of undefined value here causes illegal behavior
491// :69:27: note: when computing vector element at index '1'
492486// :69:27: error: use of undefined value here causes illegal behavior
493// :69:27: note: when computing vector element at index '0'
494487// :69:27: error: use of undefined value here causes illegal behavior
495// :69:27: note: when computing vector element at index '0'
496488// :69:27: error: use of undefined value here causes illegal behavior
497// :69:27: note: when computing vector element at index '0'
498489// :69:27: error: use of undefined value here causes illegal behavior
499// :69:27: note: when computing vector element at index '0'
500490// :69:27: error: use of undefined value here causes illegal behavior
501491// :69:27: error: use of undefined value here causes illegal behavior
502492// :69:27: error: use of undefined value here causes illegal behavior
503// :69:27: note: when computing vector element at index '0'
504493// :69:27: error: use of undefined value here causes illegal behavior
505// :69:27: note: when computing vector element at index '0'
506494// :69:27: error: use of undefined value here causes illegal behavior
507// :69:27: note: when computing vector element at index '0'
508495// :69:27: error: use of undefined value here causes illegal behavior
509// :69:27: note: when computing vector element at index '0'
510496// :69:27: error: use of undefined value here causes illegal behavior
511// :69:27: note: when computing vector element at index '1'
512497// :69:27: error: use of undefined value here causes illegal behavior
513// :69:27: note: when computing vector element at index '1'
514498// :69:27: error: use of undefined value here causes illegal behavior
515// :69:27: note: when computing vector element at index '0'
516499// :69:27: error: use of undefined value here causes illegal behavior
517// :69:27: note: when computing vector element at index '0'
518500// :69:27: error: use of undefined value here causes illegal behavior
519501// :69:27: note: when computing vector element at index '0'
520502// :69:27: error: use of undefined value here causes illegal behavior
521503// :69:27: note: when computing vector element at index '0'
522504// :69:27: error: use of undefined value here causes illegal behavior
523// :69:27: error: use of undefined value here causes illegal behavior
524// :69:27: error: use of undefined value here causes illegal behavior
525505// :69:27: note: when computing vector element at index '0'
526506// :69:27: error: use of undefined value here causes illegal behavior
527507// :69:27: note: when computing vector element at index '0'
......@@ -530,10 +510,6 @@ const std = @import("std");
530510// :69:27: error: use of undefined value here causes illegal behavior
531511// :69:27: note: when computing vector element at index '0'
532512// :69:27: error: use of undefined value here causes illegal behavior
533// :69:27: note: when computing vector element at index '1'
534// :69:27: error: use of undefined value here causes illegal behavior
535// :69:27: note: when computing vector element at index '1'
536// :69:27: error: use of undefined value here causes illegal behavior
537513// :69:27: note: when computing vector element at index '0'
538514// :69:27: error: use of undefined value here causes illegal behavior
539515// :69:27: note: when computing vector element at index '0'
......@@ -542,7 +518,9 @@ const std = @import("std");
542518// :69:27: error: use of undefined value here causes illegal behavior
543519// :69:27: note: when computing vector element at index '0'
544520// :69:27: error: use of undefined value here causes illegal behavior
521// :69:27: note: when computing vector element at index '0'
545522// :69:27: error: use of undefined value here causes illegal behavior
523// :69:27: note: when computing vector element at index '0'
546524// :69:27: error: use of undefined value here causes illegal behavior
547525// :69:27: note: when computing vector element at index '0'
548526// :69:27: error: use of undefined value here causes illegal behavior
......@@ -552,9 +530,9 @@ const std = @import("std");
552530// :69:27: error: use of undefined value here causes illegal behavior
553531// :69:27: note: when computing vector element at index '0'
554532// :69:27: error: use of undefined value here causes illegal behavior
555// :69:27: note: when computing vector element at index '1'
533// :69:27: note: when computing vector element at index '0'
556534// :69:27: error: use of undefined value here causes illegal behavior
557// :69:27: note: when computing vector element at index '1'
535// :69:27: note: when computing vector element at index '0'
558536// :69:27: error: use of undefined value here causes illegal behavior
559537// :69:27: note: when computing vector element at index '0'
560538// :69:27: error: use of undefined value here causes illegal behavior
......@@ -564,7 +542,9 @@ const std = @import("std");
564542// :69:27: error: use of undefined value here causes illegal behavior
565543// :69:27: note: when computing vector element at index '0'
566544// :69:27: error: use of undefined value here causes illegal behavior
545// :69:27: note: when computing vector element at index '0'
567546// :69:27: error: use of undefined value here causes illegal behavior
547// :69:27: note: when computing vector element at index '0'
568548// :69:27: error: use of undefined value here causes illegal behavior
569549// :69:27: note: when computing vector element at index '0'
570550// :69:27: error: use of undefined value here causes illegal behavior
......@@ -574,9 +554,9 @@ const std = @import("std");
574554// :69:27: error: use of undefined value here causes illegal behavior
575555// :69:27: note: when computing vector element at index '0'
576556// :69:27: error: use of undefined value here causes illegal behavior
577// :69:27: note: when computing vector element at index '1'
557// :69:27: note: when computing vector element at index '0'
578558// :69:27: error: use of undefined value here causes illegal behavior
579// :69:27: note: when computing vector element at index '1'
559// :69:27: note: when computing vector element at index '0'
580560// :69:27: error: use of undefined value here causes illegal behavior
581561// :69:27: note: when computing vector element at index '0'
582562// :69:27: error: use of undefined value here causes illegal behavior
......@@ -586,7 +566,9 @@ const std = @import("std");
586566// :69:27: error: use of undefined value here causes illegal behavior
587567// :69:27: note: when computing vector element at index '0'
588568// :69:27: error: use of undefined value here causes illegal behavior
569// :69:27: note: when computing vector element at index '0'
589570// :69:27: error: use of undefined value here causes illegal behavior
571// :69:27: note: when computing vector element at index '0'
590572// :69:27: error: use of undefined value here causes illegal behavior
591573// :69:27: note: when computing vector element at index '0'
592574// :69:27: error: use of undefined value here causes illegal behavior
......@@ -596,9 +578,9 @@ const std = @import("std");
596578// :69:27: error: use of undefined value here causes illegal behavior
597579// :69:27: note: when computing vector element at index '0'
598580// :69:27: error: use of undefined value here causes illegal behavior
599// :69:27: note: when computing vector element at index '1'
581// :69:27: note: when computing vector element at index '0'
600582// :69:27: error: use of undefined value here causes illegal behavior
601// :69:27: note: when computing vector element at index '1'
583// :69:27: note: when computing vector element at index '0'
602584// :69:27: error: use of undefined value here causes illegal behavior
603585// :69:27: note: when computing vector element at index '0'
604586// :69:27: error: use of undefined value here causes illegal behavior
......@@ -608,7 +590,9 @@ const std = @import("std");
608590// :69:27: error: use of undefined value here causes illegal behavior
609591// :69:27: note: when computing vector element at index '0'
610592// :69:27: error: use of undefined value here causes illegal behavior
593// :69:27: note: when computing vector element at index '0'
611594// :69:27: error: use of undefined value here causes illegal behavior
595// :69:27: note: when computing vector element at index '0'
612596// :69:27: error: use of undefined value here causes illegal behavior
613597// :69:27: note: when computing vector element at index '0'
614598// :69:27: error: use of undefined value here causes illegal behavior
......@@ -618,9 +602,9 @@ const std = @import("std");
618602// :69:27: error: use of undefined value here causes illegal behavior
619603// :69:27: note: when computing vector element at index '0'
620604// :69:27: error: use of undefined value here causes illegal behavior
621// :69:27: note: when computing vector element at index '1'
605// :69:27: note: when computing vector element at index '0'
622606// :69:27: error: use of undefined value here causes illegal behavior
623// :69:27: note: when computing vector element at index '1'
607// :69:27: note: when computing vector element at index '0'
624608// :69:27: error: use of undefined value here causes illegal behavior
625609// :69:27: note: when computing vector element at index '0'
626610// :69:27: error: use of undefined value here causes illegal behavior
......@@ -630,7 +614,9 @@ const std = @import("std");
630614// :69:27: error: use of undefined value here causes illegal behavior
631615// :69:27: note: when computing vector element at index '0'
632616// :69:27: error: use of undefined value here causes illegal behavior
617// :69:27: note: when computing vector element at index '0'
633618// :69:27: error: use of undefined value here causes illegal behavior
619// :69:27: note: when computing vector element at index '0'
634620// :69:27: error: use of undefined value here causes illegal behavior
635621// :69:27: note: when computing vector element at index '0'
636622// :69:27: error: use of undefined value here causes illegal behavior
......@@ -640,9 +626,9 @@ const std = @import("std");
640626// :69:27: error: use of undefined value here causes illegal behavior
641627// :69:27: note: when computing vector element at index '0'
642628// :69:27: error: use of undefined value here causes illegal behavior
643// :69:27: note: when computing vector element at index '1'
629// :69:27: note: when computing vector element at index '0'
644630// :69:27: error: use of undefined value here causes illegal behavior
645// :69:27: note: when computing vector element at index '1'
631// :69:27: note: when computing vector element at index '0'
646632// :69:27: error: use of undefined value here causes illegal behavior
647633// :69:27: note: when computing vector element at index '0'
648634// :69:27: error: use of undefined value here causes illegal behavior
......@@ -652,7 +638,9 @@ const std = @import("std");
652638// :69:27: error: use of undefined value here causes illegal behavior
653639// :69:27: note: when computing vector element at index '0'
654640// :69:27: error: use of undefined value here causes illegal behavior
641// :69:27: note: when computing vector element at index '0'
655642// :69:27: error: use of undefined value here causes illegal behavior
643// :69:27: note: when computing vector element at index '0'
656644// :69:27: error: use of undefined value here causes illegal behavior
657645// :69:27: note: when computing vector element at index '0'
658646// :69:27: error: use of undefined value here causes illegal behavior
......@@ -662,9 +650,9 @@ const std = @import("std");
662650// :69:27: error: use of undefined value here causes illegal behavior
663651// :69:27: note: when computing vector element at index '0'
664652// :69:27: error: use of undefined value here causes illegal behavior
665// :69:27: note: when computing vector element at index '1'
653// :69:27: note: when computing vector element at index '0'
666654// :69:27: error: use of undefined value here causes illegal behavior
667// :69:27: note: when computing vector element at index '1'
655// :69:27: note: when computing vector element at index '0'
668656// :69:27: error: use of undefined value here causes illegal behavior
669657// :69:27: note: when computing vector element at index '0'
670658// :69:27: error: use of undefined value here causes illegal behavior
......@@ -674,7 +662,9 @@ const std = @import("std");
674662// :69:27: error: use of undefined value here causes illegal behavior
675663// :69:27: note: when computing vector element at index '0'
676664// :69:27: error: use of undefined value here causes illegal behavior
665// :69:27: note: when computing vector element at index '0'
677666// :69:27: error: use of undefined value here causes illegal behavior
667// :69:27: note: when computing vector element at index '0'
678668// :69:27: error: use of undefined value here causes illegal behavior
679669// :69:27: note: when computing vector element at index '0'
680670// :69:27: error: use of undefined value here causes illegal behavior
......@@ -688,35 +678,45 @@ const std = @import("std");
688678// :69:27: error: use of undefined value here causes illegal behavior
689679// :69:27: note: when computing vector element at index '1'
690680// :69:27: error: use of undefined value here causes illegal behavior
691// :69:27: note: when computing vector element at index '0'
681// :69:27: note: when computing vector element at index '1'
692682// :69:27: error: use of undefined value here causes illegal behavior
693// :69:27: note: when computing vector element at index '0'
683// :69:27: note: when computing vector element at index '1'
694684// :69:27: error: use of undefined value here causes illegal behavior
695// :69:27: note: when computing vector element at index '0'
685// :69:27: note: when computing vector element at index '1'
696686// :69:27: error: use of undefined value here causes illegal behavior
697// :69:27: note: when computing vector element at index '0'
687// :69:27: note: when computing vector element at index '1'
698688// :69:27: error: use of undefined value here causes illegal behavior
689// :69:27: note: when computing vector element at index '1'
699690// :69:27: error: use of undefined value here causes illegal behavior
691// :69:27: note: when computing vector element at index '1'
700692// :69:27: error: use of undefined value here causes illegal behavior
701// :69:27: note: when computing vector element at index '0'
693// :69:27: note: when computing vector element at index '1'
702694// :69:27: error: use of undefined value here causes illegal behavior
703// :69:27: note: when computing vector element at index '0'
695// :69:27: note: when computing vector element at index '1'
704696// :69:27: error: use of undefined value here causes illegal behavior
705// :69:27: note: when computing vector element at index '0'
697// :69:27: note: when computing vector element at index '1'
706698// :69:27: error: use of undefined value here causes illegal behavior
707// :69:27: note: when computing vector element at index '0'
699// :69:27: note: when computing vector element at index '1'
708700// :69:27: error: use of undefined value here causes illegal behavior
709701// :69:27: note: when computing vector element at index '1'
710702// :69:27: error: use of undefined value here causes illegal behavior
711703// :69:27: note: when computing vector element at index '1'
712704// :69:27: error: use of undefined value here causes illegal behavior
713// :69:27: note: when computing vector element at index '0'
705// :69:27: note: when computing vector element at index '1'
714706// :69:27: error: use of undefined value here causes illegal behavior
715// :69:27: note: when computing vector element at index '0'
707// :69:27: note: when computing vector element at index '1'
716708// :69:27: error: use of undefined value here causes illegal behavior
717// :69:27: note: when computing vector element at index '0'
709// :69:27: note: when computing vector element at index '1'
718710// :69:27: error: use of undefined value here causes illegal behavior
719// :69:27: note: when computing vector element at index '0'
711// :69:27: note: when computing vector element at index '1'
712// :69:27: error: use of undefined value here causes illegal behavior
713// :69:27: note: when computing vector element at index '1'
714// :69:27: error: use of undefined value here causes illegal behavior
715// :69:27: note: when computing vector element at index '1'
716// :69:27: error: use of undefined value here causes illegal behavior
717// :69:27: note: when computing vector element at index '1'
718// :69:27: error: use of undefined value here causes illegal behavior
719// :69:27: note: when computing vector element at index '1'
720720// :69:30: error: use of undefined value here causes illegal behavior
721721// :69:30: note: when computing vector element at index '0'
722722// :69:30: error: use of undefined value here causes illegal behavior
......@@ -764,50 +764,30 @@ const std = @import("std");
764764// :73:27: error: use of undefined value here causes illegal behavior
765765// :73:27: error: use of undefined value here causes illegal behavior
766766// :73:27: error: use of undefined value here causes illegal behavior
767// :73:27: note: when computing vector element at index '0'
768767// :73:27: error: use of undefined value here causes illegal behavior
769// :73:27: note: when computing vector element at index '0'
770768// :73:27: error: use of undefined value here causes illegal behavior
771// :73:27: note: when computing vector element at index '0'
772769// :73:27: error: use of undefined value here causes illegal behavior
773// :73:27: note: when computing vector element at index '0'
774770// :73:27: error: use of undefined value here causes illegal behavior
775// :73:27: note: when computing vector element at index '1'
776771// :73:27: error: use of undefined value here causes illegal behavior
777// :73:27: note: when computing vector element at index '1'
778772// :73:27: error: use of undefined value here causes illegal behavior
779// :73:27: note: when computing vector element at index '0'
780773// :73:27: error: use of undefined value here causes illegal behavior
781// :73:27: note: when computing vector element at index '0'
782774// :73:27: error: use of undefined value here causes illegal behavior
783// :73:27: note: when computing vector element at index '0'
784775// :73:27: error: use of undefined value here causes illegal behavior
785// :73:27: note: when computing vector element at index '0'
786776// :73:27: error: use of undefined value here causes illegal behavior
787777// :73:27: error: use of undefined value here causes illegal behavior
788778// :73:27: error: use of undefined value here causes illegal behavior
789// :73:27: note: when computing vector element at index '0'
790779// :73:27: error: use of undefined value here causes illegal behavior
791// :73:27: note: when computing vector element at index '0'
792780// :73:27: error: use of undefined value here causes illegal behavior
793// :73:27: note: when computing vector element at index '0'
794781// :73:27: error: use of undefined value here causes illegal behavior
795// :73:27: note: when computing vector element at index '0'
796782// :73:27: error: use of undefined value here causes illegal behavior
797// :73:27: note: when computing vector element at index '1'
798783// :73:27: error: use of undefined value here causes illegal behavior
799// :73:27: note: when computing vector element at index '1'
800784// :73:27: error: use of undefined value here causes illegal behavior
801// :73:27: note: when computing vector element at index '0'
802785// :73:27: error: use of undefined value here causes illegal behavior
803// :73:27: note: when computing vector element at index '0'
804786// :73:27: error: use of undefined value here causes illegal behavior
805787// :73:27: note: when computing vector element at index '0'
806788// :73:27: error: use of undefined value here causes illegal behavior
807789// :73:27: note: when computing vector element at index '0'
808790// :73:27: error: use of undefined value here causes illegal behavior
809// :73:27: error: use of undefined value here causes illegal behavior
810// :73:27: error: use of undefined value here causes illegal behavior
811791// :73:27: note: when computing vector element at index '0'
812792// :73:27: error: use of undefined value here causes illegal behavior
813793// :73:27: note: when computing vector element at index '0'
......@@ -816,10 +796,6 @@ const std = @import("std");
816796// :73:27: error: use of undefined value here causes illegal behavior
817797// :73:27: note: when computing vector element at index '0'
818798// :73:27: error: use of undefined value here causes illegal behavior
819// :73:27: note: when computing vector element at index '1'
820// :73:27: error: use of undefined value here causes illegal behavior
821// :73:27: note: when computing vector element at index '1'
822// :73:27: error: use of undefined value here causes illegal behavior
823799// :73:27: note: when computing vector element at index '0'
824800// :73:27: error: use of undefined value here causes illegal behavior
825801// :73:27: note: when computing vector element at index '0'
......@@ -828,7 +804,9 @@ const std = @import("std");
828804// :73:27: error: use of undefined value here causes illegal behavior
829805// :73:27: note: when computing vector element at index '0'
830806// :73:27: error: use of undefined value here causes illegal behavior
807// :73:27: note: when computing vector element at index '0'
831808// :73:27: error: use of undefined value here causes illegal behavior
809// :73:27: note: when computing vector element at index '0'
832810// :73:27: error: use of undefined value here causes illegal behavior
833811// :73:27: note: when computing vector element at index '0'
834812// :73:27: error: use of undefined value here causes illegal behavior
......@@ -838,9 +816,9 @@ const std = @import("std");
838816// :73:27: error: use of undefined value here causes illegal behavior
839817// :73:27: note: when computing vector element at index '0'
840818// :73:27: error: use of undefined value here causes illegal behavior
841// :73:27: note: when computing vector element at index '1'
819// :73:27: note: when computing vector element at index '0'
842820// :73:27: error: use of undefined value here causes illegal behavior
843// :73:27: note: when computing vector element at index '1'
821// :73:27: note: when computing vector element at index '0'
844822// :73:27: error: use of undefined value here causes illegal behavior
845823// :73:27: note: when computing vector element at index '0'
846824// :73:27: error: use of undefined value here causes illegal behavior
......@@ -850,7 +828,9 @@ const std = @import("std");
850828// :73:27: error: use of undefined value here causes illegal behavior
851829// :73:27: note: when computing vector element at index '0'
852830// :73:27: error: use of undefined value here causes illegal behavior
831// :73:27: note: when computing vector element at index '0'
853832// :73:27: error: use of undefined value here causes illegal behavior
833// :73:27: note: when computing vector element at index '0'
854834// :73:27: error: use of undefined value here causes illegal behavior
855835// :73:27: note: when computing vector element at index '0'
856836// :73:27: error: use of undefined value here causes illegal behavior
......@@ -860,9 +840,9 @@ const std = @import("std");
860840// :73:27: error: use of undefined value here causes illegal behavior
861841// :73:27: note: when computing vector element at index '0'
862842// :73:27: error: use of undefined value here causes illegal behavior
863// :73:27: note: when computing vector element at index '1'
843// :73:27: note: when computing vector element at index '0'
864844// :73:27: error: use of undefined value here causes illegal behavior
865// :73:27: note: when computing vector element at index '1'
845// :73:27: note: when computing vector element at index '0'
866846// :73:27: error: use of undefined value here causes illegal behavior
867847// :73:27: note: when computing vector element at index '0'
868848// :73:27: error: use of undefined value here causes illegal behavior
......@@ -872,7 +852,9 @@ const std = @import("std");
872852// :73:27: error: use of undefined value here causes illegal behavior
873853// :73:27: note: when computing vector element at index '0'
874854// :73:27: error: use of undefined value here causes illegal behavior
855// :73:27: note: when computing vector element at index '0'
875856// :73:27: error: use of undefined value here causes illegal behavior
857// :73:27: note: when computing vector element at index '0'
876858// :73:27: error: use of undefined value here causes illegal behavior
877859// :73:27: note: when computing vector element at index '0'
878860// :73:27: error: use of undefined value here causes illegal behavior
......@@ -882,9 +864,9 @@ const std = @import("std");
882864// :73:27: error: use of undefined value here causes illegal behavior
883865// :73:27: note: when computing vector element at index '0'
884866// :73:27: error: use of undefined value here causes illegal behavior
885// :73:27: note: when computing vector element at index '1'
867// :73:27: note: when computing vector element at index '0'
886868// :73:27: error: use of undefined value here causes illegal behavior
887// :73:27: note: when computing vector element at index '1'
869// :73:27: note: when computing vector element at index '0'
888870// :73:27: error: use of undefined value here causes illegal behavior
889871// :73:27: note: when computing vector element at index '0'
890872// :73:27: error: use of undefined value here causes illegal behavior
......@@ -894,7 +876,9 @@ const std = @import("std");
894876// :73:27: error: use of undefined value here causes illegal behavior
895877// :73:27: note: when computing vector element at index '0'
896878// :73:27: error: use of undefined value here causes illegal behavior
879// :73:27: note: when computing vector element at index '0'
897880// :73:27: error: use of undefined value here causes illegal behavior
881// :73:27: note: when computing vector element at index '0'
898882// :73:27: error: use of undefined value here causes illegal behavior
899883// :73:27: note: when computing vector element at index '0'
900884// :73:27: error: use of undefined value here causes illegal behavior
......@@ -904,9 +888,9 @@ const std = @import("std");
904888// :73:27: error: use of undefined value here causes illegal behavior
905889// :73:27: note: when computing vector element at index '0'
906890// :73:27: error: use of undefined value here causes illegal behavior
907// :73:27: note: when computing vector element at index '1'
891// :73:27: note: when computing vector element at index '0'
908892// :73:27: error: use of undefined value here causes illegal behavior
909// :73:27: note: when computing vector element at index '1'
893// :73:27: note: when computing vector element at index '0'
910894// :73:27: error: use of undefined value here causes illegal behavior
911895// :73:27: note: when computing vector element at index '0'
912896// :73:27: error: use of undefined value here causes illegal behavior
......@@ -916,7 +900,9 @@ const std = @import("std");
916900// :73:27: error: use of undefined value here causes illegal behavior
917901// :73:27: note: when computing vector element at index '0'
918902// :73:27: error: use of undefined value here causes illegal behavior
903// :73:27: note: when computing vector element at index '0'
919904// :73:27: error: use of undefined value here causes illegal behavior
905// :73:27: note: when computing vector element at index '0'
920906// :73:27: error: use of undefined value here causes illegal behavior
921907// :73:27: note: when computing vector element at index '0'
922908// :73:27: error: use of undefined value here causes illegal behavior
......@@ -926,9 +912,9 @@ const std = @import("std");
926912// :73:27: error: use of undefined value here causes illegal behavior
927913// :73:27: note: when computing vector element at index '0'
928914// :73:27: error: use of undefined value here causes illegal behavior
929// :73:27: note: when computing vector element at index '1'
915// :73:27: note: when computing vector element at index '0'
930916// :73:27: error: use of undefined value here causes illegal behavior
931// :73:27: note: when computing vector element at index '1'
917// :73:27: note: when computing vector element at index '0'
932918// :73:27: error: use of undefined value here causes illegal behavior
933919// :73:27: note: when computing vector element at index '0'
934920// :73:27: error: use of undefined value here causes illegal behavior
......@@ -938,7 +924,9 @@ const std = @import("std");
938924// :73:27: error: use of undefined value here causes illegal behavior
939925// :73:27: note: when computing vector element at index '0'
940926// :73:27: error: use of undefined value here causes illegal behavior
927// :73:27: note: when computing vector element at index '0'
941928// :73:27: error: use of undefined value here causes illegal behavior
929// :73:27: note: when computing vector element at index '0'
942930// :73:27: error: use of undefined value here causes illegal behavior
943931// :73:27: note: when computing vector element at index '0'
944932// :73:27: error: use of undefined value here causes illegal behavior
......@@ -948,9 +936,9 @@ const std = @import("std");
948936// :73:27: error: use of undefined value here causes illegal behavior
949937// :73:27: note: when computing vector element at index '0'
950938// :73:27: error: use of undefined value here causes illegal behavior
951// :73:27: note: when computing vector element at index '1'
939// :73:27: note: when computing vector element at index '0'
952940// :73:27: error: use of undefined value here causes illegal behavior
953// :73:27: note: when computing vector element at index '1'
941// :73:27: note: when computing vector element at index '0'
954942// :73:27: error: use of undefined value here causes illegal behavior
955943// :73:27: note: when computing vector element at index '0'
956944// :73:27: error: use of undefined value here causes illegal behavior
......@@ -960,7 +948,9 @@ const std = @import("std");
960948// :73:27: error: use of undefined value here causes illegal behavior
961949// :73:27: note: when computing vector element at index '0'
962950// :73:27: error: use of undefined value here causes illegal behavior
951// :73:27: note: when computing vector element at index '0'
963952// :73:27: error: use of undefined value here causes illegal behavior
953// :73:27: note: when computing vector element at index '0'
964954// :73:27: error: use of undefined value here causes illegal behavior
965955// :73:27: note: when computing vector element at index '0'
966956// :73:27: error: use of undefined value here causes illegal behavior
......@@ -974,35 +964,45 @@ const std = @import("std");
974964// :73:27: error: use of undefined value here causes illegal behavior
975965// :73:27: note: when computing vector element at index '1'
976966// :73:27: error: use of undefined value here causes illegal behavior
977// :73:27: note: when computing vector element at index '0'
967// :73:27: note: when computing vector element at index '1'
978968// :73:27: error: use of undefined value here causes illegal behavior
979// :73:27: note: when computing vector element at index '0'
969// :73:27: note: when computing vector element at index '1'
980970// :73:27: error: use of undefined value here causes illegal behavior
981// :73:27: note: when computing vector element at index '0'
971// :73:27: note: when computing vector element at index '1'
982972// :73:27: error: use of undefined value here causes illegal behavior
983// :73:27: note: when computing vector element at index '0'
973// :73:27: note: when computing vector element at index '1'
984974// :73:27: error: use of undefined value here causes illegal behavior
975// :73:27: note: when computing vector element at index '1'
985976// :73:27: error: use of undefined value here causes illegal behavior
977// :73:27: note: when computing vector element at index '1'
986978// :73:27: error: use of undefined value here causes illegal behavior
987// :73:27: note: when computing vector element at index '0'
979// :73:27: note: when computing vector element at index '1'
988980// :73:27: error: use of undefined value here causes illegal behavior
989// :73:27: note: when computing vector element at index '0'
981// :73:27: note: when computing vector element at index '1'
990982// :73:27: error: use of undefined value here causes illegal behavior
991// :73:27: note: when computing vector element at index '0'
983// :73:27: note: when computing vector element at index '1'
992984// :73:27: error: use of undefined value here causes illegal behavior
993// :73:27: note: when computing vector element at index '0'
985// :73:27: note: when computing vector element at index '1'
994986// :73:27: error: use of undefined value here causes illegal behavior
995987// :73:27: note: when computing vector element at index '1'
996988// :73:27: error: use of undefined value here causes illegal behavior
997989// :73:27: note: when computing vector element at index '1'
998990// :73:27: error: use of undefined value here causes illegal behavior
999// :73:27: note: when computing vector element at index '0'
991// :73:27: note: when computing vector element at index '1'
1000992// :73:27: error: use of undefined value here causes illegal behavior
1001// :73:27: note: when computing vector element at index '0'
993// :73:27: note: when computing vector element at index '1'
1002994// :73:27: error: use of undefined value here causes illegal behavior
1003// :73:27: note: when computing vector element at index '0'
995// :73:27: note: when computing vector element at index '1'
1004996// :73:27: error: use of undefined value here causes illegal behavior
1005// :73:27: note: when computing vector element at index '0'
997// :73:27: note: when computing vector element at index '1'
998// :73:27: error: use of undefined value here causes illegal behavior
999// :73:27: note: when computing vector element at index '1'
1000// :73:27: error: use of undefined value here causes illegal behavior
1001// :73:27: note: when computing vector element at index '1'
1002// :73:27: error: use of undefined value here causes illegal behavior
1003// :73:27: note: when computing vector element at index '1'
1004// :73:27: error: use of undefined value here causes illegal behavior
1005// :73:27: note: when computing vector element at index '1'
10061006// :73:30: error: use of undefined value here causes illegal behavior
10071007// :73:30: note: when computing vector element at index '0'
10081008// :73:30: error: use of undefined value here causes illegal behavior
......@@ -1050,50 +1050,30 @@ const std = @import("std");
10501050// :77:27: error: use of undefined value here causes illegal behavior
10511051// :77:27: error: use of undefined value here causes illegal behavior
10521052// :77:27: error: use of undefined value here causes illegal behavior
1053// :77:27: note: when computing vector element at index '0'
10541053// :77:27: error: use of undefined value here causes illegal behavior
1055// :77:27: note: when computing vector element at index '0'
10561054// :77:27: error: use of undefined value here causes illegal behavior
1057// :77:27: note: when computing vector element at index '0'
10581055// :77:27: error: use of undefined value here causes illegal behavior
1059// :77:27: note: when computing vector element at index '0'
10601056// :77:27: error: use of undefined value here causes illegal behavior
1061// :77:27: note: when computing vector element at index '1'
10621057// :77:27: error: use of undefined value here causes illegal behavior
1063// :77:27: note: when computing vector element at index '1'
10641058// :77:27: error: use of undefined value here causes illegal behavior
1065// :77:27: note: when computing vector element at index '0'
10661059// :77:27: error: use of undefined value here causes illegal behavior
1067// :77:27: note: when computing vector element at index '0'
10681060// :77:27: error: use of undefined value here causes illegal behavior
1069// :77:27: note: when computing vector element at index '0'
10701061// :77:27: error: use of undefined value here causes illegal behavior
1071// :77:27: note: when computing vector element at index '0'
10721062// :77:27: error: use of undefined value here causes illegal behavior
10731063// :77:27: error: use of undefined value here causes illegal behavior
10741064// :77:27: error: use of undefined value here causes illegal behavior
1075// :77:27: note: when computing vector element at index '0'
10761065// :77:27: error: use of undefined value here causes illegal behavior
1077// :77:27: note: when computing vector element at index '0'
10781066// :77:27: error: use of undefined value here causes illegal behavior
1079// :77:27: note: when computing vector element at index '0'
10801067// :77:27: error: use of undefined value here causes illegal behavior
1081// :77:27: note: when computing vector element at index '0'
10821068// :77:27: error: use of undefined value here causes illegal behavior
1083// :77:27: note: when computing vector element at index '1'
10841069// :77:27: error: use of undefined value here causes illegal behavior
1085// :77:27: note: when computing vector element at index '1'
10861070// :77:27: error: use of undefined value here causes illegal behavior
1087// :77:27: note: when computing vector element at index '0'
10881071// :77:27: error: use of undefined value here causes illegal behavior
1089// :77:27: note: when computing vector element at index '0'
10901072// :77:27: error: use of undefined value here causes illegal behavior
10911073// :77:27: note: when computing vector element at index '0'
10921074// :77:27: error: use of undefined value here causes illegal behavior
10931075// :77:27: note: when computing vector element at index '0'
10941076// :77:27: error: use of undefined value here causes illegal behavior
1095// :77:27: error: use of undefined value here causes illegal behavior
1096// :77:27: error: use of undefined value here causes illegal behavior
10971077// :77:27: note: when computing vector element at index '0'
10981078// :77:27: error: use of undefined value here causes illegal behavior
10991079// :77:27: note: when computing vector element at index '0'
......@@ -1102,10 +1082,6 @@ const std = @import("std");
11021082// :77:27: error: use of undefined value here causes illegal behavior
11031083// :77:27: note: when computing vector element at index '0'
11041084// :77:27: error: use of undefined value here causes illegal behavior
1105// :77:27: note: when computing vector element at index '1'
1106// :77:27: error: use of undefined value here causes illegal behavior
1107// :77:27: note: when computing vector element at index '1'
1108// :77:27: error: use of undefined value here causes illegal behavior
11091085// :77:27: note: when computing vector element at index '0'
11101086// :77:27: error: use of undefined value here causes illegal behavior
11111087// :77:27: note: when computing vector element at index '0'
......@@ -1114,7 +1090,9 @@ const std = @import("std");
11141090// :77:27: error: use of undefined value here causes illegal behavior
11151091// :77:27: note: when computing vector element at index '0'
11161092// :77:27: error: use of undefined value here causes illegal behavior
1093// :77:27: note: when computing vector element at index '0'
11171094// :77:27: error: use of undefined value here causes illegal behavior
1095// :77:27: note: when computing vector element at index '0'
11181096// :77:27: error: use of undefined value here causes illegal behavior
11191097// :77:27: note: when computing vector element at index '0'
11201098// :77:27: error: use of undefined value here causes illegal behavior
......@@ -1124,9 +1102,9 @@ const std = @import("std");
11241102// :77:27: error: use of undefined value here causes illegal behavior
11251103// :77:27: note: when computing vector element at index '0'
11261104// :77:27: error: use of undefined value here causes illegal behavior
1127// :77:27: note: when computing vector element at index '1'
1105// :77:27: note: when computing vector element at index '0'
11281106// :77:27: error: use of undefined value here causes illegal behavior
1129// :77:27: note: when computing vector element at index '1'
1107// :77:27: note: when computing vector element at index '0'
11301108// :77:27: error: use of undefined value here causes illegal behavior
11311109// :77:27: note: when computing vector element at index '0'
11321110// :77:27: error: use of undefined value here causes illegal behavior
......@@ -1136,7 +1114,9 @@ const std = @import("std");
11361114// :77:27: error: use of undefined value here causes illegal behavior
11371115// :77:27: note: when computing vector element at index '0'
11381116// :77:27: error: use of undefined value here causes illegal behavior
1117// :77:27: note: when computing vector element at index '0'
11391118// :77:27: error: use of undefined value here causes illegal behavior
1119// :77:27: note: when computing vector element at index '0'
11401120// :77:27: error: use of undefined value here causes illegal behavior
11411121// :77:27: note: when computing vector element at index '0'
11421122// :77:27: error: use of undefined value here causes illegal behavior
......@@ -1146,9 +1126,9 @@ const std = @import("std");
11461126// :77:27: error: use of undefined value here causes illegal behavior
11471127// :77:27: note: when computing vector element at index '0'
11481128// :77:27: error: use of undefined value here causes illegal behavior
1149// :77:27: note: when computing vector element at index '1'
1129// :77:27: note: when computing vector element at index '0'
11501130// :77:27: error: use of undefined value here causes illegal behavior
1151// :77:27: note: when computing vector element at index '1'
1131// :77:27: note: when computing vector element at index '0'
11521132// :77:27: error: use of undefined value here causes illegal behavior
11531133// :77:27: note: when computing vector element at index '0'
11541134// :77:27: error: use of undefined value here causes illegal behavior
......@@ -1158,7 +1138,9 @@ const std = @import("std");
11581138// :77:27: error: use of undefined value here causes illegal behavior
11591139// :77:27: note: when computing vector element at index '0'
11601140// :77:27: error: use of undefined value here causes illegal behavior
1141// :77:27: note: when computing vector element at index '0'
11611142// :77:27: error: use of undefined value here causes illegal behavior
1143// :77:27: note: when computing vector element at index '0'
11621144// :77:27: error: use of undefined value here causes illegal behavior
11631145// :77:27: note: when computing vector element at index '0'
11641146// :77:27: error: use of undefined value here causes illegal behavior
......@@ -1168,9 +1150,9 @@ const std = @import("std");
11681150// :77:27: error: use of undefined value here causes illegal behavior
11691151// :77:27: note: when computing vector element at index '0'
11701152// :77:27: error: use of undefined value here causes illegal behavior
1171// :77:27: note: when computing vector element at index '1'
1153// :77:27: note: when computing vector element at index '0'
11721154// :77:27: error: use of undefined value here causes illegal behavior
1173// :77:27: note: when computing vector element at index '1'
1155// :77:27: note: when computing vector element at index '0'
11741156// :77:27: error: use of undefined value here causes illegal behavior
11751157// :77:27: note: when computing vector element at index '0'
11761158// :77:27: error: use of undefined value here causes illegal behavior
......@@ -1180,7 +1162,9 @@ const std = @import("std");
11801162// :77:27: error: use of undefined value here causes illegal behavior
11811163// :77:27: note: when computing vector element at index '0'
11821164// :77:27: error: use of undefined value here causes illegal behavior
1165// :77:27: note: when computing vector element at index '0'
11831166// :77:27: error: use of undefined value here causes illegal behavior
1167// :77:27: note: when computing vector element at index '0'
11841168// :77:27: error: use of undefined value here causes illegal behavior
11851169// :77:27: note: when computing vector element at index '0'
11861170// :77:27: error: use of undefined value here causes illegal behavior
......@@ -1190,9 +1174,9 @@ const std = @import("std");
11901174// :77:27: error: use of undefined value here causes illegal behavior
11911175// :77:27: note: when computing vector element at index '0'
11921176// :77:27: error: use of undefined value here causes illegal behavior
1193// :77:27: note: when computing vector element at index '1'
1177// :77:27: note: when computing vector element at index '0'
11941178// :77:27: error: use of undefined value here causes illegal behavior
1195// :77:27: note: when computing vector element at index '1'
1179// :77:27: note: when computing vector element at index '0'
11961180// :77:27: error: use of undefined value here causes illegal behavior
11971181// :77:27: note: when computing vector element at index '0'
11981182// :77:27: error: use of undefined value here causes illegal behavior
......@@ -1202,7 +1186,9 @@ const std = @import("std");
12021186// :77:27: error: use of undefined value here causes illegal behavior
12031187// :77:27: note: when computing vector element at index '0'
12041188// :77:27: error: use of undefined value here causes illegal behavior
1189// :77:27: note: when computing vector element at index '0'
12051190// :77:27: error: use of undefined value here causes illegal behavior
1191// :77:27: note: when computing vector element at index '0'
12061192// :77:27: error: use of undefined value here causes illegal behavior
12071193// :77:27: note: when computing vector element at index '0'
12081194// :77:27: error: use of undefined value here causes illegal behavior
......@@ -1212,9 +1198,9 @@ const std = @import("std");
12121198// :77:27: error: use of undefined value here causes illegal behavior
12131199// :77:27: note: when computing vector element at index '0'
12141200// :77:27: error: use of undefined value here causes illegal behavior
1215// :77:27: note: when computing vector element at index '1'
1201// :77:27: note: when computing vector element at index '0'
12161202// :77:27: error: use of undefined value here causes illegal behavior
1217// :77:27: note: when computing vector element at index '1'
1203// :77:27: note: when computing vector element at index '0'
12181204// :77:27: error: use of undefined value here causes illegal behavior
12191205// :77:27: note: when computing vector element at index '0'
12201206// :77:27: error: use of undefined value here causes illegal behavior
......@@ -1224,7 +1210,9 @@ const std = @import("std");
12241210// :77:27: error: use of undefined value here causes illegal behavior
12251211// :77:27: note: when computing vector element at index '0'
12261212// :77:27: error: use of undefined value here causes illegal behavior
1213// :77:27: note: when computing vector element at index '0'
12271214// :77:27: error: use of undefined value here causes illegal behavior
1215// :77:27: note: when computing vector element at index '0'
12281216// :77:27: error: use of undefined value here causes illegal behavior
12291217// :77:27: note: when computing vector element at index '0'
12301218// :77:27: error: use of undefined value here causes illegal behavior
......@@ -1234,9 +1222,9 @@ const std = @import("std");
12341222// :77:27: error: use of undefined value here causes illegal behavior
12351223// :77:27: note: when computing vector element at index '0'
12361224// :77:27: error: use of undefined value here causes illegal behavior
1237// :77:27: note: when computing vector element at index '1'
1225// :77:27: note: when computing vector element at index '0'
12381226// :77:27: error: use of undefined value here causes illegal behavior
1239// :77:27: note: when computing vector element at index '1'
1227// :77:27: note: when computing vector element at index '0'
12401228// :77:27: error: use of undefined value here causes illegal behavior
12411229// :77:27: note: when computing vector element at index '0'
12421230// :77:27: error: use of undefined value here causes illegal behavior
......@@ -1246,7 +1234,9 @@ const std = @import("std");
12461234// :77:27: error: use of undefined value here causes illegal behavior
12471235// :77:27: note: when computing vector element at index '0'
12481236// :77:27: error: use of undefined value here causes illegal behavior
1237// :77:27: note: when computing vector element at index '0'
12491238// :77:27: error: use of undefined value here causes illegal behavior
1239// :77:27: note: when computing vector element at index '0'
12501240// :77:27: error: use of undefined value here causes illegal behavior
12511241// :77:27: note: when computing vector element at index '0'
12521242// :77:27: error: use of undefined value here causes illegal behavior
......@@ -1260,35 +1250,45 @@ const std = @import("std");
12601250// :77:27: error: use of undefined value here causes illegal behavior
12611251// :77:27: note: when computing vector element at index '1'
12621252// :77:27: error: use of undefined value here causes illegal behavior
1263// :77:27: note: when computing vector element at index '0'
1253// :77:27: note: when computing vector element at index '1'
12641254// :77:27: error: use of undefined value here causes illegal behavior
1265// :77:27: note: when computing vector element at index '0'
1255// :77:27: note: when computing vector element at index '1'
12661256// :77:27: error: use of undefined value here causes illegal behavior
1267// :77:27: note: when computing vector element at index '0'
1257// :77:27: note: when computing vector element at index '1'
12681258// :77:27: error: use of undefined value here causes illegal behavior
1269// :77:27: note: when computing vector element at index '0'
1259// :77:27: note: when computing vector element at index '1'
12701260// :77:27: error: use of undefined value here causes illegal behavior
1261// :77:27: note: when computing vector element at index '1'
12711262// :77:27: error: use of undefined value here causes illegal behavior
1263// :77:27: note: when computing vector element at index '1'
12721264// :77:27: error: use of undefined value here causes illegal behavior
1273// :77:27: note: when computing vector element at index '0'
1265// :77:27: note: when computing vector element at index '1'
12741266// :77:27: error: use of undefined value here causes illegal behavior
1275// :77:27: note: when computing vector element at index '0'
1267// :77:27: note: when computing vector element at index '1'
12761268// :77:27: error: use of undefined value here causes illegal behavior
1277// :77:27: note: when computing vector element at index '0'
1269// :77:27: note: when computing vector element at index '1'
12781270// :77:27: error: use of undefined value here causes illegal behavior
1279// :77:27: note: when computing vector element at index '0'
1271// :77:27: note: when computing vector element at index '1'
12801272// :77:27: error: use of undefined value here causes illegal behavior
12811273// :77:27: note: when computing vector element at index '1'
12821274// :77:27: error: use of undefined value here causes illegal behavior
12831275// :77:27: note: when computing vector element at index '1'
12841276// :77:27: error: use of undefined value here causes illegal behavior
1285// :77:27: note: when computing vector element at index '0'
1277// :77:27: note: when computing vector element at index '1'
12861278// :77:27: error: use of undefined value here causes illegal behavior
1287// :77:27: note: when computing vector element at index '0'
1279// :77:27: note: when computing vector element at index '1'
12881280// :77:27: error: use of undefined value here causes illegal behavior
1289// :77:27: note: when computing vector element at index '0'
1281// :77:27: note: when computing vector element at index '1'
12901282// :77:27: error: use of undefined value here causes illegal behavior
1291// :77:27: note: when computing vector element at index '0'
1283// :77:27: note: when computing vector element at index '1'
1284// :77:27: error: use of undefined value here causes illegal behavior
1285// :77:27: note: when computing vector element at index '1'
1286// :77:27: error: use of undefined value here causes illegal behavior
1287// :77:27: note: when computing vector element at index '1'
1288// :77:27: error: use of undefined value here causes illegal behavior
1289// :77:27: note: when computing vector element at index '1'
1290// :77:27: error: use of undefined value here causes illegal behavior
1291// :77:27: note: when computing vector element at index '1'
12921292// :77:30: error: use of undefined value here causes illegal behavior
12931293// :77:30: note: when computing vector element at index '0'
12941294// :77:30: error: use of undefined value here causes illegal behavior
......@@ -1336,50 +1336,30 @@ const std = @import("std");
13361336// :81:17: error: use of undefined value here causes illegal behavior
13371337// :81:17: error: use of undefined value here causes illegal behavior
13381338// :81:17: error: use of undefined value here causes illegal behavior
1339// :81:17: note: when computing vector element at index '0'
13401339// :81:17: error: use of undefined value here causes illegal behavior
1341// :81:17: note: when computing vector element at index '0'
13421340// :81:17: error: use of undefined value here causes illegal behavior
1343// :81:17: note: when computing vector element at index '0'
13441341// :81:17: error: use of undefined value here causes illegal behavior
1345// :81:17: note: when computing vector element at index '0'
13461342// :81:17: error: use of undefined value here causes illegal behavior
1347// :81:17: note: when computing vector element at index '1'
13481343// :81:17: error: use of undefined value here causes illegal behavior
1349// :81:17: note: when computing vector element at index '1'
13501344// :81:17: error: use of undefined value here causes illegal behavior
1351// :81:17: note: when computing vector element at index '0'
13521345// :81:17: error: use of undefined value here causes illegal behavior
1353// :81:17: note: when computing vector element at index '0'
13541346// :81:17: error: use of undefined value here causes illegal behavior
1355// :81:17: note: when computing vector element at index '0'
13561347// :81:17: error: use of undefined value here causes illegal behavior
1357// :81:17: note: when computing vector element at index '0'
13581348// :81:17: error: use of undefined value here causes illegal behavior
13591349// :81:17: error: use of undefined value here causes illegal behavior
13601350// :81:17: error: use of undefined value here causes illegal behavior
1361// :81:17: note: when computing vector element at index '0'
13621351// :81:17: error: use of undefined value here causes illegal behavior
1363// :81:17: note: when computing vector element at index '0'
13641352// :81:17: error: use of undefined value here causes illegal behavior
1365// :81:17: note: when computing vector element at index '0'
13661353// :81:17: error: use of undefined value here causes illegal behavior
1367// :81:17: note: when computing vector element at index '0'
13681354// :81:17: error: use of undefined value here causes illegal behavior
1369// :81:17: note: when computing vector element at index '1'
13701355// :81:17: error: use of undefined value here causes illegal behavior
1371// :81:17: note: when computing vector element at index '1'
13721356// :81:17: error: use of undefined value here causes illegal behavior
1373// :81:17: note: when computing vector element at index '0'
13741357// :81:17: error: use of undefined value here causes illegal behavior
1375// :81:17: note: when computing vector element at index '0'
13761358// :81:17: error: use of undefined value here causes illegal behavior
13771359// :81:17: note: when computing vector element at index '0'
13781360// :81:17: error: use of undefined value here causes illegal behavior
13791361// :81:17: note: when computing vector element at index '0'
13801362// :81:17: error: use of undefined value here causes illegal behavior
1381// :81:17: error: use of undefined value here causes illegal behavior
1382// :81:17: error: use of undefined value here causes illegal behavior
13831363// :81:17: note: when computing vector element at index '0'
13841364// :81:17: error: use of undefined value here causes illegal behavior
13851365// :81:17: note: when computing vector element at index '0'
......@@ -1388,10 +1368,6 @@ const std = @import("std");
13881368// :81:17: error: use of undefined value here causes illegal behavior
13891369// :81:17: note: when computing vector element at index '0'
13901370// :81:17: error: use of undefined value here causes illegal behavior
1391// :81:17: note: when computing vector element at index '1'
1392// :81:17: error: use of undefined value here causes illegal behavior
1393// :81:17: note: when computing vector element at index '1'
1394// :81:17: error: use of undefined value here causes illegal behavior
13951371// :81:17: note: when computing vector element at index '0'
13961372// :81:17: error: use of undefined value here causes illegal behavior
13971373// :81:17: note: when computing vector element at index '0'
......@@ -1400,7 +1376,9 @@ const std = @import("std");
14001376// :81:17: error: use of undefined value here causes illegal behavior
14011377// :81:17: note: when computing vector element at index '0'
14021378// :81:17: error: use of undefined value here causes illegal behavior
1379// :81:17: note: when computing vector element at index '0'
14031380// :81:17: error: use of undefined value here causes illegal behavior
1381// :81:17: note: when computing vector element at index '0'
14041382// :81:17: error: use of undefined value here causes illegal behavior
14051383// :81:17: note: when computing vector element at index '0'
14061384// :81:17: error: use of undefined value here causes illegal behavior
......@@ -1410,9 +1388,9 @@ const std = @import("std");
14101388// :81:17: error: use of undefined value here causes illegal behavior
14111389// :81:17: note: when computing vector element at index '0'
14121390// :81:17: error: use of undefined value here causes illegal behavior
1413// :81:17: note: when computing vector element at index '1'
1391// :81:17: note: when computing vector element at index '0'
14141392// :81:17: error: use of undefined value here causes illegal behavior
1415// :81:17: note: when computing vector element at index '1'
1393// :81:17: note: when computing vector element at index '0'
14161394// :81:17: error: use of undefined value here causes illegal behavior
14171395// :81:17: note: when computing vector element at index '0'
14181396// :81:17: error: use of undefined value here causes illegal behavior
......@@ -1422,7 +1400,9 @@ const std = @import("std");
14221400// :81:17: error: use of undefined value here causes illegal behavior
14231401// :81:17: note: when computing vector element at index '0'
14241402// :81:17: error: use of undefined value here causes illegal behavior
1403// :81:17: note: when computing vector element at index '0'
14251404// :81:17: error: use of undefined value here causes illegal behavior
1405// :81:17: note: when computing vector element at index '0'
14261406// :81:17: error: use of undefined value here causes illegal behavior
14271407// :81:17: note: when computing vector element at index '0'
14281408// :81:17: error: use of undefined value here causes illegal behavior
......@@ -1432,9 +1412,9 @@ const std = @import("std");
14321412// :81:17: error: use of undefined value here causes illegal behavior
14331413// :81:17: note: when computing vector element at index '0'
14341414// :81:17: error: use of undefined value here causes illegal behavior
1435// :81:17: note: when computing vector element at index '1'
1415// :81:17: note: when computing vector element at index '0'
14361416// :81:17: error: use of undefined value here causes illegal behavior
1437// :81:17: note: when computing vector element at index '1'
1417// :81:17: note: when computing vector element at index '0'
14381418// :81:17: error: use of undefined value here causes illegal behavior
14391419// :81:17: note: when computing vector element at index '0'
14401420// :81:17: error: use of undefined value here causes illegal behavior
......@@ -1444,7 +1424,9 @@ const std = @import("std");
14441424// :81:17: error: use of undefined value here causes illegal behavior
14451425// :81:17: note: when computing vector element at index '0'
14461426// :81:17: error: use of undefined value here causes illegal behavior
1427// :81:17: note: when computing vector element at index '0'
14471428// :81:17: error: use of undefined value here causes illegal behavior
1429// :81:17: note: when computing vector element at index '0'
14481430// :81:17: error: use of undefined value here causes illegal behavior
14491431// :81:17: note: when computing vector element at index '0'
14501432// :81:17: error: use of undefined value here causes illegal behavior
......@@ -1454,9 +1436,9 @@ const std = @import("std");
14541436// :81:17: error: use of undefined value here causes illegal behavior
14551437// :81:17: note: when computing vector element at index '0'
14561438// :81:17: error: use of undefined value here causes illegal behavior
1457// :81:17: note: when computing vector element at index '1'
1439// :81:17: note: when computing vector element at index '0'
14581440// :81:17: error: use of undefined value here causes illegal behavior
1459// :81:17: note: when computing vector element at index '1'
1441// :81:17: note: when computing vector element at index '0'
14601442// :81:17: error: use of undefined value here causes illegal behavior
14611443// :81:17: note: when computing vector element at index '0'
14621444// :81:17: error: use of undefined value here causes illegal behavior
......@@ -1466,7 +1448,9 @@ const std = @import("std");
14661448// :81:17: error: use of undefined value here causes illegal behavior
14671449// :81:17: note: when computing vector element at index '0'
14681450// :81:17: error: use of undefined value here causes illegal behavior
1451// :81:17: note: when computing vector element at index '0'
14691452// :81:17: error: use of undefined value here causes illegal behavior
1453// :81:17: note: when computing vector element at index '0'
14701454// :81:17: error: use of undefined value here causes illegal behavior
14711455// :81:17: note: when computing vector element at index '0'
14721456// :81:17: error: use of undefined value here causes illegal behavior
......@@ -1476,9 +1460,9 @@ const std = @import("std");
14761460// :81:17: error: use of undefined value here causes illegal behavior
14771461// :81:17: note: when computing vector element at index '0'
14781462// :81:17: error: use of undefined value here causes illegal behavior
1479// :81:17: note: when computing vector element at index '1'
1463// :81:17: note: when computing vector element at index '0'
14801464// :81:17: error: use of undefined value here causes illegal behavior
1481// :81:17: note: when computing vector element at index '1'
1465// :81:17: note: when computing vector element at index '0'
14821466// :81:17: error: use of undefined value here causes illegal behavior
14831467// :81:17: note: when computing vector element at index '0'
14841468// :81:17: error: use of undefined value here causes illegal behavior
......@@ -1488,7 +1472,9 @@ const std = @import("std");
14881472// :81:17: error: use of undefined value here causes illegal behavior
14891473// :81:17: note: when computing vector element at index '0'
14901474// :81:17: error: use of undefined value here causes illegal behavior
1475// :81:17: note: when computing vector element at index '0'
14911476// :81:17: error: use of undefined value here causes illegal behavior
1477// :81:17: note: when computing vector element at index '0'
14921478// :81:17: error: use of undefined value here causes illegal behavior
14931479// :81:17: note: when computing vector element at index '0'
14941480// :81:17: error: use of undefined value here causes illegal behavior
......@@ -1498,9 +1484,9 @@ const std = @import("std");
14981484// :81:17: error: use of undefined value here causes illegal behavior
14991485// :81:17: note: when computing vector element at index '0'
15001486// :81:17: error: use of undefined value here causes illegal behavior
1501// :81:17: note: when computing vector element at index '1'
1487// :81:17: note: when computing vector element at index '0'
15021488// :81:17: error: use of undefined value here causes illegal behavior
1503// :81:17: note: when computing vector element at index '1'
1489// :81:17: note: when computing vector element at index '0'
15041490// :81:17: error: use of undefined value here causes illegal behavior
15051491// :81:17: note: when computing vector element at index '0'
15061492// :81:17: error: use of undefined value here causes illegal behavior
......@@ -1510,7 +1496,9 @@ const std = @import("std");
15101496// :81:17: error: use of undefined value here causes illegal behavior
15111497// :81:17: note: when computing vector element at index '0'
15121498// :81:17: error: use of undefined value here causes illegal behavior
1499// :81:17: note: when computing vector element at index '0'
15131500// :81:17: error: use of undefined value here causes illegal behavior
1501// :81:17: note: when computing vector element at index '0'
15141502// :81:17: error: use of undefined value here causes illegal behavior
15151503// :81:17: note: when computing vector element at index '0'
15161504// :81:17: error: use of undefined value here causes illegal behavior
......@@ -1520,9 +1508,9 @@ const std = @import("std");
15201508// :81:17: error: use of undefined value here causes illegal behavior
15211509// :81:17: note: when computing vector element at index '0'
15221510// :81:17: error: use of undefined value here causes illegal behavior
1523// :81:17: note: when computing vector element at index '1'
1511// :81:17: note: when computing vector element at index '0'
15241512// :81:17: error: use of undefined value here causes illegal behavior
1525// :81:17: note: when computing vector element at index '1'
1513// :81:17: note: when computing vector element at index '0'
15261514// :81:17: error: use of undefined value here causes illegal behavior
15271515// :81:17: note: when computing vector element at index '0'
15281516// :81:17: error: use of undefined value here causes illegal behavior
......@@ -1532,7 +1520,9 @@ const std = @import("std");
15321520// :81:17: error: use of undefined value here causes illegal behavior
15331521// :81:17: note: when computing vector element at index '0'
15341522// :81:17: error: use of undefined value here causes illegal behavior
1523// :81:17: note: when computing vector element at index '0'
15351524// :81:17: error: use of undefined value here causes illegal behavior
1525// :81:17: note: when computing vector element at index '0'
15361526// :81:17: error: use of undefined value here causes illegal behavior
15371527// :81:17: note: when computing vector element at index '0'
15381528// :81:17: error: use of undefined value here causes illegal behavior
......@@ -1546,35 +1536,45 @@ const std = @import("std");
15461536// :81:17: error: use of undefined value here causes illegal behavior
15471537// :81:17: note: when computing vector element at index '1'
15481538// :81:17: error: use of undefined value here causes illegal behavior
1549// :81:17: note: when computing vector element at index '0'
1539// :81:17: note: when computing vector element at index '1'
15501540// :81:17: error: use of undefined value here causes illegal behavior
1551// :81:17: note: when computing vector element at index '0'
1541// :81:17: note: when computing vector element at index '1'
15521542// :81:17: error: use of undefined value here causes illegal behavior
1553// :81:17: note: when computing vector element at index '0'
1543// :81:17: note: when computing vector element at index '1'
15541544// :81:17: error: use of undefined value here causes illegal behavior
1555// :81:17: note: when computing vector element at index '0'
1545// :81:17: note: when computing vector element at index '1'
15561546// :81:17: error: use of undefined value here causes illegal behavior
1547// :81:17: note: when computing vector element at index '1'
15571548// :81:17: error: use of undefined value here causes illegal behavior
1549// :81:17: note: when computing vector element at index '1'
15581550// :81:17: error: use of undefined value here causes illegal behavior
1559// :81:17: note: when computing vector element at index '0'
1551// :81:17: note: when computing vector element at index '1'
15601552// :81:17: error: use of undefined value here causes illegal behavior
1561// :81:17: note: when computing vector element at index '0'
1553// :81:17: note: when computing vector element at index '1'
15621554// :81:17: error: use of undefined value here causes illegal behavior
1563// :81:17: note: when computing vector element at index '0'
1555// :81:17: note: when computing vector element at index '1'
15641556// :81:17: error: use of undefined value here causes illegal behavior
1565// :81:17: note: when computing vector element at index '0'
1557// :81:17: note: when computing vector element at index '1'
15661558// :81:17: error: use of undefined value here causes illegal behavior
15671559// :81:17: note: when computing vector element at index '1'
15681560// :81:17: error: use of undefined value here causes illegal behavior
15691561// :81:17: note: when computing vector element at index '1'
15701562// :81:17: error: use of undefined value here causes illegal behavior
1571// :81:17: note: when computing vector element at index '0'
1563// :81:17: note: when computing vector element at index '1'
15721564// :81:17: error: use of undefined value here causes illegal behavior
1573// :81:17: note: when computing vector element at index '0'
1565// :81:17: note: when computing vector element at index '1'
15741566// :81:17: error: use of undefined value here causes illegal behavior
1575// :81:17: note: when computing vector element at index '0'
1567// :81:17: note: when computing vector element at index '1'
15761568// :81:17: error: use of undefined value here causes illegal behavior
1577// :81:17: note: when computing vector element at index '0'
1569// :81:17: note: when computing vector element at index '1'
1570// :81:17: error: use of undefined value here causes illegal behavior
1571// :81:17: note: when computing vector element at index '1'
1572// :81:17: error: use of undefined value here causes illegal behavior
1573// :81:17: note: when computing vector element at index '1'
1574// :81:17: error: use of undefined value here causes illegal behavior
1575// :81:17: note: when computing vector element at index '1'
1576// :81:17: error: use of undefined value here causes illegal behavior
1577// :81:17: note: when computing vector element at index '1'
15781578// :81:21: error: use of undefined value here causes illegal behavior
15791579// :81:21: note: when computing vector element at index '0'
15801580// :81:21: error: use of undefined value here causes illegal behavior
......@@ -1622,39 +1622,25 @@ const std = @import("std");
16221622// :85:22: error: use of undefined value here causes illegal behavior
16231623// :85:22: error: use of undefined value here causes illegal behavior
16241624// :85:22: error: use of undefined value here causes illegal behavior
1625// :85:22: note: when computing vector element at index '0'
16261625// :85:22: error: use of undefined value here causes illegal behavior
1627// :85:22: note: when computing vector element at index '0'
16281626// :85:22: error: use of undefined value here causes illegal behavior
1629// :85:22: note: when computing vector element at index '0'
16301627// :85:22: error: use of undefined value here causes illegal behavior
1631// :85:22: note: when computing vector element at index '0'
16321628// :85:22: error: use of undefined value here causes illegal behavior
1633// :85:22: note: when computing vector element at index '1'
16341629// :85:22: error: use of undefined value here causes illegal behavior
1635// :85:22: note: when computing vector element at index '1'
16361630// :85:22: error: use of undefined value here causes illegal behavior
1637// :85:22: note: when computing vector element at index '0'
16381631// :85:22: error: use of undefined value here causes illegal behavior
1639// :85:22: note: when computing vector element at index '0'
16401632// :85:22: error: use of undefined value here causes illegal behavior
1641// :85:22: note: when computing vector element at index '0'
16421633// :85:22: error: use of undefined value here causes illegal behavior
1643// :85:22: note: when computing vector element at index '0'
16441634// :85:22: error: use of undefined value here causes illegal behavior
16451635// :85:22: error: use of undefined value here causes illegal behavior
16461636// :85:22: error: use of undefined value here causes illegal behavior
1647// :85:22: note: when computing vector element at index '0'
16481637// :85:22: error: use of undefined value here causes illegal behavior
1649// :85:22: note: when computing vector element at index '0'
16501638// :85:22: error: use of undefined value here causes illegal behavior
1651// :85:22: note: when computing vector element at index '0'
16521639// :85:22: error: use of undefined value here causes illegal behavior
1653// :85:22: note: when computing vector element at index '0'
16541640// :85:22: error: use of undefined value here causes illegal behavior
1655// :85:22: note: when computing vector element at index '1'
16561641// :85:22: error: use of undefined value here causes illegal behavior
1657// :85:22: note: when computing vector element at index '1'
1642// :85:22: error: use of undefined value here causes illegal behavior
1643// :85:22: error: use of undefined value here causes illegal behavior
16581644// :85:22: error: use of undefined value here causes illegal behavior
16591645// :85:22: note: when computing vector element at index '0'
16601646// :85:22: error: use of undefined value here causes illegal behavior
......@@ -1664,7 +1650,9 @@ const std = @import("std");
16641650// :85:22: error: use of undefined value here causes illegal behavior
16651651// :85:22: note: when computing vector element at index '0'
16661652// :85:22: error: use of undefined value here causes illegal behavior
1653// :85:22: note: when computing vector element at index '0'
16671654// :85:22: error: use of undefined value here causes illegal behavior
1655// :85:22: note: when computing vector element at index '0'
16681656// :85:22: error: use of undefined value here causes illegal behavior
16691657// :85:22: note: when computing vector element at index '0'
16701658// :85:22: error: use of undefined value here causes illegal behavior
......@@ -1674,9 +1662,9 @@ const std = @import("std");
16741662// :85:22: error: use of undefined value here causes illegal behavior
16751663// :85:22: note: when computing vector element at index '0'
16761664// :85:22: error: use of undefined value here causes illegal behavior
1677// :85:22: note: when computing vector element at index '1'
1665// :85:22: note: when computing vector element at index '0'
16781666// :85:22: error: use of undefined value here causes illegal behavior
1679// :85:22: note: when computing vector element at index '1'
1667// :85:22: note: when computing vector element at index '0'
16801668// :85:22: error: use of undefined value here causes illegal behavior
16811669// :85:22: note: when computing vector element at index '0'
16821670// :85:22: error: use of undefined value here causes illegal behavior
......@@ -1686,7 +1674,9 @@ const std = @import("std");
16861674// :85:22: error: use of undefined value here causes illegal behavior
16871675// :85:22: note: when computing vector element at index '0'
16881676// :85:22: error: use of undefined value here causes illegal behavior
1677// :85:22: note: when computing vector element at index '0'
16891678// :85:22: error: use of undefined value here causes illegal behavior
1679// :85:22: note: when computing vector element at index '0'
16901680// :85:22: error: use of undefined value here causes illegal behavior
16911681// :85:22: note: when computing vector element at index '0'
16921682// :85:22: error: use of undefined value here causes illegal behavior
......@@ -1696,9 +1686,9 @@ const std = @import("std");
16961686// :85:22: error: use of undefined value here causes illegal behavior
16971687// :85:22: note: when computing vector element at index '0'
16981688// :85:22: error: use of undefined value here causes illegal behavior
1699// :85:22: note: when computing vector element at index '1'
1689// :85:22: note: when computing vector element at index '0'
17001690// :85:22: error: use of undefined value here causes illegal behavior
1701// :85:22: note: when computing vector element at index '1'
1691// :85:22: note: when computing vector element at index '0'
17021692// :85:22: error: use of undefined value here causes illegal behavior
17031693// :85:22: note: when computing vector element at index '0'
17041694// :85:22: error: use of undefined value here causes illegal behavior
......@@ -1708,7 +1698,9 @@ const std = @import("std");
17081698// :85:22: error: use of undefined value here causes illegal behavior
17091699// :85:22: note: when computing vector element at index '0'
17101700// :85:22: error: use of undefined value here causes illegal behavior
1701// :85:22: note: when computing vector element at index '0'
17111702// :85:22: error: use of undefined value here causes illegal behavior
1703// :85:22: note: when computing vector element at index '0'
17121704// :85:22: error: use of undefined value here causes illegal behavior
17131705// :85:22: note: when computing vector element at index '0'
17141706// :85:22: error: use of undefined value here causes illegal behavior
......@@ -1718,10 +1710,6 @@ const std = @import("std");
17181710// :85:22: error: use of undefined value here causes illegal behavior
17191711// :85:22: note: when computing vector element at index '0'
17201712// :85:22: error: use of undefined value here causes illegal behavior
1721// :85:22: note: when computing vector element at index '1'
1722// :85:22: error: use of undefined value here causes illegal behavior
1723// :85:22: note: when computing vector element at index '1'
1724// :85:22: error: use of undefined value here causes illegal behavior
17251713// :85:22: note: when computing vector element at index '0'
17261714// :85:22: error: use of undefined value here causes illegal behavior
17271715// :85:22: note: when computing vector element at index '0'
......@@ -1730,8 +1718,6 @@ const std = @import("std");
17301718// :85:22: error: use of undefined value here causes illegal behavior
17311719// :85:22: note: when computing vector element at index '0'
17321720// :85:22: error: use of undefined value here causes illegal behavior
1733// :85:22: error: use of undefined value here causes illegal behavior
1734// :85:22: error: use of undefined value here causes illegal behavior
17351721// :85:22: note: when computing vector element at index '0'
17361722// :85:22: error: use of undefined value here causes illegal behavior
17371723// :85:22: note: when computing vector element at index '0'
......@@ -1740,10 +1726,6 @@ const std = @import("std");
17401726// :85:22: error: use of undefined value here causes illegal behavior
17411727// :85:22: note: when computing vector element at index '0'
17421728// :85:22: error: use of undefined value here causes illegal behavior
1743// :85:22: note: when computing vector element at index '1'
1744// :85:22: error: use of undefined value here causes illegal behavior
1745// :85:22: note: when computing vector element at index '1'
1746// :85:22: error: use of undefined value here causes illegal behavior
17471729// :85:22: note: when computing vector element at index '0'
17481730// :85:22: error: use of undefined value here causes illegal behavior
17491731// :85:22: note: when computing vector element at index '0'
......@@ -1752,7 +1734,9 @@ const std = @import("std");
17521734// :85:22: error: use of undefined value here causes illegal behavior
17531735// :85:22: note: when computing vector element at index '0'
17541736// :85:22: error: use of undefined value here causes illegal behavior
1737// :85:22: note: when computing vector element at index '0'
17551738// :85:22: error: use of undefined value here causes illegal behavior
1739// :85:22: note: when computing vector element at index '0'
17561740// :85:22: error: use of undefined value here causes illegal behavior
17571741// :85:22: note: when computing vector element at index '0'
17581742// :85:22: error: use of undefined value here causes illegal behavior
......@@ -1762,9 +1746,9 @@ const std = @import("std");
17621746// :85:22: error: use of undefined value here causes illegal behavior
17631747// :85:22: note: when computing vector element at index '0'
17641748// :85:22: error: use of undefined value here causes illegal behavior
1765// :85:22: note: when computing vector element at index '1'
1749// :85:22: note: when computing vector element at index '0'
17661750// :85:22: error: use of undefined value here causes illegal behavior
1767// :85:22: note: when computing vector element at index '1'
1751// :85:22: note: when computing vector element at index '0'
17681752// :85:22: error: use of undefined value here causes illegal behavior
17691753// :85:22: note: when computing vector element at index '0'
17701754// :85:22: error: use of undefined value here causes illegal behavior
......@@ -1774,7 +1758,9 @@ const std = @import("std");
17741758// :85:22: error: use of undefined value here causes illegal behavior
17751759// :85:22: note: when computing vector element at index '0'
17761760// :85:22: error: use of undefined value here causes illegal behavior
1761// :85:22: note: when computing vector element at index '0'
17771762// :85:22: error: use of undefined value here causes illegal behavior
1763// :85:22: note: when computing vector element at index '0'
17781764// :85:22: error: use of undefined value here causes illegal behavior
17791765// :85:22: note: when computing vector element at index '0'
17801766// :85:22: error: use of undefined value here causes illegal behavior
......@@ -1784,9 +1770,9 @@ const std = @import("std");
17841770// :85:22: error: use of undefined value here causes illegal behavior
17851771// :85:22: note: when computing vector element at index '0'
17861772// :85:22: error: use of undefined value here causes illegal behavior
1787// :85:22: note: when computing vector element at index '1'
1773// :85:22: note: when computing vector element at index '0'
17881774// :85:22: error: use of undefined value here causes illegal behavior
1789// :85:22: note: when computing vector element at index '1'
1775// :85:22: note: when computing vector element at index '0'
17901776// :85:22: error: use of undefined value here causes illegal behavior
17911777// :85:22: note: when computing vector element at index '0'
17921778// :85:22: error: use of undefined value here causes illegal behavior
......@@ -1796,7 +1782,9 @@ const std = @import("std");
17961782// :85:22: error: use of undefined value here causes illegal behavior
17971783// :85:22: note: when computing vector element at index '0'
17981784// :85:22: error: use of undefined value here causes illegal behavior
1785// :85:22: note: when computing vector element at index '0'
17991786// :85:22: error: use of undefined value here causes illegal behavior
1787// :85:22: note: when computing vector element at index '0'
18001788// :85:22: error: use of undefined value here causes illegal behavior
18011789// :85:22: note: when computing vector element at index '0'
18021790// :85:22: error: use of undefined value here causes illegal behavior
......@@ -1806,9 +1794,9 @@ const std = @import("std");
18061794// :85:22: error: use of undefined value here causes illegal behavior
18071795// :85:22: note: when computing vector element at index '0'
18081796// :85:22: error: use of undefined value here causes illegal behavior
1809// :85:22: note: when computing vector element at index '1'
1797// :85:22: note: when computing vector element at index '0'
18101798// :85:22: error: use of undefined value here causes illegal behavior
1811// :85:22: note: when computing vector element at index '1'
1799// :85:22: note: when computing vector element at index '0'
18121800// :85:22: error: use of undefined value here causes illegal behavior
18131801// :85:22: note: when computing vector element at index '0'
18141802// :85:22: error: use of undefined value here causes illegal behavior
......@@ -1818,7 +1806,9 @@ const std = @import("std");
18181806// :85:22: error: use of undefined value here causes illegal behavior
18191807// :85:22: note: when computing vector element at index '0'
18201808// :85:22: error: use of undefined value here causes illegal behavior
1809// :85:22: note: when computing vector element at index '0'
18211810// :85:22: error: use of undefined value here causes illegal behavior
1811// :85:22: note: when computing vector element at index '0'
18221812// :85:22: error: use of undefined value here causes illegal behavior
18231813// :85:22: note: when computing vector element at index '0'
18241814// :85:22: error: use of undefined value here causes illegal behavior
......@@ -1832,35 +1822,45 @@ const std = @import("std");
18321822// :85:22: error: use of undefined value here causes illegal behavior
18331823// :85:22: note: when computing vector element at index '1'
18341824// :85:22: error: use of undefined value here causes illegal behavior
1835// :85:22: note: when computing vector element at index '0'
1825// :85:22: note: when computing vector element at index '1'
18361826// :85:22: error: use of undefined value here causes illegal behavior
1837// :85:22: note: when computing vector element at index '0'
1827// :85:22: note: when computing vector element at index '1'
18381828// :85:22: error: use of undefined value here causes illegal behavior
1839// :85:22: note: when computing vector element at index '0'
1829// :85:22: note: when computing vector element at index '1'
18401830// :85:22: error: use of undefined value here causes illegal behavior
1841// :85:22: note: when computing vector element at index '0'
1831// :85:22: note: when computing vector element at index '1'
18421832// :85:22: error: use of undefined value here causes illegal behavior
1833// :85:22: note: when computing vector element at index '1'
18431834// :85:22: error: use of undefined value here causes illegal behavior
1835// :85:22: note: when computing vector element at index '1'
18441836// :85:22: error: use of undefined value here causes illegal behavior
1845// :85:22: note: when computing vector element at index '0'
1837// :85:22: note: when computing vector element at index '1'
18461838// :85:22: error: use of undefined value here causes illegal behavior
1847// :85:22: note: when computing vector element at index '0'
1839// :85:22: note: when computing vector element at index '1'
18481840// :85:22: error: use of undefined value here causes illegal behavior
1849// :85:22: note: when computing vector element at index '0'
1841// :85:22: note: when computing vector element at index '1'
18501842// :85:22: error: use of undefined value here causes illegal behavior
1851// :85:22: note: when computing vector element at index '0'
1843// :85:22: note: when computing vector element at index '1'
18521844// :85:22: error: use of undefined value here causes illegal behavior
18531845// :85:22: note: when computing vector element at index '1'
18541846// :85:22: error: use of undefined value here causes illegal behavior
18551847// :85:22: note: when computing vector element at index '1'
18561848// :85:22: error: use of undefined value here causes illegal behavior
1857// :85:22: note: when computing vector element at index '0'
1849// :85:22: note: when computing vector element at index '1'
18581850// :85:22: error: use of undefined value here causes illegal behavior
1859// :85:22: note: when computing vector element at index '0'
1851// :85:22: note: when computing vector element at index '1'
18601852// :85:22: error: use of undefined value here causes illegal behavior
1861// :85:22: note: when computing vector element at index '0'
1853// :85:22: note: when computing vector element at index '1'
18621854// :85:22: error: use of undefined value here causes illegal behavior
1863// :85:22: note: when computing vector element at index '0'
1855// :85:22: note: when computing vector element at index '1'
1856// :85:22: error: use of undefined value here causes illegal behavior
1857// :85:22: note: when computing vector element at index '1'
1858// :85:22: error: use of undefined value here causes illegal behavior
1859// :85:22: note: when computing vector element at index '1'
1860// :85:22: error: use of undefined value here causes illegal behavior
1861// :85:22: note: when computing vector element at index '1'
1862// :85:22: error: use of undefined value here causes illegal behavior
1863// :85:22: note: when computing vector element at index '1'
18641864// :85:25: error: use of undefined value here causes illegal behavior
18651865// :85:25: note: when computing vector element at index '0'
18661866// :85:25: error: use of undefined value here causes illegal behavior
......@@ -1908,50 +1908,30 @@ const std = @import("std");
19081908// :89:22: error: use of undefined value here causes illegal behavior
19091909// :89:22: error: use of undefined value here causes illegal behavior
19101910// :89:22: error: use of undefined value here causes illegal behavior
1911// :89:22: note: when computing vector element at index '0'
19121911// :89:22: error: use of undefined value here causes illegal behavior
1913// :89:22: note: when computing vector element at index '0'
19141912// :89:22: error: use of undefined value here causes illegal behavior
1915// :89:22: note: when computing vector element at index '0'
19161913// :89:22: error: use of undefined value here causes illegal behavior
1917// :89:22: note: when computing vector element at index '0'
19181914// :89:22: error: use of undefined value here causes illegal behavior
1919// :89:22: note: when computing vector element at index '1'
19201915// :89:22: error: use of undefined value here causes illegal behavior
1921// :89:22: note: when computing vector element at index '1'
19221916// :89:22: error: use of undefined value here causes illegal behavior
1923// :89:22: note: when computing vector element at index '0'
19241917// :89:22: error: use of undefined value here causes illegal behavior
1925// :89:22: note: when computing vector element at index '0'
19261918// :89:22: error: use of undefined value here causes illegal behavior
1927// :89:22: note: when computing vector element at index '0'
19281919// :89:22: error: use of undefined value here causes illegal behavior
1929// :89:22: note: when computing vector element at index '0'
19301920// :89:22: error: use of undefined value here causes illegal behavior
19311921// :89:22: error: use of undefined value here causes illegal behavior
19321922// :89:22: error: use of undefined value here causes illegal behavior
1933// :89:22: note: when computing vector element at index '0'
19341923// :89:22: error: use of undefined value here causes illegal behavior
1935// :89:22: note: when computing vector element at index '0'
19361924// :89:22: error: use of undefined value here causes illegal behavior
1937// :89:22: note: when computing vector element at index '0'
19381925// :89:22: error: use of undefined value here causes illegal behavior
1939// :89:22: note: when computing vector element at index '0'
19401926// :89:22: error: use of undefined value here causes illegal behavior
1941// :89:22: note: when computing vector element at index '1'
19421927// :89:22: error: use of undefined value here causes illegal behavior
1943// :89:22: note: when computing vector element at index '1'
19441928// :89:22: error: use of undefined value here causes illegal behavior
1945// :89:22: note: when computing vector element at index '0'
19461929// :89:22: error: use of undefined value here causes illegal behavior
1947// :89:22: note: when computing vector element at index '0'
19481930// :89:22: error: use of undefined value here causes illegal behavior
19491931// :89:22: note: when computing vector element at index '0'
19501932// :89:22: error: use of undefined value here causes illegal behavior
19511933// :89:22: note: when computing vector element at index '0'
19521934// :89:22: error: use of undefined value here causes illegal behavior
1953// :89:22: error: use of undefined value here causes illegal behavior
1954// :89:22: error: use of undefined value here causes illegal behavior
19551935// :89:22: note: when computing vector element at index '0'
19561936// :89:22: error: use of undefined value here causes illegal behavior
19571937// :89:22: note: when computing vector element at index '0'
......@@ -1960,10 +1940,6 @@ const std = @import("std");
19601940// :89:22: error: use of undefined value here causes illegal behavior
19611941// :89:22: note: when computing vector element at index '0'
19621942// :89:22: error: use of undefined value here causes illegal behavior
1963// :89:22: note: when computing vector element at index '1'
1964// :89:22: error: use of undefined value here causes illegal behavior
1965// :89:22: note: when computing vector element at index '1'
1966// :89:22: error: use of undefined value here causes illegal behavior
19671943// :89:22: note: when computing vector element at index '0'
19681944// :89:22: error: use of undefined value here causes illegal behavior
19691945// :89:22: note: when computing vector element at index '0'
......@@ -1972,7 +1948,9 @@ const std = @import("std");
19721948// :89:22: error: use of undefined value here causes illegal behavior
19731949// :89:22: note: when computing vector element at index '0'
19741950// :89:22: error: use of undefined value here causes illegal behavior
1951// :89:22: note: when computing vector element at index '0'
19751952// :89:22: error: use of undefined value here causes illegal behavior
1953// :89:22: note: when computing vector element at index '0'
19761954// :89:22: error: use of undefined value here causes illegal behavior
19771955// :89:22: note: when computing vector element at index '0'
19781956// :89:22: error: use of undefined value here causes illegal behavior
......@@ -1982,9 +1960,9 @@ const std = @import("std");
19821960// :89:22: error: use of undefined value here causes illegal behavior
19831961// :89:22: note: when computing vector element at index '0'
19841962// :89:22: error: use of undefined value here causes illegal behavior
1985// :89:22: note: when computing vector element at index '1'
1963// :89:22: note: when computing vector element at index '0'
19861964// :89:22: error: use of undefined value here causes illegal behavior
1987// :89:22: note: when computing vector element at index '1'
1965// :89:22: note: when computing vector element at index '0'
19881966// :89:22: error: use of undefined value here causes illegal behavior
19891967// :89:22: note: when computing vector element at index '0'
19901968// :89:22: error: use of undefined value here causes illegal behavior
......@@ -1994,7 +1972,9 @@ const std = @import("std");
19941972// :89:22: error: use of undefined value here causes illegal behavior
19951973// :89:22: note: when computing vector element at index '0'
19961974// :89:22: error: use of undefined value here causes illegal behavior
1975// :89:22: note: when computing vector element at index '0'
19971976// :89:22: error: use of undefined value here causes illegal behavior
1977// :89:22: note: when computing vector element at index '0'
19981978// :89:22: error: use of undefined value here causes illegal behavior
19991979// :89:22: note: when computing vector element at index '0'
20001980// :89:22: error: use of undefined value here causes illegal behavior
......@@ -2004,9 +1984,9 @@ const std = @import("std");
20041984// :89:22: error: use of undefined value here causes illegal behavior
20051985// :89:22: note: when computing vector element at index '0'
20061986// :89:22: error: use of undefined value here causes illegal behavior
2007// :89:22: note: when computing vector element at index '1'
1987// :89:22: note: when computing vector element at index '0'
20081988// :89:22: error: use of undefined value here causes illegal behavior
2009// :89:22: note: when computing vector element at index '1'
1989// :89:22: note: when computing vector element at index '0'
20101990// :89:22: error: use of undefined value here causes illegal behavior
20111991// :89:22: note: when computing vector element at index '0'
20121992// :89:22: error: use of undefined value here causes illegal behavior
......@@ -2016,7 +1996,9 @@ const std = @import("std");
20161996// :89:22: error: use of undefined value here causes illegal behavior
20171997// :89:22: note: when computing vector element at index '0'
20181998// :89:22: error: use of undefined value here causes illegal behavior
1999// :89:22: note: when computing vector element at index '0'
20192000// :89:22: error: use of undefined value here causes illegal behavior
2001// :89:22: note: when computing vector element at index '0'
20202002// :89:22: error: use of undefined value here causes illegal behavior
20212003// :89:22: note: when computing vector element at index '0'
20222004// :89:22: error: use of undefined value here causes illegal behavior
......@@ -2026,9 +2008,9 @@ const std = @import("std");
20262008// :89:22: error: use of undefined value here causes illegal behavior
20272009// :89:22: note: when computing vector element at index '0'
20282010// :89:22: error: use of undefined value here causes illegal behavior
2029// :89:22: note: when computing vector element at index '1'
2011// :89:22: note: when computing vector element at index '0'
20302012// :89:22: error: use of undefined value here causes illegal behavior
2031// :89:22: note: when computing vector element at index '1'
2013// :89:22: note: when computing vector element at index '0'
20322014// :89:22: error: use of undefined value here causes illegal behavior
20332015// :89:22: note: when computing vector element at index '0'
20342016// :89:22: error: use of undefined value here causes illegal behavior
......@@ -2038,7 +2020,9 @@ const std = @import("std");
20382020// :89:22: error: use of undefined value here causes illegal behavior
20392021// :89:22: note: when computing vector element at index '0'
20402022// :89:22: error: use of undefined value here causes illegal behavior
2023// :89:22: note: when computing vector element at index '0'
20412024// :89:22: error: use of undefined value here causes illegal behavior
2025// :89:22: note: when computing vector element at index '0'
20422026// :89:22: error: use of undefined value here causes illegal behavior
20432027// :89:22: note: when computing vector element at index '0'
20442028// :89:22: error: use of undefined value here causes illegal behavior
......@@ -2048,9 +2032,9 @@ const std = @import("std");
20482032// :89:22: error: use of undefined value here causes illegal behavior
20492033// :89:22: note: when computing vector element at index '0'
20502034// :89:22: error: use of undefined value here causes illegal behavior
2051// :89:22: note: when computing vector element at index '1'
2035// :89:22: note: when computing vector element at index '0'
20522036// :89:22: error: use of undefined value here causes illegal behavior
2053// :89:22: note: when computing vector element at index '1'
2037// :89:22: note: when computing vector element at index '0'
20542038// :89:22: error: use of undefined value here causes illegal behavior
20552039// :89:22: note: when computing vector element at index '0'
20562040// :89:22: error: use of undefined value here causes illegal behavior
......@@ -2060,7 +2044,9 @@ const std = @import("std");
20602044// :89:22: error: use of undefined value here causes illegal behavior
20612045// :89:22: note: when computing vector element at index '0'
20622046// :89:22: error: use of undefined value here causes illegal behavior
2047// :89:22: note: when computing vector element at index '0'
20632048// :89:22: error: use of undefined value here causes illegal behavior
2049// :89:22: note: when computing vector element at index '0'
20642050// :89:22: error: use of undefined value here causes illegal behavior
20652051// :89:22: note: when computing vector element at index '0'
20662052// :89:22: error: use of undefined value here causes illegal behavior
......@@ -2070,9 +2056,9 @@ const std = @import("std");
20702056// :89:22: error: use of undefined value here causes illegal behavior
20712057// :89:22: note: when computing vector element at index '0'
20722058// :89:22: error: use of undefined value here causes illegal behavior
2073// :89:22: note: when computing vector element at index '1'
2059// :89:22: note: when computing vector element at index '0'
20742060// :89:22: error: use of undefined value here causes illegal behavior
2075// :89:22: note: when computing vector element at index '1'
2061// :89:22: note: when computing vector element at index '0'
20762062// :89:22: error: use of undefined value here causes illegal behavior
20772063// :89:22: note: when computing vector element at index '0'
20782064// :89:22: error: use of undefined value here causes illegal behavior
......@@ -2082,7 +2068,9 @@ const std = @import("std");
20822068// :89:22: error: use of undefined value here causes illegal behavior
20832069// :89:22: note: when computing vector element at index '0'
20842070// :89:22: error: use of undefined value here causes illegal behavior
2071// :89:22: note: when computing vector element at index '0'
20852072// :89:22: error: use of undefined value here causes illegal behavior
2073// :89:22: note: when computing vector element at index '0'
20862074// :89:22: error: use of undefined value here causes illegal behavior
20872075// :89:22: note: when computing vector element at index '0'
20882076// :89:22: error: use of undefined value here causes illegal behavior
......@@ -2092,9 +2080,9 @@ const std = @import("std");
20922080// :89:22: error: use of undefined value here causes illegal behavior
20932081// :89:22: note: when computing vector element at index '0'
20942082// :89:22: error: use of undefined value here causes illegal behavior
2095// :89:22: note: when computing vector element at index '1'
2083// :89:22: note: when computing vector element at index '0'
20962084// :89:22: error: use of undefined value here causes illegal behavior
2097// :89:22: note: when computing vector element at index '1'
2085// :89:22: note: when computing vector element at index '0'
20982086// :89:22: error: use of undefined value here causes illegal behavior
20992087// :89:22: note: when computing vector element at index '0'
21002088// :89:22: error: use of undefined value here causes illegal behavior
......@@ -2104,7 +2092,9 @@ const std = @import("std");
21042092// :89:22: error: use of undefined value here causes illegal behavior
21052093// :89:22: note: when computing vector element at index '0'
21062094// :89:22: error: use of undefined value here causes illegal behavior
2095// :89:22: note: when computing vector element at index '0'
21072096// :89:22: error: use of undefined value here causes illegal behavior
2097// :89:22: note: when computing vector element at index '0'
21082098// :89:22: error: use of undefined value here causes illegal behavior
21092099// :89:22: note: when computing vector element at index '0'
21102100// :89:22: error: use of undefined value here causes illegal behavior
......@@ -2118,35 +2108,45 @@ const std = @import("std");
21182108// :89:22: error: use of undefined value here causes illegal behavior
21192109// :89:22: note: when computing vector element at index '1'
21202110// :89:22: error: use of undefined value here causes illegal behavior
2121// :89:22: note: when computing vector element at index '0'
2111// :89:22: note: when computing vector element at index '1'
21222112// :89:22: error: use of undefined value here causes illegal behavior
2123// :89:22: note: when computing vector element at index '0'
2113// :89:22: note: when computing vector element at index '1'
21242114// :89:22: error: use of undefined value here causes illegal behavior
2125// :89:22: note: when computing vector element at index '0'
2115// :89:22: note: when computing vector element at index '1'
21262116// :89:22: error: use of undefined value here causes illegal behavior
2127// :89:22: note: when computing vector element at index '0'
2117// :89:22: note: when computing vector element at index '1'
21282118// :89:22: error: use of undefined value here causes illegal behavior
2119// :89:22: note: when computing vector element at index '1'
21292120// :89:22: error: use of undefined value here causes illegal behavior
2121// :89:22: note: when computing vector element at index '1'
21302122// :89:22: error: use of undefined value here causes illegal behavior
2131// :89:22: note: when computing vector element at index '0'
2123// :89:22: note: when computing vector element at index '1'
21322124// :89:22: error: use of undefined value here causes illegal behavior
2133// :89:22: note: when computing vector element at index '0'
2125// :89:22: note: when computing vector element at index '1'
21342126// :89:22: error: use of undefined value here causes illegal behavior
2135// :89:22: note: when computing vector element at index '0'
2127// :89:22: note: when computing vector element at index '1'
21362128// :89:22: error: use of undefined value here causes illegal behavior
2137// :89:22: note: when computing vector element at index '0'
2129// :89:22: note: when computing vector element at index '1'
21382130// :89:22: error: use of undefined value here causes illegal behavior
21392131// :89:22: note: when computing vector element at index '1'
21402132// :89:22: error: use of undefined value here causes illegal behavior
21412133// :89:22: note: when computing vector element at index '1'
21422134// :89:22: error: use of undefined value here causes illegal behavior
2143// :89:22: note: when computing vector element at index '0'
2135// :89:22: note: when computing vector element at index '1'
21442136// :89:22: error: use of undefined value here causes illegal behavior
2145// :89:22: note: when computing vector element at index '0'
2137// :89:22: note: when computing vector element at index '1'
21462138// :89:22: error: use of undefined value here causes illegal behavior
2147// :89:22: note: when computing vector element at index '0'
2139// :89:22: note: when computing vector element at index '1'
21482140// :89:22: error: use of undefined value here causes illegal behavior
2149// :89:22: note: when computing vector element at index '0'
2141// :89:22: note: when computing vector element at index '1'
2142// :89:22: error: use of undefined value here causes illegal behavior
2143// :89:22: note: when computing vector element at index '1'
2144// :89:22: error: use of undefined value here causes illegal behavior
2145// :89:22: note: when computing vector element at index '1'
2146// :89:22: error: use of undefined value here causes illegal behavior
2147// :89:22: note: when computing vector element at index '1'
2148// :89:22: error: use of undefined value here causes illegal behavior
2149// :89:22: note: when computing vector element at index '1'
21502150// :89:25: error: use of undefined value here causes illegal behavior
21512151// :89:25: note: when computing vector element at index '0'
21522152// :89:25: error: use of undefined value here causes illegal behavior
......@@ -2198,21 +2198,13 @@ const std = @import("std");
21982198// :95:17: error: use of undefined value here causes illegal behavior
21992199// :95:17: error: use of undefined value here causes illegal behavior
22002200// :95:17: error: use of undefined value here causes illegal behavior
2201// :95:17: note: when computing vector element at index '1'
22022201// :95:17: error: use of undefined value here causes illegal behavior
2203// :95:17: note: when computing vector element at index '1'
22042202// :95:17: error: use of undefined value here causes illegal behavior
2205// :95:17: note: when computing vector element at index '1'
22062203// :95:17: error: use of undefined value here causes illegal behavior
2207// :95:17: note: when computing vector element at index '1'
22082204// :95:17: error: use of undefined value here causes illegal behavior
2209// :95:17: note: when computing vector element at index '0'
22102205// :95:17: error: use of undefined value here causes illegal behavior
2211// :95:17: note: when computing vector element at index '0'
22122206// :95:17: error: use of undefined value here causes illegal behavior
2213// :95:17: note: when computing vector element at index '0'
22142207// :95:17: error: use of undefined value here causes illegal behavior
2215// :95:17: note: when computing vector element at index '0'
22162208// :95:17: error: use of undefined value here causes illegal behavior
22172209// :95:17: error: use of undefined value here causes illegal behavior
22182210// :95:17: error: use of undefined value here causes illegal behavior
......@@ -2220,21 +2212,13 @@ const std = @import("std");
22202212// :95:17: error: use of undefined value here causes illegal behavior
22212213// :95:17: error: use of undefined value here causes illegal behavior
22222214// :95:17: error: use of undefined value here causes illegal behavior
2223// :95:17: note: when computing vector element at index '1'
22242215// :95:17: error: use of undefined value here causes illegal behavior
2225// :95:17: note: when computing vector element at index '1'
22262216// :95:17: error: use of undefined value here causes illegal behavior
2227// :95:17: note: when computing vector element at index '1'
22282217// :95:17: error: use of undefined value here causes illegal behavior
2229// :95:17: note: when computing vector element at index '1'
22302218// :95:17: error: use of undefined value here causes illegal behavior
2231// :95:17: note: when computing vector element at index '0'
22322219// :95:17: error: use of undefined value here causes illegal behavior
2233// :95:17: note: when computing vector element at index '0'
22342220// :95:17: error: use of undefined value here causes illegal behavior
2235// :95:17: note: when computing vector element at index '0'
22362221// :95:17: error: use of undefined value here causes illegal behavior
2237// :95:17: note: when computing vector element at index '0'
22382222// :95:17: error: use of undefined value here causes illegal behavior
22392223// :95:17: error: use of undefined value here causes illegal behavior
22402224// :95:17: error: use of undefined value here causes illegal behavior
......@@ -2242,21 +2226,13 @@ const std = @import("std");
22422226// :95:17: error: use of undefined value here causes illegal behavior
22432227// :95:17: error: use of undefined value here causes illegal behavior
22442228// :95:17: error: use of undefined value here causes illegal behavior
2245// :95:17: note: when computing vector element at index '1'
22462229// :95:17: error: use of undefined value here causes illegal behavior
2247// :95:17: note: when computing vector element at index '1'
22482230// :95:17: error: use of undefined value here causes illegal behavior
2249// :95:17: note: when computing vector element at index '1'
22502231// :95:17: error: use of undefined value here causes illegal behavior
2251// :95:17: note: when computing vector element at index '1'
22522232// :95:17: error: use of undefined value here causes illegal behavior
2253// :95:17: note: when computing vector element at index '0'
22542233// :95:17: error: use of undefined value here causes illegal behavior
2255// :95:17: note: when computing vector element at index '0'
22562234// :95:17: error: use of undefined value here causes illegal behavior
2257// :95:17: note: when computing vector element at index '0'
22582235// :95:17: error: use of undefined value here causes illegal behavior
2259// :95:17: note: when computing vector element at index '0'
22602236// :95:17: error: use of undefined value here causes illegal behavior
22612237// :95:17: error: use of undefined value here causes illegal behavior
22622238// :95:17: error: use of undefined value here causes illegal behavior
......@@ -2264,21 +2240,13 @@ const std = @import("std");
22642240// :95:17: error: use of undefined value here causes illegal behavior
22652241// :95:17: error: use of undefined value here causes illegal behavior
22662242// :95:17: error: use of undefined value here causes illegal behavior
2267// :95:17: note: when computing vector element at index '1'
22682243// :95:17: error: use of undefined value here causes illegal behavior
2269// :95:17: note: when computing vector element at index '1'
22702244// :95:17: error: use of undefined value here causes illegal behavior
2271// :95:17: note: when computing vector element at index '1'
22722245// :95:17: error: use of undefined value here causes illegal behavior
2273// :95:17: note: when computing vector element at index '1'
22742246// :95:17: error: use of undefined value here causes illegal behavior
2275// :95:17: note: when computing vector element at index '0'
22762247// :95:17: error: use of undefined value here causes illegal behavior
2277// :95:17: note: when computing vector element at index '0'
22782248// :95:17: error: use of undefined value here causes illegal behavior
2279// :95:17: note: when computing vector element at index '0'
22802249// :95:17: error: use of undefined value here causes illegal behavior
2281// :95:17: note: when computing vector element at index '0'
22822250// :95:17: error: use of undefined value here causes illegal behavior
22832251// :95:17: error: use of undefined value here causes illegal behavior
22842252// :95:17: error: use of undefined value here causes illegal behavior
......@@ -2286,13 +2254,9 @@ const std = @import("std");
22862254// :95:17: error: use of undefined value here causes illegal behavior
22872255// :95:17: error: use of undefined value here causes illegal behavior
22882256// :95:17: error: use of undefined value here causes illegal behavior
2289// :95:17: note: when computing vector element at index '1'
22902257// :95:17: error: use of undefined value here causes illegal behavior
2291// :95:17: note: when computing vector element at index '1'
22922258// :95:17: error: use of undefined value here causes illegal behavior
2293// :95:17: note: when computing vector element at index '1'
22942259// :95:17: error: use of undefined value here causes illegal behavior
2295// :95:17: note: when computing vector element at index '1'
22962260// :95:17: error: use of undefined value here causes illegal behavior
22972261// :95:17: note: when computing vector element at index '0'
22982262// :95:17: error: use of undefined value here causes illegal behavior
......@@ -2302,19 +2266,21 @@ const std = @import("std");
23022266// :95:17: error: use of undefined value here causes illegal behavior
23032267// :95:17: note: when computing vector element at index '0'
23042268// :95:17: error: use of undefined value here causes illegal behavior
2269// :95:17: note: when computing vector element at index '0'
23052270// :95:17: error: use of undefined value here causes illegal behavior
2271// :95:17: note: when computing vector element at index '0'
23062272// :95:17: error: use of undefined value here causes illegal behavior
2273// :95:17: note: when computing vector element at index '0'
23072274// :95:17: error: use of undefined value here causes illegal behavior
2275// :95:17: note: when computing vector element at index '0'
23082276// :95:17: error: use of undefined value here causes illegal behavior
2277// :95:17: note: when computing vector element at index '0'
23092278// :95:17: error: use of undefined value here causes illegal behavior
2279// :95:17: note: when computing vector element at index '0'
23102280// :95:17: error: use of undefined value here causes illegal behavior
2311// :95:17: note: when computing vector element at index '1'
2312// :95:17: error: use of undefined value here causes illegal behavior
2313// :95:17: note: when computing vector element at index '1'
2314// :95:17: error: use of undefined value here causes illegal behavior
2315// :95:17: note: when computing vector element at index '1'
2281// :95:17: note: when computing vector element at index '0'
23162282// :95:17: error: use of undefined value here causes illegal behavior
2317// :95:17: note: when computing vector element at index '1'
2283// :95:17: note: when computing vector element at index '0'
23182284// :95:17: error: use of undefined value here causes illegal behavior
23192285// :95:17: note: when computing vector element at index '0'
23202286// :95:17: error: use of undefined value here causes illegal behavior
......@@ -2324,19 +2290,25 @@ const std = @import("std");
23242290// :95:17: error: use of undefined value here causes illegal behavior
23252291// :95:17: note: when computing vector element at index '0'
23262292// :95:17: error: use of undefined value here causes illegal behavior
2293// :95:17: note: when computing vector element at index '0'
23272294// :95:17: error: use of undefined value here causes illegal behavior
2295// :95:17: note: when computing vector element at index '0'
23282296// :95:17: error: use of undefined value here causes illegal behavior
2297// :95:17: note: when computing vector element at index '0'
23292298// :95:17: error: use of undefined value here causes illegal behavior
2299// :95:17: note: when computing vector element at index '0'
23302300// :95:17: error: use of undefined value here causes illegal behavior
2301// :95:17: note: when computing vector element at index '0'
23312302// :95:17: error: use of undefined value here causes illegal behavior
2303// :95:17: note: when computing vector element at index '0'
23322304// :95:17: error: use of undefined value here causes illegal behavior
2333// :95:17: note: when computing vector element at index '1'
2305// :95:17: note: when computing vector element at index '0'
23342306// :95:17: error: use of undefined value here causes illegal behavior
2335// :95:17: note: when computing vector element at index '1'
2307// :95:17: note: when computing vector element at index '0'
23362308// :95:17: error: use of undefined value here causes illegal behavior
2337// :95:17: note: when computing vector element at index '1'
2309// :95:17: note: when computing vector element at index '0'
23382310// :95:17: error: use of undefined value here causes illegal behavior
2339// :95:17: note: when computing vector element at index '1'
2311// :95:17: note: when computing vector element at index '0'
23402312// :95:17: error: use of undefined value here causes illegal behavior
23412313// :95:17: note: when computing vector element at index '0'
23422314// :95:17: error: use of undefined value here causes illegal behavior
......@@ -2346,19 +2318,25 @@ const std = @import("std");
23462318// :95:17: error: use of undefined value here causes illegal behavior
23472319// :95:17: note: when computing vector element at index '0'
23482320// :95:17: error: use of undefined value here causes illegal behavior
2321// :95:17: note: when computing vector element at index '0'
23492322// :95:17: error: use of undefined value here causes illegal behavior
2323// :95:17: note: when computing vector element at index '0'
23502324// :95:17: error: use of undefined value here causes illegal behavior
2325// :95:17: note: when computing vector element at index '0'
23512326// :95:17: error: use of undefined value here causes illegal behavior
2327// :95:17: note: when computing vector element at index '0'
23522328// :95:17: error: use of undefined value here causes illegal behavior
2329// :95:17: note: when computing vector element at index '0'
23532330// :95:17: error: use of undefined value here causes illegal behavior
2331// :95:17: note: when computing vector element at index '0'
23542332// :95:17: error: use of undefined value here causes illegal behavior
2355// :95:17: note: when computing vector element at index '1'
2333// :95:17: note: when computing vector element at index '0'
23562334// :95:17: error: use of undefined value here causes illegal behavior
2357// :95:17: note: when computing vector element at index '1'
2335// :95:17: note: when computing vector element at index '0'
23582336// :95:17: error: use of undefined value here causes illegal behavior
2359// :95:17: note: when computing vector element at index '1'
2337// :95:17: note: when computing vector element at index '0'
23602338// :95:17: error: use of undefined value here causes illegal behavior
2361// :95:17: note: when computing vector element at index '1'
2339// :95:17: note: when computing vector element at index '0'
23622340// :95:17: error: use of undefined value here causes illegal behavior
23632341// :95:17: note: when computing vector element at index '0'
23642342// :95:17: error: use of undefined value here causes illegal behavior
......@@ -2368,11 +2346,17 @@ const std = @import("std");
23682346// :95:17: error: use of undefined value here causes illegal behavior
23692347// :95:17: note: when computing vector element at index '0'
23702348// :95:17: error: use of undefined value here causes illegal behavior
2349// :95:17: note: when computing vector element at index '1'
23712350// :95:17: error: use of undefined value here causes illegal behavior
2351// :95:17: note: when computing vector element at index '1'
23722352// :95:17: error: use of undefined value here causes illegal behavior
2353// :95:17: note: when computing vector element at index '1'
23732354// :95:17: error: use of undefined value here causes illegal behavior
2355// :95:17: note: when computing vector element at index '1'
23742356// :95:17: error: use of undefined value here causes illegal behavior
2357// :95:17: note: when computing vector element at index '1'
23752358// :95:17: error: use of undefined value here causes illegal behavior
2359// :95:17: note: when computing vector element at index '1'
23762360// :95:17: error: use of undefined value here causes illegal behavior
23772361// :95:17: note: when computing vector element at index '1'
23782362// :95:17: error: use of undefined value here causes illegal behavior
......@@ -2382,19 +2366,25 @@ const std = @import("std");
23822366// :95:17: error: use of undefined value here causes illegal behavior
23832367// :95:17: note: when computing vector element at index '1'
23842368// :95:17: error: use of undefined value here causes illegal behavior
2385// :95:17: note: when computing vector element at index '0'
2369// :95:17: note: when computing vector element at index '1'
23862370// :95:17: error: use of undefined value here causes illegal behavior
2387// :95:17: note: when computing vector element at index '0'
2371// :95:17: note: when computing vector element at index '1'
23882372// :95:17: error: use of undefined value here causes illegal behavior
2389// :95:17: note: when computing vector element at index '0'
2373// :95:17: note: when computing vector element at index '1'
23902374// :95:17: error: use of undefined value here causes illegal behavior
2391// :95:17: note: when computing vector element at index '0'
2375// :95:17: note: when computing vector element at index '1'
23922376// :95:17: error: use of undefined value here causes illegal behavior
2377// :95:17: note: when computing vector element at index '1'
23932378// :95:17: error: use of undefined value here causes illegal behavior
2379// :95:17: note: when computing vector element at index '1'
23942380// :95:17: error: use of undefined value here causes illegal behavior
2381// :95:17: note: when computing vector element at index '1'
23952382// :95:17: error: use of undefined value here causes illegal behavior
2383// :95:17: note: when computing vector element at index '1'
23962384// :95:17: error: use of undefined value here causes illegal behavior
2385// :95:17: note: when computing vector element at index '1'
23972386// :95:17: error: use of undefined value here causes illegal behavior
2387// :95:17: note: when computing vector element at index '1'
23982388// :95:17: error: use of undefined value here causes illegal behavior
23992389// :95:17: note: when computing vector element at index '1'
24002390// :95:17: error: use of undefined value here causes illegal behavior
......@@ -2404,19 +2394,25 @@ const std = @import("std");
24042394// :95:17: error: use of undefined value here causes illegal behavior
24052395// :95:17: note: when computing vector element at index '1'
24062396// :95:17: error: use of undefined value here causes illegal behavior
2407// :95:17: note: when computing vector element at index '0'
2397// :95:17: note: when computing vector element at index '1'
24082398// :95:17: error: use of undefined value here causes illegal behavior
2409// :95:17: note: when computing vector element at index '0'
2399// :95:17: note: when computing vector element at index '1'
24102400// :95:17: error: use of undefined value here causes illegal behavior
2411// :95:17: note: when computing vector element at index '0'
2401// :95:17: note: when computing vector element at index '1'
24122402// :95:17: error: use of undefined value here causes illegal behavior
2413// :95:17: note: when computing vector element at index '0'
2403// :95:17: note: when computing vector element at index '1'
24142404// :95:17: error: use of undefined value here causes illegal behavior
2405// :95:17: note: when computing vector element at index '1'
24152406// :95:17: error: use of undefined value here causes illegal behavior
2407// :95:17: note: when computing vector element at index '1'
24162408// :95:17: error: use of undefined value here causes illegal behavior
2409// :95:17: note: when computing vector element at index '1'
24172410// :95:17: error: use of undefined value here causes illegal behavior
2411// :95:17: note: when computing vector element at index '1'
24182412// :95:17: error: use of undefined value here causes illegal behavior
2413// :95:17: note: when computing vector element at index '1'
24192414// :95:17: error: use of undefined value here causes illegal behavior
2415// :95:17: note: when computing vector element at index '1'
24202416// :95:17: error: use of undefined value here causes illegal behavior
24212417// :95:17: note: when computing vector element at index '1'
24222418// :95:17: error: use of undefined value here causes illegal behavior
......@@ -2426,13 +2422,17 @@ const std = @import("std");
24262422// :95:17: error: use of undefined value here causes illegal behavior
24272423// :95:17: note: when computing vector element at index '1'
24282424// :95:17: error: use of undefined value here causes illegal behavior
2429// :95:17: note: when computing vector element at index '0'
2425// :95:17: note: when computing vector element at index '1'
24302426// :95:17: error: use of undefined value here causes illegal behavior
2431// :95:17: note: when computing vector element at index '0'
2427// :95:17: note: when computing vector element at index '1'
24322428// :95:17: error: use of undefined value here causes illegal behavior
2433// :95:17: note: when computing vector element at index '0'
2429// :95:17: note: when computing vector element at index '1'
24342430// :95:17: error: use of undefined value here causes illegal behavior
2435// :95:17: note: when computing vector element at index '0'
2431// :95:17: note: when computing vector element at index '1'
2432// :95:17: error: use of undefined value here causes illegal behavior
2433// :95:17: note: when computing vector element at index '1'
2434// :95:17: error: use of undefined value here causes illegal behavior
2435// :95:17: note: when computing vector element at index '1'
24362436// :99:27: error: use of undefined value here causes illegal behavior
24372437// :99:27: error: use of undefined value here causes illegal behavior
24382438// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2440,21 +2440,13 @@ const std = @import("std");
24402440// :99:27: error: use of undefined value here causes illegal behavior
24412441// :99:27: error: use of undefined value here causes illegal behavior
24422442// :99:27: error: use of undefined value here causes illegal behavior
2443// :99:27: note: when computing vector element at index '1'
24442443// :99:27: error: use of undefined value here causes illegal behavior
2445// :99:27: note: when computing vector element at index '1'
24462444// :99:27: error: use of undefined value here causes illegal behavior
2447// :99:27: note: when computing vector element at index '1'
24482445// :99:27: error: use of undefined value here causes illegal behavior
2449// :99:27: note: when computing vector element at index '1'
24502446// :99:27: error: use of undefined value here causes illegal behavior
2451// :99:27: note: when computing vector element at index '0'
24522447// :99:27: error: use of undefined value here causes illegal behavior
2453// :99:27: note: when computing vector element at index '0'
24542448// :99:27: error: use of undefined value here causes illegal behavior
2455// :99:27: note: when computing vector element at index '0'
24562449// :99:27: error: use of undefined value here causes illegal behavior
2457// :99:27: note: when computing vector element at index '0'
24582450// :99:27: error: use of undefined value here causes illegal behavior
24592451// :99:27: error: use of undefined value here causes illegal behavior
24602452// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2462,21 +2454,13 @@ const std = @import("std");
24622454// :99:27: error: use of undefined value here causes illegal behavior
24632455// :99:27: error: use of undefined value here causes illegal behavior
24642456// :99:27: error: use of undefined value here causes illegal behavior
2465// :99:27: note: when computing vector element at index '1'
24662457// :99:27: error: use of undefined value here causes illegal behavior
2467// :99:27: note: when computing vector element at index '1'
24682458// :99:27: error: use of undefined value here causes illegal behavior
2469// :99:27: note: when computing vector element at index '1'
24702459// :99:27: error: use of undefined value here causes illegal behavior
2471// :99:27: note: when computing vector element at index '1'
24722460// :99:27: error: use of undefined value here causes illegal behavior
2473// :99:27: note: when computing vector element at index '0'
24742461// :99:27: error: use of undefined value here causes illegal behavior
2475// :99:27: note: when computing vector element at index '0'
24762462// :99:27: error: use of undefined value here causes illegal behavior
2477// :99:27: note: when computing vector element at index '0'
24782463// :99:27: error: use of undefined value here causes illegal behavior
2479// :99:27: note: when computing vector element at index '0'
24802464// :99:27: error: use of undefined value here causes illegal behavior
24812465// :99:27: error: use of undefined value here causes illegal behavior
24822466// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2484,21 +2468,13 @@ const std = @import("std");
24842468// :99:27: error: use of undefined value here causes illegal behavior
24852469// :99:27: error: use of undefined value here causes illegal behavior
24862470// :99:27: error: use of undefined value here causes illegal behavior
2487// :99:27: note: when computing vector element at index '1'
24882471// :99:27: error: use of undefined value here causes illegal behavior
2489// :99:27: note: when computing vector element at index '1'
24902472// :99:27: error: use of undefined value here causes illegal behavior
2491// :99:27: note: when computing vector element at index '1'
24922473// :99:27: error: use of undefined value here causes illegal behavior
2493// :99:27: note: when computing vector element at index '1'
24942474// :99:27: error: use of undefined value here causes illegal behavior
2495// :99:27: note: when computing vector element at index '0'
24962475// :99:27: error: use of undefined value here causes illegal behavior
2497// :99:27: note: when computing vector element at index '0'
24982476// :99:27: error: use of undefined value here causes illegal behavior
2499// :99:27: note: when computing vector element at index '0'
25002477// :99:27: error: use of undefined value here causes illegal behavior
2501// :99:27: note: when computing vector element at index '0'
25022478// :99:27: error: use of undefined value here causes illegal behavior
25032479// :99:27: error: use of undefined value here causes illegal behavior
25042480// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2506,21 +2482,13 @@ const std = @import("std");
25062482// :99:27: error: use of undefined value here causes illegal behavior
25072483// :99:27: error: use of undefined value here causes illegal behavior
25082484// :99:27: error: use of undefined value here causes illegal behavior
2509// :99:27: note: when computing vector element at index '1'
25102485// :99:27: error: use of undefined value here causes illegal behavior
2511// :99:27: note: when computing vector element at index '1'
25122486// :99:27: error: use of undefined value here causes illegal behavior
2513// :99:27: note: when computing vector element at index '1'
25142487// :99:27: error: use of undefined value here causes illegal behavior
2515// :99:27: note: when computing vector element at index '1'
25162488// :99:27: error: use of undefined value here causes illegal behavior
2517// :99:27: note: when computing vector element at index '0'
25182489// :99:27: error: use of undefined value here causes illegal behavior
2519// :99:27: note: when computing vector element at index '0'
25202490// :99:27: error: use of undefined value here causes illegal behavior
2521// :99:27: note: when computing vector element at index '0'
25222491// :99:27: error: use of undefined value here causes illegal behavior
2523// :99:27: note: when computing vector element at index '0'
25242492// :99:27: error: use of undefined value here causes illegal behavior
25252493// :99:27: error: use of undefined value here causes illegal behavior
25262494// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2528,13 +2496,9 @@ const std = @import("std");
25282496// :99:27: error: use of undefined value here causes illegal behavior
25292497// :99:27: error: use of undefined value here causes illegal behavior
25302498// :99:27: error: use of undefined value here causes illegal behavior
2531// :99:27: note: when computing vector element at index '1'
25322499// :99:27: error: use of undefined value here causes illegal behavior
2533// :99:27: note: when computing vector element at index '1'
25342500// :99:27: error: use of undefined value here causes illegal behavior
2535// :99:27: note: when computing vector element at index '1'
25362501// :99:27: error: use of undefined value here causes illegal behavior
2537// :99:27: note: when computing vector element at index '1'
25382502// :99:27: error: use of undefined value here causes illegal behavior
25392503// :99:27: note: when computing vector element at index '0'
25402504// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2544,19 +2508,21 @@ const std = @import("std");
25442508// :99:27: error: use of undefined value here causes illegal behavior
25452509// :99:27: note: when computing vector element at index '0'
25462510// :99:27: error: use of undefined value here causes illegal behavior
2511// :99:27: note: when computing vector element at index '0'
25472512// :99:27: error: use of undefined value here causes illegal behavior
2513// :99:27: note: when computing vector element at index '0'
25482514// :99:27: error: use of undefined value here causes illegal behavior
2515// :99:27: note: when computing vector element at index '0'
25492516// :99:27: error: use of undefined value here causes illegal behavior
2517// :99:27: note: when computing vector element at index '0'
25502518// :99:27: error: use of undefined value here causes illegal behavior
2519// :99:27: note: when computing vector element at index '0'
25512520// :99:27: error: use of undefined value here causes illegal behavior
2521// :99:27: note: when computing vector element at index '0'
25522522// :99:27: error: use of undefined value here causes illegal behavior
2553// :99:27: note: when computing vector element at index '1'
2554// :99:27: error: use of undefined value here causes illegal behavior
2555// :99:27: note: when computing vector element at index '1'
2556// :99:27: error: use of undefined value here causes illegal behavior
2557// :99:27: note: when computing vector element at index '1'
2523// :99:27: note: when computing vector element at index '0'
25582524// :99:27: error: use of undefined value here causes illegal behavior
2559// :99:27: note: when computing vector element at index '1'
2525// :99:27: note: when computing vector element at index '0'
25602526// :99:27: error: use of undefined value here causes illegal behavior
25612527// :99:27: note: when computing vector element at index '0'
25622528// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2566,19 +2532,25 @@ const std = @import("std");
25662532// :99:27: error: use of undefined value here causes illegal behavior
25672533// :99:27: note: when computing vector element at index '0'
25682534// :99:27: error: use of undefined value here causes illegal behavior
2535// :99:27: note: when computing vector element at index '0'
25692536// :99:27: error: use of undefined value here causes illegal behavior
2537// :99:27: note: when computing vector element at index '0'
25702538// :99:27: error: use of undefined value here causes illegal behavior
2539// :99:27: note: when computing vector element at index '0'
25712540// :99:27: error: use of undefined value here causes illegal behavior
2541// :99:27: note: when computing vector element at index '0'
25722542// :99:27: error: use of undefined value here causes illegal behavior
2543// :99:27: note: when computing vector element at index '0'
25732544// :99:27: error: use of undefined value here causes illegal behavior
2545// :99:27: note: when computing vector element at index '0'
25742546// :99:27: error: use of undefined value here causes illegal behavior
2575// :99:27: note: when computing vector element at index '1'
2547// :99:27: note: when computing vector element at index '0'
25762548// :99:27: error: use of undefined value here causes illegal behavior
2577// :99:27: note: when computing vector element at index '1'
2549// :99:27: note: when computing vector element at index '0'
25782550// :99:27: error: use of undefined value here causes illegal behavior
2579// :99:27: note: when computing vector element at index '1'
2551// :99:27: note: when computing vector element at index '0'
25802552// :99:27: error: use of undefined value here causes illegal behavior
2581// :99:27: note: when computing vector element at index '1'
2553// :99:27: note: when computing vector element at index '0'
25822554// :99:27: error: use of undefined value here causes illegal behavior
25832555// :99:27: note: when computing vector element at index '0'
25842556// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2588,19 +2560,25 @@ const std = @import("std");
25882560// :99:27: error: use of undefined value here causes illegal behavior
25892561// :99:27: note: when computing vector element at index '0'
25902562// :99:27: error: use of undefined value here causes illegal behavior
2563// :99:27: note: when computing vector element at index '0'
25912564// :99:27: error: use of undefined value here causes illegal behavior
2565// :99:27: note: when computing vector element at index '0'
25922566// :99:27: error: use of undefined value here causes illegal behavior
2567// :99:27: note: when computing vector element at index '0'
25932568// :99:27: error: use of undefined value here causes illegal behavior
2569// :99:27: note: when computing vector element at index '0'
25942570// :99:27: error: use of undefined value here causes illegal behavior
2571// :99:27: note: when computing vector element at index '0'
25952572// :99:27: error: use of undefined value here causes illegal behavior
2573// :99:27: note: when computing vector element at index '0'
25962574// :99:27: error: use of undefined value here causes illegal behavior
2597// :99:27: note: when computing vector element at index '1'
2575// :99:27: note: when computing vector element at index '0'
25982576// :99:27: error: use of undefined value here causes illegal behavior
2599// :99:27: note: when computing vector element at index '1'
2577// :99:27: note: when computing vector element at index '0'
26002578// :99:27: error: use of undefined value here causes illegal behavior
2601// :99:27: note: when computing vector element at index '1'
2579// :99:27: note: when computing vector element at index '0'
26022580// :99:27: error: use of undefined value here causes illegal behavior
2603// :99:27: note: when computing vector element at index '1'
2581// :99:27: note: when computing vector element at index '0'
26042582// :99:27: error: use of undefined value here causes illegal behavior
26052583// :99:27: note: when computing vector element at index '0'
26062584// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2610,11 +2588,17 @@ const std = @import("std");
26102588// :99:27: error: use of undefined value here causes illegal behavior
26112589// :99:27: note: when computing vector element at index '0'
26122590// :99:27: error: use of undefined value here causes illegal behavior
2591// :99:27: note: when computing vector element at index '1'
26132592// :99:27: error: use of undefined value here causes illegal behavior
2593// :99:27: note: when computing vector element at index '1'
26142594// :99:27: error: use of undefined value here causes illegal behavior
2595// :99:27: note: when computing vector element at index '1'
26152596// :99:27: error: use of undefined value here causes illegal behavior
2597// :99:27: note: when computing vector element at index '1'
26162598// :99:27: error: use of undefined value here causes illegal behavior
2599// :99:27: note: when computing vector element at index '1'
26172600// :99:27: error: use of undefined value here causes illegal behavior
2601// :99:27: note: when computing vector element at index '1'
26182602// :99:27: error: use of undefined value here causes illegal behavior
26192603// :99:27: note: when computing vector element at index '1'
26202604// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2624,19 +2608,25 @@ const std = @import("std");
26242608// :99:27: error: use of undefined value here causes illegal behavior
26252609// :99:27: note: when computing vector element at index '1'
26262610// :99:27: error: use of undefined value here causes illegal behavior
2627// :99:27: note: when computing vector element at index '0'
2611// :99:27: note: when computing vector element at index '1'
26282612// :99:27: error: use of undefined value here causes illegal behavior
2629// :99:27: note: when computing vector element at index '0'
2613// :99:27: note: when computing vector element at index '1'
26302614// :99:27: error: use of undefined value here causes illegal behavior
2631// :99:27: note: when computing vector element at index '0'
2615// :99:27: note: when computing vector element at index '1'
26322616// :99:27: error: use of undefined value here causes illegal behavior
2633// :99:27: note: when computing vector element at index '0'
2617// :99:27: note: when computing vector element at index '1'
26342618// :99:27: error: use of undefined value here causes illegal behavior
2619// :99:27: note: when computing vector element at index '1'
26352620// :99:27: error: use of undefined value here causes illegal behavior
2621// :99:27: note: when computing vector element at index '1'
26362622// :99:27: error: use of undefined value here causes illegal behavior
2623// :99:27: note: when computing vector element at index '1'
26372624// :99:27: error: use of undefined value here causes illegal behavior
2625// :99:27: note: when computing vector element at index '1'
26382626// :99:27: error: use of undefined value here causes illegal behavior
2627// :99:27: note: when computing vector element at index '1'
26392628// :99:27: error: use of undefined value here causes illegal behavior
2629// :99:27: note: when computing vector element at index '1'
26402630// :99:27: error: use of undefined value here causes illegal behavior
26412631// :99:27: note: when computing vector element at index '1'
26422632// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2646,19 +2636,25 @@ const std = @import("std");
26462636// :99:27: error: use of undefined value here causes illegal behavior
26472637// :99:27: note: when computing vector element at index '1'
26482638// :99:27: error: use of undefined value here causes illegal behavior
2649// :99:27: note: when computing vector element at index '0'
2639// :99:27: note: when computing vector element at index '1'
26502640// :99:27: error: use of undefined value here causes illegal behavior
2651// :99:27: note: when computing vector element at index '0'
2641// :99:27: note: when computing vector element at index '1'
26522642// :99:27: error: use of undefined value here causes illegal behavior
2653// :99:27: note: when computing vector element at index '0'
2643// :99:27: note: when computing vector element at index '1'
26542644// :99:27: error: use of undefined value here causes illegal behavior
2655// :99:27: note: when computing vector element at index '0'
2645// :99:27: note: when computing vector element at index '1'
26562646// :99:27: error: use of undefined value here causes illegal behavior
2647// :99:27: note: when computing vector element at index '1'
26572648// :99:27: error: use of undefined value here causes illegal behavior
2649// :99:27: note: when computing vector element at index '1'
26582650// :99:27: error: use of undefined value here causes illegal behavior
2651// :99:27: note: when computing vector element at index '1'
26592652// :99:27: error: use of undefined value here causes illegal behavior
2653// :99:27: note: when computing vector element at index '1'
26602654// :99:27: error: use of undefined value here causes illegal behavior
2655// :99:27: note: when computing vector element at index '1'
26612656// :99:27: error: use of undefined value here causes illegal behavior
2657// :99:27: note: when computing vector element at index '1'
26622658// :99:27: error: use of undefined value here causes illegal behavior
26632659// :99:27: note: when computing vector element at index '1'
26642660// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2668,13 +2664,17 @@ const std = @import("std");
26682664// :99:27: error: use of undefined value here causes illegal behavior
26692665// :99:27: note: when computing vector element at index '1'
26702666// :99:27: error: use of undefined value here causes illegal behavior
2671// :99:27: note: when computing vector element at index '0'
2667// :99:27: note: when computing vector element at index '1'
26722668// :99:27: error: use of undefined value here causes illegal behavior
2673// :99:27: note: when computing vector element at index '0'
2669// :99:27: note: when computing vector element at index '1'
26742670// :99:27: error: use of undefined value here causes illegal behavior
2675// :99:27: note: when computing vector element at index '0'
2671// :99:27: note: when computing vector element at index '1'
26762672// :99:27: error: use of undefined value here causes illegal behavior
2677// :99:27: note: when computing vector element at index '0'
2673// :99:27: note: when computing vector element at index '1'
2674// :99:27: error: use of undefined value here causes illegal behavior
2675// :99:27: note: when computing vector element at index '1'
2676// :99:27: error: use of undefined value here causes illegal behavior
2677// :99:27: note: when computing vector element at index '1'
26782678// :103:27: error: use of undefined value here causes illegal behavior
26792679// :103:27: error: use of undefined value here causes illegal behavior
26802680// :103:27: error: use of undefined value here causes illegal behavior
......@@ -2682,21 +2682,13 @@ const std = @import("std");
26822682// :103:27: error: use of undefined value here causes illegal behavior
26832683// :103:27: error: use of undefined value here causes illegal behavior
26842684// :103:27: error: use of undefined value here causes illegal behavior
2685// :103:27: note: when computing vector element at index '1'
26862685// :103:27: error: use of undefined value here causes illegal behavior
2687// :103:27: note: when computing vector element at index '1'
26882686// :103:27: error: use of undefined value here causes illegal behavior
2689// :103:27: note: when computing vector element at index '1'
26902687// :103:27: error: use of undefined value here causes illegal behavior
2691// :103:27: note: when computing vector element at index '1'
26922688// :103:27: error: use of undefined value here causes illegal behavior
2693// :103:27: note: when computing vector element at index '0'
26942689// :103:27: error: use of undefined value here causes illegal behavior
2695// :103:27: note: when computing vector element at index '0'
26962690// :103:27: error: use of undefined value here causes illegal behavior
2697// :103:27: note: when computing vector element at index '0'
26982691// :103:27: error: use of undefined value here causes illegal behavior
2699// :103:27: note: when computing vector element at index '0'
27002692// :103:27: error: use of undefined value here causes illegal behavior
27012693// :103:27: error: use of undefined value here causes illegal behavior
27022694// :103:27: error: use of undefined value here causes illegal behavior
......@@ -2704,21 +2696,13 @@ const std = @import("std");
27042696// :103:27: error: use of undefined value here causes illegal behavior
27052697// :103:27: error: use of undefined value here causes illegal behavior
27062698// :103:27: error: use of undefined value here causes illegal behavior
2707// :103:27: note: when computing vector element at index '1'
27082699// :103:27: error: use of undefined value here causes illegal behavior
2709// :103:27: note: when computing vector element at index '1'
27102700// :103:27: error: use of undefined value here causes illegal behavior
2711// :103:27: note: when computing vector element at index '1'
27122701// :103:27: error: use of undefined value here causes illegal behavior
2713// :103:27: note: when computing vector element at index '1'
27142702// :103:27: error: use of undefined value here causes illegal behavior
2715// :103:27: note: when computing vector element at index '0'
27162703// :103:27: error: use of undefined value here causes illegal behavior
2717// :103:27: note: when computing vector element at index '0'
27182704// :103:27: error: use of undefined value here causes illegal behavior
2719// :103:27: note: when computing vector element at index '0'
27202705// :103:27: error: use of undefined value here causes illegal behavior
2721// :103:27: note: when computing vector element at index '0'
27222706// :103:27: error: use of undefined value here causes illegal behavior
27232707// :103:27: error: use of undefined value here causes illegal behavior
27242708// :103:27: error: use of undefined value here causes illegal behavior
......@@ -2726,21 +2710,13 @@ const std = @import("std");
27262710// :103:27: error: use of undefined value here causes illegal behavior
27272711// :103:27: error: use of undefined value here causes illegal behavior
27282712// :103:27: error: use of undefined value here causes illegal behavior
2729// :103:27: note: when computing vector element at index '1'
27302713// :103:27: error: use of undefined value here causes illegal behavior
2731// :103:27: note: when computing vector element at index '1'
27322714// :103:27: error: use of undefined value here causes illegal behavior
2733// :103:27: note: when computing vector element at index '1'
27342715// :103:27: error: use of undefined value here causes illegal behavior
2735// :103:27: note: when computing vector element at index '1'
27362716// :103:27: error: use of undefined value here causes illegal behavior
2737// :103:27: note: when computing vector element at index '0'
27382717// :103:27: error: use of undefined value here causes illegal behavior
2739// :103:27: note: when computing vector element at index '0'
27402718// :103:27: error: use of undefined value here causes illegal behavior
2741// :103:27: note: when computing vector element at index '0'
27422719// :103:27: error: use of undefined value here causes illegal behavior
2743// :103:27: note: when computing vector element at index '0'
27442720// :103:27: error: use of undefined value here causes illegal behavior
27452721// :103:27: error: use of undefined value here causes illegal behavior
27462722// :103:27: error: use of undefined value here causes illegal behavior
......@@ -2748,21 +2724,13 @@ const std = @import("std");
27482724// :103:27: error: use of undefined value here causes illegal behavior
27492725// :103:27: error: use of undefined value here causes illegal behavior
27502726// :103:27: error: use of undefined value here causes illegal behavior
2751// :103:27: note: when computing vector element at index '1'
27522727// :103:27: error: use of undefined value here causes illegal behavior
2753// :103:27: note: when computing vector element at index '1'
27542728// :103:27: error: use of undefined value here causes illegal behavior
2755// :103:27: note: when computing vector element at index '1'
27562729// :103:27: error: use of undefined value here causes illegal behavior
2757// :103:27: note: when computing vector element at index '1'
27582730// :103:27: error: use of undefined value here causes illegal behavior
2759// :103:27: note: when computing vector element at index '0'
27602731// :103:27: error: use of undefined value here causes illegal behavior
2761// :103:27: note: when computing vector element at index '0'
27622732// :103:27: error: use of undefined value here causes illegal behavior
2763// :103:27: note: when computing vector element at index '0'
27642733// :103:27: error: use of undefined value here causes illegal behavior
2765// :103:27: note: when computing vector element at index '0'
27662734// :103:27: error: use of undefined value here causes illegal behavior
27672735// :103:27: error: use of undefined value here causes illegal behavior
27682736// :103:27: error: use of undefined value here causes illegal behavior
......@@ -2770,13 +2738,9 @@ const std = @import("std");
27702738// :103:27: error: use of undefined value here causes illegal behavior
27712739// :103:27: error: use of undefined value here causes illegal behavior
27722740// :103:27: error: use of undefined value here causes illegal behavior
2773// :103:27: note: when computing vector element at index '1'
27742741// :103:27: error: use of undefined value here causes illegal behavior
2775// :103:27: note: when computing vector element at index '1'
27762742// :103:27: error: use of undefined value here causes illegal behavior
2777// :103:27: note: when computing vector element at index '1'
27782743// :103:27: error: use of undefined value here causes illegal behavior
2779// :103:27: note: when computing vector element at index '1'
27802744// :103:27: error: use of undefined value here causes illegal behavior
27812745// :103:27: note: when computing vector element at index '0'
27822746// :103:27: error: use of undefined value here causes illegal behavior
......@@ -2786,19 +2750,21 @@ const std = @import("std");
27862750// :103:27: error: use of undefined value here causes illegal behavior
27872751// :103:27: note: when computing vector element at index '0'
27882752// :103:27: error: use of undefined value here causes illegal behavior
2753// :103:27: note: when computing vector element at index '0'
27892754// :103:27: error: use of undefined value here causes illegal behavior
2755// :103:27: note: when computing vector element at index '0'
27902756// :103:27: error: use of undefined value here causes illegal behavior
2757// :103:27: note: when computing vector element at index '0'
27912758// :103:27: error: use of undefined value here causes illegal behavior
2759// :103:27: note: when computing vector element at index '0'
27922760// :103:27: error: use of undefined value here causes illegal behavior
2761// :103:27: note: when computing vector element at index '0'
27932762// :103:27: error: use of undefined value here causes illegal behavior
2763// :103:27: note: when computing vector element at index '0'
27942764// :103:27: error: use of undefined value here causes illegal behavior
2795// :103:27: note: when computing vector element at index '1'
2796// :103:27: error: use of undefined value here causes illegal behavior
2797// :103:27: note: when computing vector element at index '1'
2798// :103:27: error: use of undefined value here causes illegal behavior
2799// :103:27: note: when computing vector element at index '1'
2765// :103:27: note: when computing vector element at index '0'
28002766// :103:27: error: use of undefined value here causes illegal behavior
2801// :103:27: note: when computing vector element at index '1'
2767// :103:27: note: when computing vector element at index '0'
28022768// :103:27: error: use of undefined value here causes illegal behavior
28032769// :103:27: note: when computing vector element at index '0'
28042770// :103:27: error: use of undefined value here causes illegal behavior
......@@ -2808,19 +2774,25 @@ const std = @import("std");
28082774// :103:27: error: use of undefined value here causes illegal behavior
28092775// :103:27: note: when computing vector element at index '0'
28102776// :103:27: error: use of undefined value here causes illegal behavior
2777// :103:27: note: when computing vector element at index '0'
28112778// :103:27: error: use of undefined value here causes illegal behavior
2779// :103:27: note: when computing vector element at index '0'
28122780// :103:27: error: use of undefined value here causes illegal behavior
2781// :103:27: note: when computing vector element at index '0'
28132782// :103:27: error: use of undefined value here causes illegal behavior
2783// :103:27: note: when computing vector element at index '0'
28142784// :103:27: error: use of undefined value here causes illegal behavior
2785// :103:27: note: when computing vector element at index '0'
28152786// :103:27: error: use of undefined value here causes illegal behavior
2787// :103:27: note: when computing vector element at index '0'
28162788// :103:27: error: use of undefined value here causes illegal behavior
2817// :103:27: note: when computing vector element at index '1'
2789// :103:27: note: when computing vector element at index '0'
28182790// :103:27: error: use of undefined value here causes illegal behavior
2819// :103:27: note: when computing vector element at index '1'
2791// :103:27: note: when computing vector element at index '0'
28202792// :103:27: error: use of undefined value here causes illegal behavior
2821// :103:27: note: when computing vector element at index '1'
2793// :103:27: note: when computing vector element at index '0'
28222794// :103:27: error: use of undefined value here causes illegal behavior
2823// :103:27: note: when computing vector element at index '1'
2795// :103:27: note: when computing vector element at index '0'
28242796// :103:27: error: use of undefined value here causes illegal behavior
28252797// :103:27: note: when computing vector element at index '0'
28262798// :103:27: error: use of undefined value here causes illegal behavior
......@@ -2830,19 +2802,25 @@ const std = @import("std");
28302802// :103:27: error: use of undefined value here causes illegal behavior
28312803// :103:27: note: when computing vector element at index '0'
28322804// :103:27: error: use of undefined value here causes illegal behavior
2805// :103:27: note: when computing vector element at index '0'
28332806// :103:27: error: use of undefined value here causes illegal behavior
2807// :103:27: note: when computing vector element at index '0'
28342808// :103:27: error: use of undefined value here causes illegal behavior
2809// :103:27: note: when computing vector element at index '0'
28352810// :103:27: error: use of undefined value here causes illegal behavior
2811// :103:27: note: when computing vector element at index '0'
28362812// :103:27: error: use of undefined value here causes illegal behavior
2813// :103:27: note: when computing vector element at index '0'
28372814// :103:27: error: use of undefined value here causes illegal behavior
2815// :103:27: note: when computing vector element at index '0'
28382816// :103:27: error: use of undefined value here causes illegal behavior
2839// :103:27: note: when computing vector element at index '1'
2817// :103:27: note: when computing vector element at index '0'
28402818// :103:27: error: use of undefined value here causes illegal behavior
2841// :103:27: note: when computing vector element at index '1'
2819// :103:27: note: when computing vector element at index '0'
28422820// :103:27: error: use of undefined value here causes illegal behavior
2843// :103:27: note: when computing vector element at index '1'
2821// :103:27: note: when computing vector element at index '0'
28442822// :103:27: error: use of undefined value here causes illegal behavior
2845// :103:27: note: when computing vector element at index '1'
2823// :103:27: note: when computing vector element at index '0'
28462824// :103:27: error: use of undefined value here causes illegal behavior
28472825// :103:27: note: when computing vector element at index '0'
28482826// :103:27: error: use of undefined value here causes illegal behavior
......@@ -2852,11 +2830,17 @@ const std = @import("std");
28522830// :103:27: error: use of undefined value here causes illegal behavior
28532831// :103:27: note: when computing vector element at index '0'
28542832// :103:27: error: use of undefined value here causes illegal behavior
2833// :103:27: note: when computing vector element at index '1'
28552834// :103:27: error: use of undefined value here causes illegal behavior
2835// :103:27: note: when computing vector element at index '1'
28562836// :103:27: error: use of undefined value here causes illegal behavior
2837// :103:27: note: when computing vector element at index '1'
28572838// :103:27: error: use of undefined value here causes illegal behavior
2839// :103:27: note: when computing vector element at index '1'
28582840// :103:27: error: use of undefined value here causes illegal behavior
2841// :103:27: note: when computing vector element at index '1'
28592842// :103:27: error: use of undefined value here causes illegal behavior
2843// :103:27: note: when computing vector element at index '1'
28602844// :103:27: error: use of undefined value here causes illegal behavior
28612845// :103:27: note: when computing vector element at index '1'
28622846// :103:27: error: use of undefined value here causes illegal behavior
......@@ -2866,19 +2850,25 @@ const std = @import("std");
28662850// :103:27: error: use of undefined value here causes illegal behavior
28672851// :103:27: note: when computing vector element at index '1'
28682852// :103:27: error: use of undefined value here causes illegal behavior
2869// :103:27: note: when computing vector element at index '0'
2853// :103:27: note: when computing vector element at index '1'
28702854// :103:27: error: use of undefined value here causes illegal behavior
2871// :103:27: note: when computing vector element at index '0'
2855// :103:27: note: when computing vector element at index '1'
28722856// :103:27: error: use of undefined value here causes illegal behavior
2873// :103:27: note: when computing vector element at index '0'
2857// :103:27: note: when computing vector element at index '1'
28742858// :103:27: error: use of undefined value here causes illegal behavior
2875// :103:27: note: when computing vector element at index '0'
2859// :103:27: note: when computing vector element at index '1'
28762860// :103:27: error: use of undefined value here causes illegal behavior
2861// :103:27: note: when computing vector element at index '1'
28772862// :103:27: error: use of undefined value here causes illegal behavior
2863// :103:27: note: when computing vector element at index '1'
28782864// :103:27: error: use of undefined value here causes illegal behavior
2865// :103:27: note: when computing vector element at index '1'
28792866// :103:27: error: use of undefined value here causes illegal behavior
2867// :103:27: note: when computing vector element at index '1'
28802868// :103:27: error: use of undefined value here causes illegal behavior
2869// :103:27: note: when computing vector element at index '1'
28812870// :103:27: error: use of undefined value here causes illegal behavior
2871// :103:27: note: when computing vector element at index '1'
28822872// :103:27: error: use of undefined value here causes illegal behavior
28832873// :103:27: note: when computing vector element at index '1'
28842874// :103:27: error: use of undefined value here causes illegal behavior
......@@ -2888,19 +2878,25 @@ const std = @import("std");
28882878// :103:27: error: use of undefined value here causes illegal behavior
28892879// :103:27: note: when computing vector element at index '1'
28902880// :103:27: error: use of undefined value here causes illegal behavior
2891// :103:27: note: when computing vector element at index '0'
2881// :103:27: note: when computing vector element at index '1'
28922882// :103:27: error: use of undefined value here causes illegal behavior
2893// :103:27: note: when computing vector element at index '0'
2883// :103:27: note: when computing vector element at index '1'
28942884// :103:27: error: use of undefined value here causes illegal behavior
2895// :103:27: note: when computing vector element at index '0'
2885// :103:27: note: when computing vector element at index '1'
28962886// :103:27: error: use of undefined value here causes illegal behavior
2897// :103:27: note: when computing vector element at index '0'
2887// :103:27: note: when computing vector element at index '1'
28982888// :103:27: error: use of undefined value here causes illegal behavior
2889// :103:27: note: when computing vector element at index '1'
28992890// :103:27: error: use of undefined value here causes illegal behavior
2891// :103:27: note: when computing vector element at index '1'
29002892// :103:27: error: use of undefined value here causes illegal behavior
2893// :103:27: note: when computing vector element at index '1'
29012894// :103:27: error: use of undefined value here causes illegal behavior
2895// :103:27: note: when computing vector element at index '1'
29022896// :103:27: error: use of undefined value here causes illegal behavior
2897// :103:27: note: when computing vector element at index '1'
29032898// :103:27: error: use of undefined value here causes illegal behavior
2899// :103:27: note: when computing vector element at index '1'
29042900// :103:27: error: use of undefined value here causes illegal behavior
29052901// :103:27: note: when computing vector element at index '1'
29062902// :103:27: error: use of undefined value here causes illegal behavior
......@@ -2910,13 +2906,17 @@ const std = @import("std");
29102906// :103:27: error: use of undefined value here causes illegal behavior
29112907// :103:27: note: when computing vector element at index '1'
29122908// :103:27: error: use of undefined value here causes illegal behavior
2913// :103:27: note: when computing vector element at index '0'
2909// :103:27: note: when computing vector element at index '1'
29142910// :103:27: error: use of undefined value here causes illegal behavior
2915// :103:27: note: when computing vector element at index '0'
2911// :103:27: note: when computing vector element at index '1'
29162912// :103:27: error: use of undefined value here causes illegal behavior
2917// :103:27: note: when computing vector element at index '0'
2913// :103:27: note: when computing vector element at index '1'
29182914// :103:27: error: use of undefined value here causes illegal behavior
2919// :103:27: note: when computing vector element at index '0'
2915// :103:27: note: when computing vector element at index '1'
2916// :103:27: error: use of undefined value here causes illegal behavior
2917// :103:27: note: when computing vector element at index '1'
2918// :103:27: error: use of undefined value here causes illegal behavior
2919// :103:27: note: when computing vector element at index '1'
29202920// :107:27: error: use of undefined value here causes illegal behavior
29212921// :107:27: error: use of undefined value here causes illegal behavior
29222922// :107:27: error: use of undefined value here causes illegal behavior
......@@ -2924,21 +2924,13 @@ const std = @import("std");
29242924// :107:27: error: use of undefined value here causes illegal behavior
29252925// :107:27: error: use of undefined value here causes illegal behavior
29262926// :107:27: error: use of undefined value here causes illegal behavior
2927// :107:27: note: when computing vector element at index '1'
29282927// :107:27: error: use of undefined value here causes illegal behavior
2929// :107:27: note: when computing vector element at index '1'
29302928// :107:27: error: use of undefined value here causes illegal behavior
2931// :107:27: note: when computing vector element at index '1'
29322929// :107:27: error: use of undefined value here causes illegal behavior
2933// :107:27: note: when computing vector element at index '1'
29342930// :107:27: error: use of undefined value here causes illegal behavior
2935// :107:27: note: when computing vector element at index '0'
29362931// :107:27: error: use of undefined value here causes illegal behavior
2937// :107:27: note: when computing vector element at index '0'
29382932// :107:27: error: use of undefined value here causes illegal behavior
2939// :107:27: note: when computing vector element at index '0'
29402933// :107:27: error: use of undefined value here causes illegal behavior
2941// :107:27: note: when computing vector element at index '0'
29422934// :107:27: error: use of undefined value here causes illegal behavior
29432935// :107:27: error: use of undefined value here causes illegal behavior
29442936// :107:27: error: use of undefined value here causes illegal behavior
......@@ -2946,21 +2938,13 @@ const std = @import("std");
29462938// :107:27: error: use of undefined value here causes illegal behavior
29472939// :107:27: error: use of undefined value here causes illegal behavior
29482940// :107:27: error: use of undefined value here causes illegal behavior
2949// :107:27: note: when computing vector element at index '1'
29502941// :107:27: error: use of undefined value here causes illegal behavior
2951// :107:27: note: when computing vector element at index '1'
29522942// :107:27: error: use of undefined value here causes illegal behavior
2953// :107:27: note: when computing vector element at index '1'
29542943// :107:27: error: use of undefined value here causes illegal behavior
2955// :107:27: note: when computing vector element at index '1'
29562944// :107:27: error: use of undefined value here causes illegal behavior
2957// :107:27: note: when computing vector element at index '0'
29582945// :107:27: error: use of undefined value here causes illegal behavior
2959// :107:27: note: when computing vector element at index '0'
29602946// :107:27: error: use of undefined value here causes illegal behavior
2961// :107:27: note: when computing vector element at index '0'
29622947// :107:27: error: use of undefined value here causes illegal behavior
2963// :107:27: note: when computing vector element at index '0'
29642948// :107:27: error: use of undefined value here causes illegal behavior
29652949// :107:27: error: use of undefined value here causes illegal behavior
29662950// :107:27: error: use of undefined value here causes illegal behavior
......@@ -2968,21 +2952,13 @@ const std = @import("std");
29682952// :107:27: error: use of undefined value here causes illegal behavior
29692953// :107:27: error: use of undefined value here causes illegal behavior
29702954// :107:27: error: use of undefined value here causes illegal behavior
2971// :107:27: note: when computing vector element at index '1'
29722955// :107:27: error: use of undefined value here causes illegal behavior
2973// :107:27: note: when computing vector element at index '1'
29742956// :107:27: error: use of undefined value here causes illegal behavior
2975// :107:27: note: when computing vector element at index '1'
29762957// :107:27: error: use of undefined value here causes illegal behavior
2977// :107:27: note: when computing vector element at index '1'
29782958// :107:27: error: use of undefined value here causes illegal behavior
2979// :107:27: note: when computing vector element at index '0'
29802959// :107:27: error: use of undefined value here causes illegal behavior
2981// :107:27: note: when computing vector element at index '0'
29822960// :107:27: error: use of undefined value here causes illegal behavior
2983// :107:27: note: when computing vector element at index '0'
29842961// :107:27: error: use of undefined value here causes illegal behavior
2985// :107:27: note: when computing vector element at index '0'
29862962// :107:27: error: use of undefined value here causes illegal behavior
29872963// :107:27: error: use of undefined value here causes illegal behavior
29882964// :107:27: error: use of undefined value here causes illegal behavior
......@@ -2990,21 +2966,13 @@ const std = @import("std");
29902966// :107:27: error: use of undefined value here causes illegal behavior
29912967// :107:27: error: use of undefined value here causes illegal behavior
29922968// :107:27: error: use of undefined value here causes illegal behavior
2993// :107:27: note: when computing vector element at index '1'
29942969// :107:27: error: use of undefined value here causes illegal behavior
2995// :107:27: note: when computing vector element at index '1'
29962970// :107:27: error: use of undefined value here causes illegal behavior
2997// :107:27: note: when computing vector element at index '1'
29982971// :107:27: error: use of undefined value here causes illegal behavior
2999// :107:27: note: when computing vector element at index '1'
30002972// :107:27: error: use of undefined value here causes illegal behavior
3001// :107:27: note: when computing vector element at index '0'
30022973// :107:27: error: use of undefined value here causes illegal behavior
3003// :107:27: note: when computing vector element at index '0'
30042974// :107:27: error: use of undefined value here causes illegal behavior
3005// :107:27: note: when computing vector element at index '0'
30062975// :107:27: error: use of undefined value here causes illegal behavior
3007// :107:27: note: when computing vector element at index '0'
30082976// :107:27: error: use of undefined value here causes illegal behavior
30092977// :107:27: error: use of undefined value here causes illegal behavior
30102978// :107:27: error: use of undefined value here causes illegal behavior
......@@ -3012,13 +2980,9 @@ const std = @import("std");
30122980// :107:27: error: use of undefined value here causes illegal behavior
30132981// :107:27: error: use of undefined value here causes illegal behavior
30142982// :107:27: error: use of undefined value here causes illegal behavior
3015// :107:27: note: when computing vector element at index '1'
30162983// :107:27: error: use of undefined value here causes illegal behavior
3017// :107:27: note: when computing vector element at index '1'
30182984// :107:27: error: use of undefined value here causes illegal behavior
3019// :107:27: note: when computing vector element at index '1'
30202985// :107:27: error: use of undefined value here causes illegal behavior
3021// :107:27: note: when computing vector element at index '1'
30222986// :107:27: error: use of undefined value here causes illegal behavior
30232987// :107:27: note: when computing vector element at index '0'
30242988// :107:27: error: use of undefined value here causes illegal behavior
......@@ -3028,19 +2992,21 @@ const std = @import("std");
30282992// :107:27: error: use of undefined value here causes illegal behavior
30292993// :107:27: note: when computing vector element at index '0'
30302994// :107:27: error: use of undefined value here causes illegal behavior
2995// :107:27: note: when computing vector element at index '0'
30312996// :107:27: error: use of undefined value here causes illegal behavior
2997// :107:27: note: when computing vector element at index '0'
30322998// :107:27: error: use of undefined value here causes illegal behavior
2999// :107:27: note: when computing vector element at index '0'
30333000// :107:27: error: use of undefined value here causes illegal behavior
3001// :107:27: note: when computing vector element at index '0'
30343002// :107:27: error: use of undefined value here causes illegal behavior
3003// :107:27: note: when computing vector element at index '0'
30353004// :107:27: error: use of undefined value here causes illegal behavior
3005// :107:27: note: when computing vector element at index '0'
30363006// :107:27: error: use of undefined value here causes illegal behavior
3037// :107:27: note: when computing vector element at index '1'
3038// :107:27: error: use of undefined value here causes illegal behavior
3039// :107:27: note: when computing vector element at index '1'
3040// :107:27: error: use of undefined value here causes illegal behavior
3041// :107:27: note: when computing vector element at index '1'
3007// :107:27: note: when computing vector element at index '0'
30423008// :107:27: error: use of undefined value here causes illegal behavior
3043// :107:27: note: when computing vector element at index '1'
3009// :107:27: note: when computing vector element at index '0'
30443010// :107:27: error: use of undefined value here causes illegal behavior
30453011// :107:27: note: when computing vector element at index '0'
30463012// :107:27: error: use of undefined value here causes illegal behavior
......@@ -3050,19 +3016,25 @@ const std = @import("std");
30503016// :107:27: error: use of undefined value here causes illegal behavior
30513017// :107:27: note: when computing vector element at index '0'
30523018// :107:27: error: use of undefined value here causes illegal behavior
3019// :107:27: note: when computing vector element at index '0'
30533020// :107:27: error: use of undefined value here causes illegal behavior
3021// :107:27: note: when computing vector element at index '0'
30543022// :107:27: error: use of undefined value here causes illegal behavior
3023// :107:27: note: when computing vector element at index '0'
30553024// :107:27: error: use of undefined value here causes illegal behavior
3025// :107:27: note: when computing vector element at index '0'
30563026// :107:27: error: use of undefined value here causes illegal behavior
3027// :107:27: note: when computing vector element at index '0'
30573028// :107:27: error: use of undefined value here causes illegal behavior
3029// :107:27: note: when computing vector element at index '0'
30583030// :107:27: error: use of undefined value here causes illegal behavior
3059// :107:27: note: when computing vector element at index '1'
3031// :107:27: note: when computing vector element at index '0'
30603032// :107:27: error: use of undefined value here causes illegal behavior
3061// :107:27: note: when computing vector element at index '1'
3033// :107:27: note: when computing vector element at index '0'
30623034// :107:27: error: use of undefined value here causes illegal behavior
3063// :107:27: note: when computing vector element at index '1'
3035// :107:27: note: when computing vector element at index '0'
30643036// :107:27: error: use of undefined value here causes illegal behavior
3065// :107:27: note: when computing vector element at index '1'
3037// :107:27: note: when computing vector element at index '0'
30663038// :107:27: error: use of undefined value here causes illegal behavior
30673039// :107:27: note: when computing vector element at index '0'
30683040// :107:27: error: use of undefined value here causes illegal behavior
......@@ -3072,19 +3044,25 @@ const std = @import("std");
30723044// :107:27: error: use of undefined value here causes illegal behavior
30733045// :107:27: note: when computing vector element at index '0'
30743046// :107:27: error: use of undefined value here causes illegal behavior
3047// :107:27: note: when computing vector element at index '0'
30753048// :107:27: error: use of undefined value here causes illegal behavior
3049// :107:27: note: when computing vector element at index '0'
30763050// :107:27: error: use of undefined value here causes illegal behavior
3051// :107:27: note: when computing vector element at index '0'
30773052// :107:27: error: use of undefined value here causes illegal behavior
3053// :107:27: note: when computing vector element at index '0'
30783054// :107:27: error: use of undefined value here causes illegal behavior
3055// :107:27: note: when computing vector element at index '0'
30793056// :107:27: error: use of undefined value here causes illegal behavior
3057// :107:27: note: when computing vector element at index '0'
30803058// :107:27: error: use of undefined value here causes illegal behavior
3081// :107:27: note: when computing vector element at index '1'
3059// :107:27: note: when computing vector element at index '0'
30823060// :107:27: error: use of undefined value here causes illegal behavior
3083// :107:27: note: when computing vector element at index '1'
3061// :107:27: note: when computing vector element at index '0'
30843062// :107:27: error: use of undefined value here causes illegal behavior
3085// :107:27: note: when computing vector element at index '1'
3063// :107:27: note: when computing vector element at index '0'
30863064// :107:27: error: use of undefined value here causes illegal behavior
3087// :107:27: note: when computing vector element at index '1'
3065// :107:27: note: when computing vector element at index '0'
30883066// :107:27: error: use of undefined value here causes illegal behavior
30893067// :107:27: note: when computing vector element at index '0'
30903068// :107:27: error: use of undefined value here causes illegal behavior
......@@ -3094,11 +3072,17 @@ const std = @import("std");
30943072// :107:27: error: use of undefined value here causes illegal behavior
30953073// :107:27: note: when computing vector element at index '0'
30963074// :107:27: error: use of undefined value here causes illegal behavior
3075// :107:27: note: when computing vector element at index '1'
30973076// :107:27: error: use of undefined value here causes illegal behavior
3077// :107:27: note: when computing vector element at index '1'
30983078// :107:27: error: use of undefined value here causes illegal behavior
3079// :107:27: note: when computing vector element at index '1'
30993080// :107:27: error: use of undefined value here causes illegal behavior
3081// :107:27: note: when computing vector element at index '1'
31003082// :107:27: error: use of undefined value here causes illegal behavior
3083// :107:27: note: when computing vector element at index '1'
31013084// :107:27: error: use of undefined value here causes illegal behavior
3085// :107:27: note: when computing vector element at index '1'
31023086// :107:27: error: use of undefined value here causes illegal behavior
31033087// :107:27: note: when computing vector element at index '1'
31043088// :107:27: error: use of undefined value here causes illegal behavior
......@@ -3108,19 +3092,25 @@ const std = @import("std");
31083092// :107:27: error: use of undefined value here causes illegal behavior
31093093// :107:27: note: when computing vector element at index '1'
31103094// :107:27: error: use of undefined value here causes illegal behavior
3111// :107:27: note: when computing vector element at index '0'
3095// :107:27: note: when computing vector element at index '1'
31123096// :107:27: error: use of undefined value here causes illegal behavior
3113// :107:27: note: when computing vector element at index '0'
3097// :107:27: note: when computing vector element at index '1'
31143098// :107:27: error: use of undefined value here causes illegal behavior
3115// :107:27: note: when computing vector element at index '0'
3099// :107:27: note: when computing vector element at index '1'
31163100// :107:27: error: use of undefined value here causes illegal behavior
3117// :107:27: note: when computing vector element at index '0'
3101// :107:27: note: when computing vector element at index '1'
31183102// :107:27: error: use of undefined value here causes illegal behavior
3103// :107:27: note: when computing vector element at index '1'
31193104// :107:27: error: use of undefined value here causes illegal behavior
3105// :107:27: note: when computing vector element at index '1'
31203106// :107:27: error: use of undefined value here causes illegal behavior
3107// :107:27: note: when computing vector element at index '1'
31213108// :107:27: error: use of undefined value here causes illegal behavior
3109// :107:27: note: when computing vector element at index '1'
31223110// :107:27: error: use of undefined value here causes illegal behavior
3111// :107:27: note: when computing vector element at index '1'
31233112// :107:27: error: use of undefined value here causes illegal behavior
3113// :107:27: note: when computing vector element at index '1'
31243114// :107:27: error: use of undefined value here causes illegal behavior
31253115// :107:27: note: when computing vector element at index '1'
31263116// :107:27: error: use of undefined value here causes illegal behavior
......@@ -3130,19 +3120,29 @@ const std = @import("std");
31303120// :107:27: error: use of undefined value here causes illegal behavior
31313121// :107:27: note: when computing vector element at index '1'
31323122// :107:27: error: use of undefined value here causes illegal behavior
3133// :107:27: note: when computing vector element at index '0'
3123// :107:27: note: when computing vector element at index '1'
31343124// :107:27: error: use of undefined value here causes illegal behavior
3135// :107:27: note: when computing vector element at index '0'
3125// :107:27: note: when computing vector element at index '1'
31363126// :107:27: error: use of undefined value here causes illegal behavior
3137// :107:27: note: when computing vector element at index '0'
3127// :107:27: note: when computing vector element at index '1'
31383128// :107:27: error: use of undefined value here causes illegal behavior
3139// :107:27: note: when computing vector element at index '0'
3129// :107:27: note: when computing vector element at index '1'
3130// :107:27: error: use of undefined value here causes illegal behavior
3131// :107:27: note: when computing vector element at index '1'
3132// :107:27: error: use of undefined value here causes illegal behavior
3133// :107:27: note: when computing vector element at index '1'
31403134// :107:27: error: use of undefined value here causes illegal behavior
3135// :107:27: note: when computing vector element at index '1'
31413136// :107:27: error: use of undefined value here causes illegal behavior
3137// :107:27: note: when computing vector element at index '1'
31423138// :107:27: error: use of undefined value here causes illegal behavior
3139// :107:27: note: when computing vector element at index '1'
31433140// :107:27: error: use of undefined value here causes illegal behavior
3141// :107:27: note: when computing vector element at index '1'
31443142// :107:27: error: use of undefined value here causes illegal behavior
3143// :107:27: note: when computing vector element at index '1'
31453144// :107:27: error: use of undefined value here causes illegal behavior
3145// :107:27: note: when computing vector element at index '1'
31463146// :107:27: error: use of undefined value here causes illegal behavior
31473147// :107:27: note: when computing vector element at index '1'
31483148// :107:27: error: use of undefined value here causes illegal behavior
......@@ -3152,13 +3152,13 @@ const std = @import("std");
31523152// :107:27: error: use of undefined value here causes illegal behavior
31533153// :107:27: note: when computing vector element at index '1'
31543154// :107:27: error: use of undefined value here causes illegal behavior
3155// :107:27: note: when computing vector element at index '0'
3155// :107:27: note: when computing vector element at index '1'
31563156// :107:27: error: use of undefined value here causes illegal behavior
3157// :107:27: note: when computing vector element at index '0'
3157// :107:27: note: when computing vector element at index '1'
31583158// :107:27: error: use of undefined value here causes illegal behavior
3159// :107:27: note: when computing vector element at index '0'
3159// :107:27: note: when computing vector element at index '1'
31603160// :107:27: error: use of undefined value here causes illegal behavior
3161// :107:27: note: when computing vector element at index '0'
3161// :107:27: note: when computing vector element at index '1'
31623162// :111:22: error: use of undefined value here causes illegal behavior
31633163// :111:22: error: use of undefined value here causes illegal behavior
31643164// :111:22: error: use of undefined value here causes illegal behavior
......@@ -3166,21 +3166,13 @@ const std = @import("std");
31663166// :111:22: error: use of undefined value here causes illegal behavior
31673167// :111:22: error: use of undefined value here causes illegal behavior
31683168// :111:22: error: use of undefined value here causes illegal behavior
3169// :111:22: note: when computing vector element at index '1'
31703169// :111:22: error: use of undefined value here causes illegal behavior
3171// :111:22: note: when computing vector element at index '1'
31723170// :111:22: error: use of undefined value here causes illegal behavior
3173// :111:22: note: when computing vector element at index '1'
31743171// :111:22: error: use of undefined value here causes illegal behavior
3175// :111:22: note: when computing vector element at index '1'
31763172// :111:22: error: use of undefined value here causes illegal behavior
3177// :111:22: note: when computing vector element at index '0'
31783173// :111:22: error: use of undefined value here causes illegal behavior
3179// :111:22: note: when computing vector element at index '0'
31803174// :111:22: error: use of undefined value here causes illegal behavior
3181// :111:22: note: when computing vector element at index '0'
31823175// :111:22: error: use of undefined value here causes illegal behavior
3183// :111:22: note: when computing vector element at index '0'
31843176// :111:22: error: use of undefined value here causes illegal behavior
31853177// :111:22: error: use of undefined value here causes illegal behavior
31863178// :111:22: error: use of undefined value here causes illegal behavior
......@@ -3188,21 +3180,13 @@ const std = @import("std");
31883180// :111:22: error: use of undefined value here causes illegal behavior
31893181// :111:22: error: use of undefined value here causes illegal behavior
31903182// :111:22: error: use of undefined value here causes illegal behavior
3191// :111:22: note: when computing vector element at index '1'
31923183// :111:22: error: use of undefined value here causes illegal behavior
3193// :111:22: note: when computing vector element at index '1'
31943184// :111:22: error: use of undefined value here causes illegal behavior
3195// :111:22: note: when computing vector element at index '1'
31963185// :111:22: error: use of undefined value here causes illegal behavior
3197// :111:22: note: when computing vector element at index '1'
31983186// :111:22: error: use of undefined value here causes illegal behavior
3199// :111:22: note: when computing vector element at index '0'
32003187// :111:22: error: use of undefined value here causes illegal behavior
3201// :111:22: note: when computing vector element at index '0'
32023188// :111:22: error: use of undefined value here causes illegal behavior
3203// :111:22: note: when computing vector element at index '0'
32043189// :111:22: error: use of undefined value here causes illegal behavior
3205// :111:22: note: when computing vector element at index '0'
32063190// :111:22: error: use of undefined value here causes illegal behavior
32073191// :111:22: error: use of undefined value here causes illegal behavior
32083192// :111:22: error: use of undefined value here causes illegal behavior
......@@ -3210,21 +3194,13 @@ const std = @import("std");
32103194// :111:22: error: use of undefined value here causes illegal behavior
32113195// :111:22: error: use of undefined value here causes illegal behavior
32123196// :111:22: error: use of undefined value here causes illegal behavior
3213// :111:22: note: when computing vector element at index '1'
32143197// :111:22: error: use of undefined value here causes illegal behavior
3215// :111:22: note: when computing vector element at index '1'
32163198// :111:22: error: use of undefined value here causes illegal behavior
3217// :111:22: note: when computing vector element at index '1'
32183199// :111:22: error: use of undefined value here causes illegal behavior
3219// :111:22: note: when computing vector element at index '1'
32203200// :111:22: error: use of undefined value here causes illegal behavior
3221// :111:22: note: when computing vector element at index '0'
32223201// :111:22: error: use of undefined value here causes illegal behavior
3223// :111:22: note: when computing vector element at index '0'
32243202// :111:22: error: use of undefined value here causes illegal behavior
3225// :111:22: note: when computing vector element at index '0'
32263203// :111:22: error: use of undefined value here causes illegal behavior
3227// :111:22: note: when computing vector element at index '0'
32283204// :111:22: error: use of undefined value here causes illegal behavior
32293205// :111:22: error: use of undefined value here causes illegal behavior
32303206// :111:22: error: use of undefined value here causes illegal behavior
......@@ -3232,21 +3208,13 @@ const std = @import("std");
32323208// :111:22: error: use of undefined value here causes illegal behavior
32333209// :111:22: error: use of undefined value here causes illegal behavior
32343210// :111:22: error: use of undefined value here causes illegal behavior
3235// :111:22: note: when computing vector element at index '1'
32363211// :111:22: error: use of undefined value here causes illegal behavior
3237// :111:22: note: when computing vector element at index '1'
32383212// :111:22: error: use of undefined value here causes illegal behavior
3239// :111:22: note: when computing vector element at index '1'
32403213// :111:22: error: use of undefined value here causes illegal behavior
3241// :111:22: note: when computing vector element at index '1'
32423214// :111:22: error: use of undefined value here causes illegal behavior
3243// :111:22: note: when computing vector element at index '0'
32443215// :111:22: error: use of undefined value here causes illegal behavior
3245// :111:22: note: when computing vector element at index '0'
32463216// :111:22: error: use of undefined value here causes illegal behavior
3247// :111:22: note: when computing vector element at index '0'
32483217// :111:22: error: use of undefined value here causes illegal behavior
3249// :111:22: note: when computing vector element at index '0'
32503218// :111:22: error: use of undefined value here causes illegal behavior
32513219// :111:22: error: use of undefined value here causes illegal behavior
32523220// :111:22: error: use of undefined value here causes illegal behavior
......@@ -3254,13 +3222,9 @@ const std = @import("std");
32543222// :111:22: error: use of undefined value here causes illegal behavior
32553223// :111:22: error: use of undefined value here causes illegal behavior
32563224// :111:22: error: use of undefined value here causes illegal behavior
3257// :111:22: note: when computing vector element at index '1'
32583225// :111:22: error: use of undefined value here causes illegal behavior
3259// :111:22: note: when computing vector element at index '1'
32603226// :111:22: error: use of undefined value here causes illegal behavior
3261// :111:22: note: when computing vector element at index '1'
32623227// :111:22: error: use of undefined value here causes illegal behavior
3263// :111:22: note: when computing vector element at index '1'
32643228// :111:22: error: use of undefined value here causes illegal behavior
32653229// :111:22: note: when computing vector element at index '0'
32663230// :111:22: error: use of undefined value here causes illegal behavior
......@@ -3270,19 +3234,21 @@ const std = @import("std");
32703234// :111:22: error: use of undefined value here causes illegal behavior
32713235// :111:22: note: when computing vector element at index '0'
32723236// :111:22: error: use of undefined value here causes illegal behavior
3237// :111:22: note: when computing vector element at index '0'
32733238// :111:22: error: use of undefined value here causes illegal behavior
3239// :111:22: note: when computing vector element at index '0'
32743240// :111:22: error: use of undefined value here causes illegal behavior
3241// :111:22: note: when computing vector element at index '0'
32753242// :111:22: error: use of undefined value here causes illegal behavior
3243// :111:22: note: when computing vector element at index '0'
32763244// :111:22: error: use of undefined value here causes illegal behavior
3245// :111:22: note: when computing vector element at index '0'
32773246// :111:22: error: use of undefined value here causes illegal behavior
3247// :111:22: note: when computing vector element at index '0'
32783248// :111:22: error: use of undefined value here causes illegal behavior
3279// :111:22: note: when computing vector element at index '1'
3280// :111:22: error: use of undefined value here causes illegal behavior
3281// :111:22: note: when computing vector element at index '1'
3282// :111:22: error: use of undefined value here causes illegal behavior
3283// :111:22: note: when computing vector element at index '1'
3249// :111:22: note: when computing vector element at index '0'
32843250// :111:22: error: use of undefined value here causes illegal behavior
3285// :111:22: note: when computing vector element at index '1'
3251// :111:22: note: when computing vector element at index '0'
32863252// :111:22: error: use of undefined value here causes illegal behavior
32873253// :111:22: note: when computing vector element at index '0'
32883254// :111:22: error: use of undefined value here causes illegal behavior
......@@ -3292,19 +3258,25 @@ const std = @import("std");
32923258// :111:22: error: use of undefined value here causes illegal behavior
32933259// :111:22: note: when computing vector element at index '0'
32943260// :111:22: error: use of undefined value here causes illegal behavior
3261// :111:22: note: when computing vector element at index '0'
32953262// :111:22: error: use of undefined value here causes illegal behavior
3263// :111:22: note: when computing vector element at index '0'
32963264// :111:22: error: use of undefined value here causes illegal behavior
3265// :111:22: note: when computing vector element at index '0'
32973266// :111:22: error: use of undefined value here causes illegal behavior
3267// :111:22: note: when computing vector element at index '0'
32983268// :111:22: error: use of undefined value here causes illegal behavior
3269// :111:22: note: when computing vector element at index '0'
32993270// :111:22: error: use of undefined value here causes illegal behavior
3271// :111:22: note: when computing vector element at index '0'
33003272// :111:22: error: use of undefined value here causes illegal behavior
3301// :111:22: note: when computing vector element at index '1'
3273// :111:22: note: when computing vector element at index '0'
33023274// :111:22: error: use of undefined value here causes illegal behavior
3303// :111:22: note: when computing vector element at index '1'
3275// :111:22: note: when computing vector element at index '0'
33043276// :111:22: error: use of undefined value here causes illegal behavior
3305// :111:22: note: when computing vector element at index '1'
3277// :111:22: note: when computing vector element at index '0'
33063278// :111:22: error: use of undefined value here causes illegal behavior
3307// :111:22: note: when computing vector element at index '1'
3279// :111:22: note: when computing vector element at index '0'
33083280// :111:22: error: use of undefined value here causes illegal behavior
33093281// :111:22: note: when computing vector element at index '0'
33103282// :111:22: error: use of undefined value here causes illegal behavior
......@@ -3314,19 +3286,25 @@ const std = @import("std");
33143286// :111:22: error: use of undefined value here causes illegal behavior
33153287// :111:22: note: when computing vector element at index '0'
33163288// :111:22: error: use of undefined value here causes illegal behavior
3289// :111:22: note: when computing vector element at index '0'
33173290// :111:22: error: use of undefined value here causes illegal behavior
3291// :111:22: note: when computing vector element at index '0'
33183292// :111:22: error: use of undefined value here causes illegal behavior
3293// :111:22: note: when computing vector element at index '0'
33193294// :111:22: error: use of undefined value here causes illegal behavior
3295// :111:22: note: when computing vector element at index '0'
33203296// :111:22: error: use of undefined value here causes illegal behavior
3297// :111:22: note: when computing vector element at index '0'
33213298// :111:22: error: use of undefined value here causes illegal behavior
3299// :111:22: note: when computing vector element at index '0'
33223300// :111:22: error: use of undefined value here causes illegal behavior
3323// :111:22: note: when computing vector element at index '1'
3301// :111:22: note: when computing vector element at index '0'
33243302// :111:22: error: use of undefined value here causes illegal behavior
3325// :111:22: note: when computing vector element at index '1'
3303// :111:22: note: when computing vector element at index '0'
33263304// :111:22: error: use of undefined value here causes illegal behavior
3327// :111:22: note: when computing vector element at index '1'
3305// :111:22: note: when computing vector element at index '0'
33283306// :111:22: error: use of undefined value here causes illegal behavior
3329// :111:22: note: when computing vector element at index '1'
3307// :111:22: note: when computing vector element at index '0'
33303308// :111:22: error: use of undefined value here causes illegal behavior
33313309// :111:22: note: when computing vector element at index '0'
33323310// :111:22: error: use of undefined value here causes illegal behavior
......@@ -3336,11 +3314,17 @@ const std = @import("std");
33363314// :111:22: error: use of undefined value here causes illegal behavior
33373315// :111:22: note: when computing vector element at index '0'
33383316// :111:22: error: use of undefined value here causes illegal behavior
3317// :111:22: note: when computing vector element at index '1'
33393318// :111:22: error: use of undefined value here causes illegal behavior
3319// :111:22: note: when computing vector element at index '1'
33403320// :111:22: error: use of undefined value here causes illegal behavior
3321// :111:22: note: when computing vector element at index '1'
33413322// :111:22: error: use of undefined value here causes illegal behavior
3323// :111:22: note: when computing vector element at index '1'
33423324// :111:22: error: use of undefined value here causes illegal behavior
3325// :111:22: note: when computing vector element at index '1'
33433326// :111:22: error: use of undefined value here causes illegal behavior
3327// :111:22: note: when computing vector element at index '1'
33443328// :111:22: error: use of undefined value here causes illegal behavior
33453329// :111:22: note: when computing vector element at index '1'
33463330// :111:22: error: use of undefined value here causes illegal behavior
......@@ -3350,19 +3334,25 @@ const std = @import("std");
33503334// :111:22: error: use of undefined value here causes illegal behavior
33513335// :111:22: note: when computing vector element at index '1'
33523336// :111:22: error: use of undefined value here causes illegal behavior
3353// :111:22: note: when computing vector element at index '0'
3337// :111:22: note: when computing vector element at index '1'
33543338// :111:22: error: use of undefined value here causes illegal behavior
3355// :111:22: note: when computing vector element at index '0'
3339// :111:22: note: when computing vector element at index '1'
33563340// :111:22: error: use of undefined value here causes illegal behavior
3357// :111:22: note: when computing vector element at index '0'
3341// :111:22: note: when computing vector element at index '1'
33583342// :111:22: error: use of undefined value here causes illegal behavior
3359// :111:22: note: when computing vector element at index '0'
3343// :111:22: note: when computing vector element at index '1'
33603344// :111:22: error: use of undefined value here causes illegal behavior
3345// :111:22: note: when computing vector element at index '1'
33613346// :111:22: error: use of undefined value here causes illegal behavior
3347// :111:22: note: when computing vector element at index '1'
33623348// :111:22: error: use of undefined value here causes illegal behavior
3349// :111:22: note: when computing vector element at index '1'
33633350// :111:22: error: use of undefined value here causes illegal behavior
3351// :111:22: note: when computing vector element at index '1'
33643352// :111:22: error: use of undefined value here causes illegal behavior
3353// :111:22: note: when computing vector element at index '1'
33653354// :111:22: error: use of undefined value here causes illegal behavior
3355// :111:22: note: when computing vector element at index '1'
33663356// :111:22: error: use of undefined value here causes illegal behavior
33673357// :111:22: note: when computing vector element at index '1'
33683358// :111:22: error: use of undefined value here causes illegal behavior
......@@ -3372,19 +3362,25 @@ const std = @import("std");
33723362// :111:22: error: use of undefined value here causes illegal behavior
33733363// :111:22: note: when computing vector element at index '1'
33743364// :111:22: error: use of undefined value here causes illegal behavior
3375// :111:22: note: when computing vector element at index '0'
3365// :111:22: note: when computing vector element at index '1'
33763366// :111:22: error: use of undefined value here causes illegal behavior
3377// :111:22: note: when computing vector element at index '0'
3367// :111:22: note: when computing vector element at index '1'
33783368// :111:22: error: use of undefined value here causes illegal behavior
3379// :111:22: note: when computing vector element at index '0'
3369// :111:22: note: when computing vector element at index '1'
33803370// :111:22: error: use of undefined value here causes illegal behavior
3381// :111:22: note: when computing vector element at index '0'
3371// :111:22: note: when computing vector element at index '1'
33823372// :111:22: error: use of undefined value here causes illegal behavior
3373// :111:22: note: when computing vector element at index '1'
33833374// :111:22: error: use of undefined value here causes illegal behavior
3375// :111:22: note: when computing vector element at index '1'
33843376// :111:22: error: use of undefined value here causes illegal behavior
3377// :111:22: note: when computing vector element at index '1'
33853378// :111:22: error: use of undefined value here causes illegal behavior
3379// :111:22: note: when computing vector element at index '1'
33863380// :111:22: error: use of undefined value here causes illegal behavior
3381// :111:22: note: when computing vector element at index '1'
33873382// :111:22: error: use of undefined value here causes illegal behavior
3383// :111:22: note: when computing vector element at index '1'
33883384// :111:22: error: use of undefined value here causes illegal behavior
33893385// :111:22: note: when computing vector element at index '1'
33903386// :111:22: error: use of undefined value here causes illegal behavior
......@@ -3394,13 +3390,17 @@ const std = @import("std");
33943390// :111:22: error: use of undefined value here causes illegal behavior
33953391// :111:22: note: when computing vector element at index '1'
33963392// :111:22: error: use of undefined value here causes illegal behavior
3397// :111:22: note: when computing vector element at index '0'
3393// :111:22: note: when computing vector element at index '1'
33983394// :111:22: error: use of undefined value here causes illegal behavior
3399// :111:22: note: when computing vector element at index '0'
3395// :111:22: note: when computing vector element at index '1'
34003396// :111:22: error: use of undefined value here causes illegal behavior
3401// :111:22: note: when computing vector element at index '0'
3397// :111:22: note: when computing vector element at index '1'
34023398// :111:22: error: use of undefined value here causes illegal behavior
3403// :111:22: note: when computing vector element at index '0'
3399// :111:22: note: when computing vector element at index '1'
3400// :111:22: error: use of undefined value here causes illegal behavior
3401// :111:22: note: when computing vector element at index '1'
3402// :111:22: error: use of undefined value here causes illegal behavior
3403// :111:22: note: when computing vector element at index '1'
34043404// :115:22: error: use of undefined value here causes illegal behavior
34053405// :115:22: error: use of undefined value here causes illegal behavior
34063406// :115:22: error: use of undefined value here causes illegal behavior
......@@ -3408,21 +3408,13 @@ const std = @import("std");
34083408// :115:22: error: use of undefined value here causes illegal behavior
34093409// :115:22: error: use of undefined value here causes illegal behavior
34103410// :115:22: error: use of undefined value here causes illegal behavior
3411// :115:22: note: when computing vector element at index '1'
34123411// :115:22: error: use of undefined value here causes illegal behavior
3413// :115:22: note: when computing vector element at index '1'
34143412// :115:22: error: use of undefined value here causes illegal behavior
3415// :115:22: note: when computing vector element at index '1'
34163413// :115:22: error: use of undefined value here causes illegal behavior
3417// :115:22: note: when computing vector element at index '1'
34183414// :115:22: error: use of undefined value here causes illegal behavior
3419// :115:22: note: when computing vector element at index '0'
34203415// :115:22: error: use of undefined value here causes illegal behavior
3421// :115:22: note: when computing vector element at index '0'
34223416// :115:22: error: use of undefined value here causes illegal behavior
3423// :115:22: note: when computing vector element at index '0'
34243417// :115:22: error: use of undefined value here causes illegal behavior
3425// :115:22: note: when computing vector element at index '0'
34263418// :115:22: error: use of undefined value here causes illegal behavior
34273419// :115:22: error: use of undefined value here causes illegal behavior
34283420// :115:22: error: use of undefined value here causes illegal behavior
......@@ -3430,21 +3422,13 @@ const std = @import("std");
34303422// :115:22: error: use of undefined value here causes illegal behavior
34313423// :115:22: error: use of undefined value here causes illegal behavior
34323424// :115:22: error: use of undefined value here causes illegal behavior
3433// :115:22: note: when computing vector element at index '1'
34343425// :115:22: error: use of undefined value here causes illegal behavior
3435// :115:22: note: when computing vector element at index '1'
34363426// :115:22: error: use of undefined value here causes illegal behavior
3437// :115:22: note: when computing vector element at index '1'
34383427// :115:22: error: use of undefined value here causes illegal behavior
3439// :115:22: note: when computing vector element at index '1'
34403428// :115:22: error: use of undefined value here causes illegal behavior
3441// :115:22: note: when computing vector element at index '0'
34423429// :115:22: error: use of undefined value here causes illegal behavior
3443// :115:22: note: when computing vector element at index '0'
34443430// :115:22: error: use of undefined value here causes illegal behavior
3445// :115:22: note: when computing vector element at index '0'
34463431// :115:22: error: use of undefined value here causes illegal behavior
3447// :115:22: note: when computing vector element at index '0'
34483432// :115:22: error: use of undefined value here causes illegal behavior
34493433// :115:22: error: use of undefined value here causes illegal behavior
34503434// :115:22: error: use of undefined value here causes illegal behavior
......@@ -3452,21 +3436,13 @@ const std = @import("std");
34523436// :115:22: error: use of undefined value here causes illegal behavior
34533437// :115:22: error: use of undefined value here causes illegal behavior
34543438// :115:22: error: use of undefined value here causes illegal behavior
3455// :115:22: note: when computing vector element at index '1'
34563439// :115:22: error: use of undefined value here causes illegal behavior
3457// :115:22: note: when computing vector element at index '1'
34583440// :115:22: error: use of undefined value here causes illegal behavior
3459// :115:22: note: when computing vector element at index '1'
34603441// :115:22: error: use of undefined value here causes illegal behavior
3461// :115:22: note: when computing vector element at index '1'
34623442// :115:22: error: use of undefined value here causes illegal behavior
3463// :115:22: note: when computing vector element at index '0'
34643443// :115:22: error: use of undefined value here causes illegal behavior
3465// :115:22: note: when computing vector element at index '0'
34663444// :115:22: error: use of undefined value here causes illegal behavior
3467// :115:22: note: when computing vector element at index '0'
34683445// :115:22: error: use of undefined value here causes illegal behavior
3469// :115:22: note: when computing vector element at index '0'
34703446// :115:22: error: use of undefined value here causes illegal behavior
34713447// :115:22: error: use of undefined value here causes illegal behavior
34723448// :115:22: error: use of undefined value here causes illegal behavior
......@@ -3474,21 +3450,13 @@ const std = @import("std");
34743450// :115:22: error: use of undefined value here causes illegal behavior
34753451// :115:22: error: use of undefined value here causes illegal behavior
34763452// :115:22: error: use of undefined value here causes illegal behavior
3477// :115:22: note: when computing vector element at index '1'
34783453// :115:22: error: use of undefined value here causes illegal behavior
3479// :115:22: note: when computing vector element at index '1'
34803454// :115:22: error: use of undefined value here causes illegal behavior
3481// :115:22: note: when computing vector element at index '1'
34823455// :115:22: error: use of undefined value here causes illegal behavior
3483// :115:22: note: when computing vector element at index '1'
34843456// :115:22: error: use of undefined value here causes illegal behavior
3485// :115:22: note: when computing vector element at index '0'
34863457// :115:22: error: use of undefined value here causes illegal behavior
3487// :115:22: note: when computing vector element at index '0'
34883458// :115:22: error: use of undefined value here causes illegal behavior
3489// :115:22: note: when computing vector element at index '0'
34903459// :115:22: error: use of undefined value here causes illegal behavior
3491// :115:22: note: when computing vector element at index '0'
34923460// :115:22: error: use of undefined value here causes illegal behavior
34933461// :115:22: error: use of undefined value here causes illegal behavior
34943462// :115:22: error: use of undefined value here causes illegal behavior
......@@ -3496,13 +3464,9 @@ const std = @import("std");
34963464// :115:22: error: use of undefined value here causes illegal behavior
34973465// :115:22: error: use of undefined value here causes illegal behavior
34983466// :115:22: error: use of undefined value here causes illegal behavior
3499// :115:22: note: when computing vector element at index '1'
35003467// :115:22: error: use of undefined value here causes illegal behavior
3501// :115:22: note: when computing vector element at index '1'
35023468// :115:22: error: use of undefined value here causes illegal behavior
3503// :115:22: note: when computing vector element at index '1'
35043469// :115:22: error: use of undefined value here causes illegal behavior
3505// :115:22: note: when computing vector element at index '1'
35063470// :115:22: error: use of undefined value here causes illegal behavior
35073471// :115:22: note: when computing vector element at index '0'
35083472// :115:22: error: use of undefined value here causes illegal behavior
......@@ -3512,19 +3476,21 @@ const std = @import("std");
35123476// :115:22: error: use of undefined value here causes illegal behavior
35133477// :115:22: note: when computing vector element at index '0'
35143478// :115:22: error: use of undefined value here causes illegal behavior
3479// :115:22: note: when computing vector element at index '0'
35153480// :115:22: error: use of undefined value here causes illegal behavior
3481// :115:22: note: when computing vector element at index '0'
35163482// :115:22: error: use of undefined value here causes illegal behavior
3483// :115:22: note: when computing vector element at index '0'
35173484// :115:22: error: use of undefined value here causes illegal behavior
3485// :115:22: note: when computing vector element at index '0'
35183486// :115:22: error: use of undefined value here causes illegal behavior
3487// :115:22: note: when computing vector element at index '0'
35193488// :115:22: error: use of undefined value here causes illegal behavior
3489// :115:22: note: when computing vector element at index '0'
35203490// :115:22: error: use of undefined value here causes illegal behavior
3521// :115:22: note: when computing vector element at index '1'
3522// :115:22: error: use of undefined value here causes illegal behavior
3523// :115:22: note: when computing vector element at index '1'
3524// :115:22: error: use of undefined value here causes illegal behavior
3525// :115:22: note: when computing vector element at index '1'
3491// :115:22: note: when computing vector element at index '0'
35263492// :115:22: error: use of undefined value here causes illegal behavior
3527// :115:22: note: when computing vector element at index '1'
3493// :115:22: note: when computing vector element at index '0'
35283494// :115:22: error: use of undefined value here causes illegal behavior
35293495// :115:22: note: when computing vector element at index '0'
35303496// :115:22: error: use of undefined value here causes illegal behavior
......@@ -3534,19 +3500,25 @@ const std = @import("std");
35343500// :115:22: error: use of undefined value here causes illegal behavior
35353501// :115:22: note: when computing vector element at index '0'
35363502// :115:22: error: use of undefined value here causes illegal behavior
3503// :115:22: note: when computing vector element at index '0'
35373504// :115:22: error: use of undefined value here causes illegal behavior
3505// :115:22: note: when computing vector element at index '0'
35383506// :115:22: error: use of undefined value here causes illegal behavior
3507// :115:22: note: when computing vector element at index '0'
35393508// :115:22: error: use of undefined value here causes illegal behavior
3509// :115:22: note: when computing vector element at index '0'
35403510// :115:22: error: use of undefined value here causes illegal behavior
3511// :115:22: note: when computing vector element at index '0'
35413512// :115:22: error: use of undefined value here causes illegal behavior
3513// :115:22: note: when computing vector element at index '0'
35423514// :115:22: error: use of undefined value here causes illegal behavior
3543// :115:22: note: when computing vector element at index '1'
3515// :115:22: note: when computing vector element at index '0'
35443516// :115:22: error: use of undefined value here causes illegal behavior
3545// :115:22: note: when computing vector element at index '1'
3517// :115:22: note: when computing vector element at index '0'
35463518// :115:22: error: use of undefined value here causes illegal behavior
3547// :115:22: note: when computing vector element at index '1'
3519// :115:22: note: when computing vector element at index '0'
35483520// :115:22: error: use of undefined value here causes illegal behavior
3549// :115:22: note: when computing vector element at index '1'
3521// :115:22: note: when computing vector element at index '0'
35503522// :115:22: error: use of undefined value here causes illegal behavior
35513523// :115:22: note: when computing vector element at index '0'
35523524// :115:22: error: use of undefined value here causes illegal behavior
......@@ -3556,19 +3528,25 @@ const std = @import("std");
35563528// :115:22: error: use of undefined value here causes illegal behavior
35573529// :115:22: note: when computing vector element at index '0'
35583530// :115:22: error: use of undefined value here causes illegal behavior
3531// :115:22: note: when computing vector element at index '0'
35593532// :115:22: error: use of undefined value here causes illegal behavior
3533// :115:22: note: when computing vector element at index '0'
35603534// :115:22: error: use of undefined value here causes illegal behavior
3535// :115:22: note: when computing vector element at index '0'
35613536// :115:22: error: use of undefined value here causes illegal behavior
3537// :115:22: note: when computing vector element at index '0'
35623538// :115:22: error: use of undefined value here causes illegal behavior
3539// :115:22: note: when computing vector element at index '0'
35633540// :115:22: error: use of undefined value here causes illegal behavior
3541// :115:22: note: when computing vector element at index '0'
35643542// :115:22: error: use of undefined value here causes illegal behavior
3565// :115:22: note: when computing vector element at index '1'
3543// :115:22: note: when computing vector element at index '0'
35663544// :115:22: error: use of undefined value here causes illegal behavior
3567// :115:22: note: when computing vector element at index '1'
3545// :115:22: note: when computing vector element at index '0'
35683546// :115:22: error: use of undefined value here causes illegal behavior
3569// :115:22: note: when computing vector element at index '1'
3547// :115:22: note: when computing vector element at index '0'
35703548// :115:22: error: use of undefined value here causes illegal behavior
3571// :115:22: note: when computing vector element at index '1'
3549// :115:22: note: when computing vector element at index '0'
35723550// :115:22: error: use of undefined value here causes illegal behavior
35733551// :115:22: note: when computing vector element at index '0'
35743552// :115:22: error: use of undefined value here causes illegal behavior
......@@ -3578,11 +3556,17 @@ const std = @import("std");
35783556// :115:22: error: use of undefined value here causes illegal behavior
35793557// :115:22: note: when computing vector element at index '0'
35803558// :115:22: error: use of undefined value here causes illegal behavior
3559// :115:22: note: when computing vector element at index '1'
35813560// :115:22: error: use of undefined value here causes illegal behavior
3561// :115:22: note: when computing vector element at index '1'
35823562// :115:22: error: use of undefined value here causes illegal behavior
3563// :115:22: note: when computing vector element at index '1'
35833564// :115:22: error: use of undefined value here causes illegal behavior
3565// :115:22: note: when computing vector element at index '1'
35843566// :115:22: error: use of undefined value here causes illegal behavior
3567// :115:22: note: when computing vector element at index '1'
35853568// :115:22: error: use of undefined value here causes illegal behavior
3569// :115:22: note: when computing vector element at index '1'
35863570// :115:22: error: use of undefined value here causes illegal behavior
35873571// :115:22: note: when computing vector element at index '1'
35883572// :115:22: error: use of undefined value here causes illegal behavior
......@@ -3592,19 +3576,25 @@ const std = @import("std");
35923576// :115:22: error: use of undefined value here causes illegal behavior
35933577// :115:22: note: when computing vector element at index '1'
35943578// :115:22: error: use of undefined value here causes illegal behavior
3595// :115:22: note: when computing vector element at index '0'
3579// :115:22: note: when computing vector element at index '1'
35963580// :115:22: error: use of undefined value here causes illegal behavior
3597// :115:22: note: when computing vector element at index '0'
3581// :115:22: note: when computing vector element at index '1'
35983582// :115:22: error: use of undefined value here causes illegal behavior
3599// :115:22: note: when computing vector element at index '0'
3583// :115:22: note: when computing vector element at index '1'
36003584// :115:22: error: use of undefined value here causes illegal behavior
3601// :115:22: note: when computing vector element at index '0'
3585// :115:22: note: when computing vector element at index '1'
36023586// :115:22: error: use of undefined value here causes illegal behavior
3587// :115:22: note: when computing vector element at index '1'
36033588// :115:22: error: use of undefined value here causes illegal behavior
3589// :115:22: note: when computing vector element at index '1'
36043590// :115:22: error: use of undefined value here causes illegal behavior
3591// :115:22: note: when computing vector element at index '1'
36053592// :115:22: error: use of undefined value here causes illegal behavior
3593// :115:22: note: when computing vector element at index '1'
36063594// :115:22: error: use of undefined value here causes illegal behavior
3595// :115:22: note: when computing vector element at index '1'
36073596// :115:22: error: use of undefined value here causes illegal behavior
3597// :115:22: note: when computing vector element at index '1'
36083598// :115:22: error: use of undefined value here causes illegal behavior
36093599// :115:22: note: when computing vector element at index '1'
36103600// :115:22: error: use of undefined value here causes illegal behavior
......@@ -3614,19 +3604,27 @@ const std = @import("std");
36143604// :115:22: error: use of undefined value here causes illegal behavior
36153605// :115:22: note: when computing vector element at index '1'
36163606// :115:22: error: use of undefined value here causes illegal behavior
3617// :115:22: note: when computing vector element at index '0'
3607// :115:22: note: when computing vector element at index '1'
36183608// :115:22: error: use of undefined value here causes illegal behavior
3619// :115:22: note: when computing vector element at index '0'
3609// :115:22: note: when computing vector element at index '1'
36203610// :115:22: error: use of undefined value here causes illegal behavior
3621// :115:22: note: when computing vector element at index '0'
3611// :115:22: note: when computing vector element at index '1'
36223612// :115:22: error: use of undefined value here causes illegal behavior
3623// :115:22: note: when computing vector element at index '0'
3613// :115:22: note: when computing vector element at index '1'
3614// :115:22: error: use of undefined value here causes illegal behavior
3615// :115:22: note: when computing vector element at index '1'
36243616// :115:22: error: use of undefined value here causes illegal behavior
3617// :115:22: note: when computing vector element at index '1'
36253618// :115:22: error: use of undefined value here causes illegal behavior
3619// :115:22: note: when computing vector element at index '1'
36263620// :115:22: error: use of undefined value here causes illegal behavior
3621// :115:22: note: when computing vector element at index '1'
36273622// :115:22: error: use of undefined value here causes illegal behavior
3623// :115:22: note: when computing vector element at index '1'
36283624// :115:22: error: use of undefined value here causes illegal behavior
3625// :115:22: note: when computing vector element at index '1'
36293626// :115:22: error: use of undefined value here causes illegal behavior
3627// :115:22: note: when computing vector element at index '1'
36303628// :115:22: error: use of undefined value here causes illegal behavior
36313629// :115:22: note: when computing vector element at index '1'
36323630// :115:22: error: use of undefined value here causes illegal behavior
......@@ -3636,37 +3634,32 @@ const std = @import("std");
36363634// :115:22: error: use of undefined value here causes illegal behavior
36373635// :115:22: note: when computing vector element at index '1'
36383636// :115:22: error: use of undefined value here causes illegal behavior
3639// :115:22: note: when computing vector element at index '0'
3637// :115:22: note: when computing vector element at index '1'
36403638// :115:22: error: use of undefined value here causes illegal behavior
3641// :115:22: note: when computing vector element at index '0'
3639// :115:22: note: when computing vector element at index '1'
36423640// :115:22: error: use of undefined value here causes illegal behavior
3643// :115:22: note: when computing vector element at index '0'
3641// :115:22: note: when computing vector element at index '1'
36443642// :115:22: error: use of undefined value here causes illegal behavior
3645// :115:22: note: when computing vector element at index '0'
3643// :115:22: note: when computing vector element at index '1'
3644// :115:22: error: use of undefined value here causes illegal behavior
3645// :115:22: note: when computing vector element at index '1'
3646// :121:17: error: use of undefined value here causes illegal behavior
36463647// :121:17: error: use of undefined value here causes illegal behavior
36473648// :121:17: error: use of undefined value here causes illegal behavior
3648// :121:17: note: when computing vector element at index '0'
36493649// :121:17: error: use of undefined value here causes illegal behavior
3650// :121:17: note: when computing vector element at index '0'
36513650// :121:17: error: use of undefined value here causes illegal behavior
3652// :121:17: note: when computing vector element at index '0'
36533651// :121:17: error: use of undefined value here causes illegal behavior
3654// :121:17: note: when computing vector element at index '1'
36553652// :121:17: error: use of undefined value here causes illegal behavior
3656// :121:17: note: when computing vector element at index '0'
36573653// :121:17: error: use of undefined value here causes illegal behavior
3658// :121:17: note: when computing vector element at index '0'
36593654// :121:17: error: use of undefined value here causes illegal behavior
3660// :121:17: note: when computing vector element at index '0'
36613655// :121:17: error: use of undefined value here causes illegal behavior
36623656// :121:17: error: use of undefined value here causes illegal behavior
3663// :121:17: note: when computing vector element at index '0'
36643657// :121:17: error: use of undefined value here causes illegal behavior
36653658// :121:17: note: when computing vector element at index '0'
36663659// :121:17: error: use of undefined value here causes illegal behavior
36673660// :121:17: note: when computing vector element at index '0'
36683661// :121:17: error: use of undefined value here causes illegal behavior
3669// :121:17: note: when computing vector element at index '1'
3662// :121:17: note: when computing vector element at index '0'
36703663// :121:17: error: use of undefined value here causes illegal behavior
36713664// :121:17: note: when computing vector element at index '0'
36723665// :121:17: error: use of undefined value here causes illegal behavior
......@@ -3674,6 +3667,7 @@ const std = @import("std");
36743667// :121:17: error: use of undefined value here causes illegal behavior
36753668// :121:17: note: when computing vector element at index '0'
36763669// :121:17: error: use of undefined value here causes illegal behavior
3670// :121:17: note: when computing vector element at index '0'
36773671// :121:17: error: use of undefined value here causes illegal behavior
36783672// :121:17: note: when computing vector element at index '0'
36793673// :121:17: error: use of undefined value here causes illegal behavior
......@@ -3681,7 +3675,7 @@ const std = @import("std");
36813675// :121:17: error: use of undefined value here causes illegal behavior
36823676// :121:17: note: when computing vector element at index '0'
36833677// :121:17: error: use of undefined value here causes illegal behavior
3684// :121:17: note: when computing vector element at index '1'
3678// :121:17: note: when computing vector element at index '0'
36853679// :121:17: error: use of undefined value here causes illegal behavior
36863680// :121:17: note: when computing vector element at index '0'
36873681// :121:17: error: use of undefined value here causes illegal behavior
......@@ -3689,6 +3683,7 @@ const std = @import("std");
36893683// :121:17: error: use of undefined value here causes illegal behavior
36903684// :121:17: note: when computing vector element at index '0'
36913685// :121:17: error: use of undefined value here causes illegal behavior
3686// :121:17: note: when computing vector element at index '0'
36923687// :121:17: error: use of undefined value here causes illegal behavior
36933688// :121:17: note: when computing vector element at index '0'
36943689// :121:17: error: use of undefined value here causes illegal behavior
......@@ -3696,7 +3691,7 @@ const std = @import("std");
36963691// :121:17: error: use of undefined value here causes illegal behavior
36973692// :121:17: note: when computing vector element at index '0'
36983693// :121:17: error: use of undefined value here causes illegal behavior
3699// :121:17: note: when computing vector element at index '1'
3694// :121:17: note: when computing vector element at index '0'
37003695// :121:17: error: use of undefined value here causes illegal behavior
37013696// :121:17: note: when computing vector element at index '0'
37023697// :121:17: error: use of undefined value here causes illegal behavior
......@@ -3704,6 +3699,7 @@ const std = @import("std");
37043699// :121:17: error: use of undefined value here causes illegal behavior
37053700// :121:17: note: when computing vector element at index '0'
37063701// :121:17: error: use of undefined value here causes illegal behavior
3702// :121:17: note: when computing vector element at index '0'
37073703// :121:17: error: use of undefined value here causes illegal behavior
37083704// :121:17: note: when computing vector element at index '0'
37093705// :121:17: error: use of undefined value here causes illegal behavior
......@@ -3711,7 +3707,7 @@ const std = @import("std");
37113707// :121:17: error: use of undefined value here causes illegal behavior
37123708// :121:17: note: when computing vector element at index '0'
37133709// :121:17: error: use of undefined value here causes illegal behavior
3714// :121:17: note: when computing vector element at index '1'
3710// :121:17: note: when computing vector element at index '0'
37153711// :121:17: error: use of undefined value here causes illegal behavior
37163712// :121:17: note: when computing vector element at index '0'
37173713// :121:17: error: use of undefined value here causes illegal behavior
......@@ -3719,6 +3715,7 @@ const std = @import("std");
37193715// :121:17: error: use of undefined value here causes illegal behavior
37203716// :121:17: note: when computing vector element at index '0'
37213717// :121:17: error: use of undefined value here causes illegal behavior
3718// :121:17: note: when computing vector element at index '0'
37223719// :121:17: error: use of undefined value here causes illegal behavior
37233720// :121:17: note: when computing vector element at index '0'
37243721// :121:17: error: use of undefined value here causes illegal behavior
......@@ -3726,7 +3723,7 @@ const std = @import("std");
37263723// :121:17: error: use of undefined value here causes illegal behavior
37273724// :121:17: note: when computing vector element at index '0'
37283725// :121:17: error: use of undefined value here causes illegal behavior
3729// :121:17: note: when computing vector element at index '1'
3726// :121:17: note: when computing vector element at index '0'
37303727// :121:17: error: use of undefined value here causes illegal behavior
37313728// :121:17: note: when computing vector element at index '0'
37323729// :121:17: error: use of undefined value here causes illegal behavior
......@@ -3734,6 +3731,7 @@ const std = @import("std");
37343731// :121:17: error: use of undefined value here causes illegal behavior
37353732// :121:17: note: when computing vector element at index '0'
37363733// :121:17: error: use of undefined value here causes illegal behavior
3734// :121:17: note: when computing vector element at index '0'
37373735// :121:17: error: use of undefined value here causes illegal behavior
37383736// :121:17: note: when computing vector element at index '0'
37393737// :121:17: error: use of undefined value here causes illegal behavior
......@@ -3741,7 +3739,7 @@ const std = @import("std");
37413739// :121:17: error: use of undefined value here causes illegal behavior
37423740// :121:17: note: when computing vector element at index '0'
37433741// :121:17: error: use of undefined value here causes illegal behavior
3744// :121:17: note: when computing vector element at index '1'
3742// :121:17: note: when computing vector element at index '0'
37453743// :121:17: error: use of undefined value here causes illegal behavior
37463744// :121:17: note: when computing vector element at index '0'
37473745// :121:17: error: use of undefined value here causes illegal behavior
......@@ -3749,6 +3747,7 @@ const std = @import("std");
37493747// :121:17: error: use of undefined value here causes illegal behavior
37503748// :121:17: note: when computing vector element at index '0'
37513749// :121:17: error: use of undefined value here causes illegal behavior
3750// :121:17: note: when computing vector element at index '0'
37523751// :121:17: error: use of undefined value here causes illegal behavior
37533752// :121:17: note: when computing vector element at index '0'
37543753// :121:17: error: use of undefined value here causes illegal behavior
......@@ -3756,7 +3755,7 @@ const std = @import("std");
37563755// :121:17: error: use of undefined value here causes illegal behavior
37573756// :121:17: note: when computing vector element at index '0'
37583757// :121:17: error: use of undefined value here causes illegal behavior
3759// :121:17: note: when computing vector element at index '1'
3758// :121:17: note: when computing vector element at index '0'
37603759// :121:17: error: use of undefined value here causes illegal behavior
37613760// :121:17: note: when computing vector element at index '0'
37623761// :121:17: error: use of undefined value here causes illegal behavior
......@@ -3764,6 +3763,7 @@ const std = @import("std");
37643763// :121:17: error: use of undefined value here causes illegal behavior
37653764// :121:17: note: when computing vector element at index '0'
37663765// :121:17: error: use of undefined value here causes illegal behavior
3766// :121:17: note: when computing vector element at index '0'
37673767// :121:17: error: use of undefined value here causes illegal behavior
37683768// :121:17: note: when computing vector element at index '0'
37693769// :121:17: error: use of undefined value here causes illegal behavior
......@@ -3771,7 +3771,7 @@ const std = @import("std");
37713771// :121:17: error: use of undefined value here causes illegal behavior
37723772// :121:17: note: when computing vector element at index '0'
37733773// :121:17: error: use of undefined value here causes illegal behavior
3774// :121:17: note: when computing vector element at index '1'
3774// :121:17: note: when computing vector element at index '0'
37753775// :121:17: error: use of undefined value here causes illegal behavior
37763776// :121:17: note: when computing vector element at index '0'
37773777// :121:17: error: use of undefined value here causes illegal behavior
......@@ -3779,6 +3779,7 @@ const std = @import("std");
37793779// :121:17: error: use of undefined value here causes illegal behavior
37803780// :121:17: note: when computing vector element at index '0'
37813781// :121:17: error: use of undefined value here causes illegal behavior
3782// :121:17: note: when computing vector element at index '0'
37823783// :121:17: error: use of undefined value here causes illegal behavior
37833784// :121:17: note: when computing vector element at index '0'
37843785// :121:17: error: use of undefined value here causes illegal behavior
......@@ -3788,126 +3789,120 @@ const std = @import("std");
37883789// :121:17: error: use of undefined value here causes illegal behavior
37893790// :121:17: note: when computing vector element at index '1'
37903791// :121:17: error: use of undefined value here causes illegal behavior
3791// :121:17: note: when computing vector element at index '0'
3792// :121:17: error: use of undefined value here causes illegal behavior
3793// :121:17: note: when computing vector element at index '0'
3792// :121:17: note: when computing vector element at index '1'
37943793// :121:17: error: use of undefined value here causes illegal behavior
3795// :121:17: note: when computing vector element at index '0'
3794// :121:17: note: when computing vector element at index '1'
37963795// :121:17: error: use of undefined value here causes illegal behavior
3796// :121:17: note: when computing vector element at index '1'
37973797// :121:17: error: use of undefined value here causes illegal behavior
3798// :121:17: note: when computing vector element at index '0'
3798// :121:17: note: when computing vector element at index '1'
37993799// :121:17: error: use of undefined value here causes illegal behavior
3800// :121:17: note: when computing vector element at index '0'
3800// :121:17: note: when computing vector element at index '1'
38013801// :121:17: error: use of undefined value here causes illegal behavior
3802// :121:17: note: when computing vector element at index '0'
3802// :121:17: note: when computing vector element at index '1'
38033803// :121:17: error: use of undefined value here causes illegal behavior
38043804// :121:17: note: when computing vector element at index '1'
38053805// :121:17: error: use of undefined value here causes illegal behavior
3806// :121:17: note: when computing vector element at index '0'
3806// :121:17: note: when computing vector element at index '1'
38073807// :121:17: error: use of undefined value here causes illegal behavior
3808// :121:17: note: when computing vector element at index '0'
3808// :121:17: note: when computing vector element at index '1'
38093809// :121:17: error: use of undefined value here causes illegal behavior
3810// :121:17: note: when computing vector element at index '0'
3810// :121:17: note: when computing vector element at index '1'
38113811// :121:21: error: use of undefined value here causes illegal behavior
38123812// :121:21: error: use of undefined value here causes illegal behavior
3813// :121:21: note: when computing vector element at index '0'
38143813// :121:21: error: use of undefined value here causes illegal behavior
3815// :121:21: note: when computing vector element at index '0'
38163814// :121:21: error: use of undefined value here causes illegal behavior
3817// :121:21: note: when computing vector element at index '1'
38183815// :121:21: error: use of undefined value here causes illegal behavior
3819// :121:21: note: when computing vector element at index '0'
38203816// :121:21: error: use of undefined value here causes illegal behavior
3821// :121:21: note: when computing vector element at index '0'
38223817// :121:21: error: use of undefined value here causes illegal behavior
38233818// :121:21: error: use of undefined value here causes illegal behavior
3824// :121:21: note: when computing vector element at index '0'
38253819// :121:21: error: use of undefined value here causes illegal behavior
3826// :121:21: note: when computing vector element at index '0'
38273820// :121:21: error: use of undefined value here causes illegal behavior
3828// :121:21: note: when computing vector element at index '1'
38293821// :121:21: error: use of undefined value here causes illegal behavior
3830// :121:21: note: when computing vector element at index '0'
38313822// :121:21: error: use of undefined value here causes illegal behavior
38323823// :121:21: note: when computing vector element at index '0'
38333824// :121:21: error: use of undefined value here causes illegal behavior
3834// :121:21: error: use of undefined value here causes illegal behavior
38353825// :121:21: note: when computing vector element at index '0'
38363826// :121:21: error: use of undefined value here causes illegal behavior
38373827// :121:21: note: when computing vector element at index '0'
38383828// :121:21: error: use of undefined value here causes illegal behavior
3839// :121:21: note: when computing vector element at index '1'
3840// :121:21: error: use of undefined value here causes illegal behavior
38413829// :121:21: note: when computing vector element at index '0'
38423830// :121:21: error: use of undefined value here causes illegal behavior
38433831// :121:21: note: when computing vector element at index '0'
38443832// :121:21: error: use of undefined value here causes illegal behavior
3833// :121:21: note: when computing vector element at index '0'
38453834// :121:21: error: use of undefined value here causes illegal behavior
38463835// :121:21: note: when computing vector element at index '0'
38473836// :121:21: error: use of undefined value here causes illegal behavior
38483837// :121:21: note: when computing vector element at index '0'
38493838// :121:21: error: use of undefined value here causes illegal behavior
3850// :121:21: note: when computing vector element at index '1'
3839// :121:21: note: when computing vector element at index '0'
38513840// :121:21: error: use of undefined value here causes illegal behavior
38523841// :121:21: note: when computing vector element at index '0'
38533842// :121:21: error: use of undefined value here causes illegal behavior
38543843// :121:21: note: when computing vector element at index '0'
38553844// :121:21: error: use of undefined value here causes illegal behavior
3845// :121:21: note: when computing vector element at index '0'
38563846// :121:21: error: use of undefined value here causes illegal behavior
38573847// :121:21: note: when computing vector element at index '0'
38583848// :121:21: error: use of undefined value here causes illegal behavior
38593849// :121:21: note: when computing vector element at index '0'
38603850// :121:21: error: use of undefined value here causes illegal behavior
3861// :121:21: note: when computing vector element at index '1'
3851// :121:21: note: when computing vector element at index '0'
38623852// :121:21: error: use of undefined value here causes illegal behavior
38633853// :121:21: note: when computing vector element at index '0'
38643854// :121:21: error: use of undefined value here causes illegal behavior
38653855// :121:21: note: when computing vector element at index '0'
38663856// :121:21: error: use of undefined value here causes illegal behavior
3857// :121:21: note: when computing vector element at index '0'
38673858// :121:21: error: use of undefined value here causes illegal behavior
38683859// :121:21: note: when computing vector element at index '0'
38693860// :121:21: error: use of undefined value here causes illegal behavior
38703861// :121:21: note: when computing vector element at index '0'
38713862// :121:21: error: use of undefined value here causes illegal behavior
3872// :121:21: note: when computing vector element at index '1'
3863// :121:21: note: when computing vector element at index '0'
38733864// :121:21: error: use of undefined value here causes illegal behavior
38743865// :121:21: note: when computing vector element at index '0'
38753866// :121:21: error: use of undefined value here causes illegal behavior
38763867// :121:21: note: when computing vector element at index '0'
38773868// :121:21: error: use of undefined value here causes illegal behavior
3869// :121:21: note: when computing vector element at index '0'
38783870// :121:21: error: use of undefined value here causes illegal behavior
38793871// :121:21: note: when computing vector element at index '0'
38803872// :121:21: error: use of undefined value here causes illegal behavior
38813873// :121:21: note: when computing vector element at index '0'
38823874// :121:21: error: use of undefined value here causes illegal behavior
3883// :121:21: note: when computing vector element at index '1'
3875// :121:21: note: when computing vector element at index '0'
38843876// :121:21: error: use of undefined value here causes illegal behavior
38853877// :121:21: note: when computing vector element at index '0'
38863878// :121:21: error: use of undefined value here causes illegal behavior
38873879// :121:21: note: when computing vector element at index '0'
38883880// :121:21: error: use of undefined value here causes illegal behavior
3881// :121:21: note: when computing vector element at index '0'
38893882// :121:21: error: use of undefined value here causes illegal behavior
38903883// :121:21: note: when computing vector element at index '0'
38913884// :121:21: error: use of undefined value here causes illegal behavior
38923885// :121:21: note: when computing vector element at index '0'
38933886// :121:21: error: use of undefined value here causes illegal behavior
3894// :121:21: note: when computing vector element at index '1'
3887// :121:21: note: when computing vector element at index '0'
38953888// :121:21: error: use of undefined value here causes illegal behavior
38963889// :121:21: note: when computing vector element at index '0'
38973890// :121:21: error: use of undefined value here causes illegal behavior
38983891// :121:21: note: when computing vector element at index '0'
38993892// :121:21: error: use of undefined value here causes illegal behavior
3893// :121:21: note: when computing vector element at index '0'
39003894// :121:21: error: use of undefined value here causes illegal behavior
39013895// :121:21: note: when computing vector element at index '0'
39023896// :121:21: error: use of undefined value here causes illegal behavior
39033897// :121:21: note: when computing vector element at index '0'
39043898// :121:21: error: use of undefined value here causes illegal behavior
3905// :121:21: note: when computing vector element at index '1'
3899// :121:21: note: when computing vector element at index '0'
39063900// :121:21: error: use of undefined value here causes illegal behavior
39073901// :121:21: note: when computing vector element at index '0'
39083902// :121:21: error: use of undefined value here causes illegal behavior
39093903// :121:21: note: when computing vector element at index '0'
39103904// :121:21: error: use of undefined value here causes illegal behavior
3905// :121:21: note: when computing vector element at index '0'
39113906// :121:21: error: use of undefined value here causes illegal behavior
39123907// :121:21: note: when computing vector element at index '0'
39133908// :121:21: error: use of undefined value here causes illegal behavior
......@@ -3915,44 +3910,42 @@ const std = @import("std");
39153910// :121:21: error: use of undefined value here causes illegal behavior
39163911// :121:21: note: when computing vector element at index '1'
39173912// :121:21: error: use of undefined value here causes illegal behavior
3918// :121:21: note: when computing vector element at index '0'
3913// :121:21: note: when computing vector element at index '1'
39193914// :121:21: error: use of undefined value here causes illegal behavior
3920// :121:21: note: when computing vector element at index '0'
3915// :121:21: note: when computing vector element at index '1'
39213916// :121:21: error: use of undefined value here causes illegal behavior
3917// :121:21: note: when computing vector element at index '1'
39223918// :121:21: error: use of undefined value here causes illegal behavior
3923// :121:21: note: when computing vector element at index '0'
3919// :121:21: note: when computing vector element at index '1'
39243920// :121:21: error: use of undefined value here causes illegal behavior
3925// :121:21: note: when computing vector element at index '0'
3921// :121:21: note: when computing vector element at index '1'
39263922// :121:21: error: use of undefined value here causes illegal behavior
39273923// :121:21: note: when computing vector element at index '1'
39283924// :121:21: error: use of undefined value here causes illegal behavior
3929// :121:21: note: when computing vector element at index '0'
3925// :121:21: note: when computing vector element at index '1'
39303926// :121:21: error: use of undefined value here causes illegal behavior
3931// :121:21: note: when computing vector element at index '0'
3927// :121:21: note: when computing vector element at index '1'
3928// :121:21: error: use of undefined value here causes illegal behavior
3929// :121:21: note: when computing vector element at index '1'
3930// :121:21: error: use of undefined value here causes illegal behavior
3931// :121:21: note: when computing vector element at index '1'
3932// :125:27: error: use of undefined value here causes illegal behavior
39323933// :125:27: error: use of undefined value here causes illegal behavior
39333934// :125:27: error: use of undefined value here causes illegal behavior
3934// :125:27: note: when computing vector element at index '0'
39353935// :125:27: error: use of undefined value here causes illegal behavior
3936// :125:27: note: when computing vector element at index '0'
39373936// :125:27: error: use of undefined value here causes illegal behavior
3938// :125:27: note: when computing vector element at index '0'
39393937// :125:27: error: use of undefined value here causes illegal behavior
3940// :125:27: note: when computing vector element at index '1'
39413938// :125:27: error: use of undefined value here causes illegal behavior
3942// :125:27: note: when computing vector element at index '0'
39433939// :125:27: error: use of undefined value here causes illegal behavior
3944// :125:27: note: when computing vector element at index '0'
39453940// :125:27: error: use of undefined value here causes illegal behavior
3946// :125:27: note: when computing vector element at index '0'
39473941// :125:27: error: use of undefined value here causes illegal behavior
39483942// :125:27: error: use of undefined value here causes illegal behavior
3949// :125:27: note: when computing vector element at index '0'
39503943// :125:27: error: use of undefined value here causes illegal behavior
39513944// :125:27: note: when computing vector element at index '0'
39523945// :125:27: error: use of undefined value here causes illegal behavior
39533946// :125:27: note: when computing vector element at index '0'
39543947// :125:27: error: use of undefined value here causes illegal behavior
3955// :125:27: note: when computing vector element at index '1'
3948// :125:27: note: when computing vector element at index '0'
39563949// :125:27: error: use of undefined value here causes illegal behavior
39573950// :125:27: note: when computing vector element at index '0'
39583951// :125:27: error: use of undefined value here causes illegal behavior
......@@ -3960,6 +3953,7 @@ const std = @import("std");
39603953// :125:27: error: use of undefined value here causes illegal behavior
39613954// :125:27: note: when computing vector element at index '0'
39623955// :125:27: error: use of undefined value here causes illegal behavior
3956// :125:27: note: when computing vector element at index '0'
39633957// :125:27: error: use of undefined value here causes illegal behavior
39643958// :125:27: note: when computing vector element at index '0'
39653959// :125:27: error: use of undefined value here causes illegal behavior
......@@ -3967,7 +3961,7 @@ const std = @import("std");
39673961// :125:27: error: use of undefined value here causes illegal behavior
39683962// :125:27: note: when computing vector element at index '0'
39693963// :125:27: error: use of undefined value here causes illegal behavior
3970// :125:27: note: when computing vector element at index '1'
3964// :125:27: note: when computing vector element at index '0'
39713965// :125:27: error: use of undefined value here causes illegal behavior
39723966// :125:27: note: when computing vector element at index '0'
39733967// :125:27: error: use of undefined value here causes illegal behavior
......@@ -3975,6 +3969,7 @@ const std = @import("std");
39753969// :125:27: error: use of undefined value here causes illegal behavior
39763970// :125:27: note: when computing vector element at index '0'
39773971// :125:27: error: use of undefined value here causes illegal behavior
3972// :125:27: note: when computing vector element at index '0'
39783973// :125:27: error: use of undefined value here causes illegal behavior
39793974// :125:27: note: when computing vector element at index '0'
39803975// :125:27: error: use of undefined value here causes illegal behavior
......@@ -3982,7 +3977,7 @@ const std = @import("std");
39823977// :125:27: error: use of undefined value here causes illegal behavior
39833978// :125:27: note: when computing vector element at index '0'
39843979// :125:27: error: use of undefined value here causes illegal behavior
3985// :125:27: note: when computing vector element at index '1'
3980// :125:27: note: when computing vector element at index '0'
39863981// :125:27: error: use of undefined value here causes illegal behavior
39873982// :125:27: note: when computing vector element at index '0'
39883983// :125:27: error: use of undefined value here causes illegal behavior
......@@ -3990,6 +3985,7 @@ const std = @import("std");
39903985// :125:27: error: use of undefined value here causes illegal behavior
39913986// :125:27: note: when computing vector element at index '0'
39923987// :125:27: error: use of undefined value here causes illegal behavior
3988// :125:27: note: when computing vector element at index '0'
39933989// :125:27: error: use of undefined value here causes illegal behavior
39943990// :125:27: note: when computing vector element at index '0'
39953991// :125:27: error: use of undefined value here causes illegal behavior
......@@ -3997,7 +3993,7 @@ const std = @import("std");
39973993// :125:27: error: use of undefined value here causes illegal behavior
39983994// :125:27: note: when computing vector element at index '0'
39993995// :125:27: error: use of undefined value here causes illegal behavior
4000// :125:27: note: when computing vector element at index '1'
3996// :125:27: note: when computing vector element at index '0'
40013997// :125:27: error: use of undefined value here causes illegal behavior
40023998// :125:27: note: when computing vector element at index '0'
40033999// :125:27: error: use of undefined value here causes illegal behavior
......@@ -4005,6 +4001,7 @@ const std = @import("std");
40054001// :125:27: error: use of undefined value here causes illegal behavior
40064002// :125:27: note: when computing vector element at index '0'
40074003// :125:27: error: use of undefined value here causes illegal behavior
4004// :125:27: note: when computing vector element at index '0'
40084005// :125:27: error: use of undefined value here causes illegal behavior
40094006// :125:27: note: when computing vector element at index '0'
40104007// :125:27: error: use of undefined value here causes illegal behavior
......@@ -4012,7 +4009,7 @@ const std = @import("std");
40124009// :125:27: error: use of undefined value here causes illegal behavior
40134010// :125:27: note: when computing vector element at index '0'
40144011// :125:27: error: use of undefined value here causes illegal behavior
4015// :125:27: note: when computing vector element at index '1'
4012// :125:27: note: when computing vector element at index '0'
40164013// :125:27: error: use of undefined value here causes illegal behavior
40174014// :125:27: note: when computing vector element at index '0'
40184015// :125:27: error: use of undefined value here causes illegal behavior
......@@ -4020,6 +4017,7 @@ const std = @import("std");
40204017// :125:27: error: use of undefined value here causes illegal behavior
40214018// :125:27: note: when computing vector element at index '0'
40224019// :125:27: error: use of undefined value here causes illegal behavior
4020// :125:27: note: when computing vector element at index '0'
40234021// :125:27: error: use of undefined value here causes illegal behavior
40244022// :125:27: note: when computing vector element at index '0'
40254023// :125:27: error: use of undefined value here causes illegal behavior
......@@ -4027,7 +4025,7 @@ const std = @import("std");
40274025// :125:27: error: use of undefined value here causes illegal behavior
40284026// :125:27: note: when computing vector element at index '0'
40294027// :125:27: error: use of undefined value here causes illegal behavior
4030// :125:27: note: when computing vector element at index '1'
4028// :125:27: note: when computing vector element at index '0'
40314029// :125:27: error: use of undefined value here causes illegal behavior
40324030// :125:27: note: when computing vector element at index '0'
40334031// :125:27: error: use of undefined value here causes illegal behavior
......@@ -4035,6 +4033,7 @@ const std = @import("std");
40354033// :125:27: error: use of undefined value here causes illegal behavior
40364034// :125:27: note: when computing vector element at index '0'
40374035// :125:27: error: use of undefined value here causes illegal behavior
4036// :125:27: note: when computing vector element at index '0'
40384037// :125:27: error: use of undefined value here causes illegal behavior
40394038// :125:27: note: when computing vector element at index '0'
40404039// :125:27: error: use of undefined value here causes illegal behavior
......@@ -4042,7 +4041,7 @@ const std = @import("std");
40424041// :125:27: error: use of undefined value here causes illegal behavior
40434042// :125:27: note: when computing vector element at index '0'
40444043// :125:27: error: use of undefined value here causes illegal behavior
4045// :125:27: note: when computing vector element at index '1'
4044// :125:27: note: when computing vector element at index '0'
40464045// :125:27: error: use of undefined value here causes illegal behavior
40474046// :125:27: note: when computing vector element at index '0'
40484047// :125:27: error: use of undefined value here causes illegal behavior
......@@ -4050,6 +4049,7 @@ const std = @import("std");
40504049// :125:27: error: use of undefined value here causes illegal behavior
40514050// :125:27: note: when computing vector element at index '0'
40524051// :125:27: error: use of undefined value here causes illegal behavior
4052// :125:27: note: when computing vector element at index '0'
40534053// :125:27: error: use of undefined value here causes illegal behavior
40544054// :125:27: note: when computing vector element at index '0'
40554055// :125:27: error: use of undefined value here causes illegal behavior
......@@ -4057,7 +4057,7 @@ const std = @import("std");
40574057// :125:27: error: use of undefined value here causes illegal behavior
40584058// :125:27: note: when computing vector element at index '0'
40594059// :125:27: error: use of undefined value here causes illegal behavior
4060// :125:27: note: when computing vector element at index '1'
4060// :125:27: note: when computing vector element at index '0'
40614061// :125:27: error: use of undefined value here causes illegal behavior
40624062// :125:27: note: when computing vector element at index '0'
40634063// :125:27: error: use of undefined value here causes illegal behavior
......@@ -4065,6 +4065,7 @@ const std = @import("std");
40654065// :125:27: error: use of undefined value here causes illegal behavior
40664066// :125:27: note: when computing vector element at index '0'
40674067// :125:27: error: use of undefined value here causes illegal behavior
4068// :125:27: note: when computing vector element at index '0'
40684069// :125:27: error: use of undefined value here causes illegal behavior
40694070// :125:27: note: when computing vector element at index '0'
40704071// :125:27: error: use of undefined value here causes illegal behavior
......@@ -4074,126 +4075,120 @@ const std = @import("std");
40744075// :125:27: error: use of undefined value here causes illegal behavior
40754076// :125:27: note: when computing vector element at index '1'
40764077// :125:27: error: use of undefined value here causes illegal behavior
4077// :125:27: note: when computing vector element at index '0'
4078// :125:27: error: use of undefined value here causes illegal behavior
4079// :125:27: note: when computing vector element at index '0'
4078// :125:27: note: when computing vector element at index '1'
40804079// :125:27: error: use of undefined value here causes illegal behavior
4081// :125:27: note: when computing vector element at index '0'
4080// :125:27: note: when computing vector element at index '1'
40824081// :125:27: error: use of undefined value here causes illegal behavior
4082// :125:27: note: when computing vector element at index '1'
40834083// :125:27: error: use of undefined value here causes illegal behavior
4084// :125:27: note: when computing vector element at index '0'
4084// :125:27: note: when computing vector element at index '1'
40854085// :125:27: error: use of undefined value here causes illegal behavior
4086// :125:27: note: when computing vector element at index '0'
4086// :125:27: note: when computing vector element at index '1'
40874087// :125:27: error: use of undefined value here causes illegal behavior
4088// :125:27: note: when computing vector element at index '0'
4088// :125:27: note: when computing vector element at index '1'
40894089// :125:27: error: use of undefined value here causes illegal behavior
40904090// :125:27: note: when computing vector element at index '1'
40914091// :125:27: error: use of undefined value here causes illegal behavior
4092// :125:27: note: when computing vector element at index '0'
4092// :125:27: note: when computing vector element at index '1'
40934093// :125:27: error: use of undefined value here causes illegal behavior
4094// :125:27: note: when computing vector element at index '0'
4094// :125:27: note: when computing vector element at index '1'
40954095// :125:27: error: use of undefined value here causes illegal behavior
4096// :125:27: note: when computing vector element at index '0'
4096// :125:27: note: when computing vector element at index '1'
40974097// :125:30: error: use of undefined value here causes illegal behavior
40984098// :125:30: error: use of undefined value here causes illegal behavior
4099// :125:30: note: when computing vector element at index '0'
41004099// :125:30: error: use of undefined value here causes illegal behavior
4101// :125:30: note: when computing vector element at index '0'
41024100// :125:30: error: use of undefined value here causes illegal behavior
4103// :125:30: note: when computing vector element at index '1'
41044101// :125:30: error: use of undefined value here causes illegal behavior
4105// :125:30: note: when computing vector element at index '0'
41064102// :125:30: error: use of undefined value here causes illegal behavior
4107// :125:30: note: when computing vector element at index '0'
41084103// :125:30: error: use of undefined value here causes illegal behavior
41094104// :125:30: error: use of undefined value here causes illegal behavior
4110// :125:30: note: when computing vector element at index '0'
41114105// :125:30: error: use of undefined value here causes illegal behavior
4112// :125:30: note: when computing vector element at index '0'
41134106// :125:30: error: use of undefined value here causes illegal behavior
4114// :125:30: note: when computing vector element at index '1'
41154107// :125:30: error: use of undefined value here causes illegal behavior
4116// :125:30: note: when computing vector element at index '0'
41174108// :125:30: error: use of undefined value here causes illegal behavior
41184109// :125:30: note: when computing vector element at index '0'
41194110// :125:30: error: use of undefined value here causes illegal behavior
4120// :125:30: error: use of undefined value here causes illegal behavior
41214111// :125:30: note: when computing vector element at index '0'
41224112// :125:30: error: use of undefined value here causes illegal behavior
41234113// :125:30: note: when computing vector element at index '0'
41244114// :125:30: error: use of undefined value here causes illegal behavior
4125// :125:30: note: when computing vector element at index '1'
4126// :125:30: error: use of undefined value here causes illegal behavior
41274115// :125:30: note: when computing vector element at index '0'
41284116// :125:30: error: use of undefined value here causes illegal behavior
41294117// :125:30: note: when computing vector element at index '0'
41304118// :125:30: error: use of undefined value here causes illegal behavior
4119// :125:30: note: when computing vector element at index '0'
41314120// :125:30: error: use of undefined value here causes illegal behavior
41324121// :125:30: note: when computing vector element at index '0'
41334122// :125:30: error: use of undefined value here causes illegal behavior
41344123// :125:30: note: when computing vector element at index '0'
41354124// :125:30: error: use of undefined value here causes illegal behavior
4136// :125:30: note: when computing vector element at index '1'
4125// :125:30: note: when computing vector element at index '0'
41374126// :125:30: error: use of undefined value here causes illegal behavior
41384127// :125:30: note: when computing vector element at index '0'
41394128// :125:30: error: use of undefined value here causes illegal behavior
41404129// :125:30: note: when computing vector element at index '0'
41414130// :125:30: error: use of undefined value here causes illegal behavior
4131// :125:30: note: when computing vector element at index '0'
41424132// :125:30: error: use of undefined value here causes illegal behavior
41434133// :125:30: note: when computing vector element at index '0'
41444134// :125:30: error: use of undefined value here causes illegal behavior
41454135// :125:30: note: when computing vector element at index '0'
41464136// :125:30: error: use of undefined value here causes illegal behavior
4147// :125:30: note: when computing vector element at index '1'
4137// :125:30: note: when computing vector element at index '0'
41484138// :125:30: error: use of undefined value here causes illegal behavior
41494139// :125:30: note: when computing vector element at index '0'
41504140// :125:30: error: use of undefined value here causes illegal behavior
41514141// :125:30: note: when computing vector element at index '0'
41524142// :125:30: error: use of undefined value here causes illegal behavior
4143// :125:30: note: when computing vector element at index '0'
41534144// :125:30: error: use of undefined value here causes illegal behavior
41544145// :125:30: note: when computing vector element at index '0'
41554146// :125:30: error: use of undefined value here causes illegal behavior
41564147// :125:30: note: when computing vector element at index '0'
41574148// :125:30: error: use of undefined value here causes illegal behavior
4158// :125:30: note: when computing vector element at index '1'
4149// :125:30: note: when computing vector element at index '0'
41594150// :125:30: error: use of undefined value here causes illegal behavior
41604151// :125:30: note: when computing vector element at index '0'
41614152// :125:30: error: use of undefined value here causes illegal behavior
41624153// :125:30: note: when computing vector element at index '0'
41634154// :125:30: error: use of undefined value here causes illegal behavior
4155// :125:30: note: when computing vector element at index '0'
41644156// :125:30: error: use of undefined value here causes illegal behavior
41654157// :125:30: note: when computing vector element at index '0'
41664158// :125:30: error: use of undefined value here causes illegal behavior
41674159// :125:30: note: when computing vector element at index '0'
41684160// :125:30: error: use of undefined value here causes illegal behavior
4169// :125:30: note: when computing vector element at index '1'
4161// :125:30: note: when computing vector element at index '0'
41704162// :125:30: error: use of undefined value here causes illegal behavior
41714163// :125:30: note: when computing vector element at index '0'
41724164// :125:30: error: use of undefined value here causes illegal behavior
41734165// :125:30: note: when computing vector element at index '0'
41744166// :125:30: error: use of undefined value here causes illegal behavior
4167// :125:30: note: when computing vector element at index '0'
41754168// :125:30: error: use of undefined value here causes illegal behavior
41764169// :125:30: note: when computing vector element at index '0'
41774170// :125:30: error: use of undefined value here causes illegal behavior
41784171// :125:30: note: when computing vector element at index '0'
41794172// :125:30: error: use of undefined value here causes illegal behavior
4180// :125:30: note: when computing vector element at index '1'
4173// :125:30: note: when computing vector element at index '0'
41814174// :125:30: error: use of undefined value here causes illegal behavior
41824175// :125:30: note: when computing vector element at index '0'
41834176// :125:30: error: use of undefined value here causes illegal behavior
41844177// :125:30: note: when computing vector element at index '0'
41854178// :125:30: error: use of undefined value here causes illegal behavior
4179// :125:30: note: when computing vector element at index '0'
41864180// :125:30: error: use of undefined value here causes illegal behavior
41874181// :125:30: note: when computing vector element at index '0'
41884182// :125:30: error: use of undefined value here causes illegal behavior
41894183// :125:30: note: when computing vector element at index '0'
41904184// :125:30: error: use of undefined value here causes illegal behavior
4191// :125:30: note: when computing vector element at index '1'
4185// :125:30: note: when computing vector element at index '0'
41924186// :125:30: error: use of undefined value here causes illegal behavior
41934187// :125:30: note: when computing vector element at index '0'
41944188// :125:30: error: use of undefined value here causes illegal behavior
41954189// :125:30: note: when computing vector element at index '0'
41964190// :125:30: error: use of undefined value here causes illegal behavior
4191// :125:30: note: when computing vector element at index '0'
41974192// :125:30: error: use of undefined value here causes illegal behavior
41984193// :125:30: note: when computing vector element at index '0'
41994194// :125:30: error: use of undefined value here causes illegal behavior
......@@ -4201,44 +4196,42 @@ const std = @import("std");
42014196// :125:30: error: use of undefined value here causes illegal behavior
42024197// :125:30: note: when computing vector element at index '1'
42034198// :125:30: error: use of undefined value here causes illegal behavior
4204// :125:30: note: when computing vector element at index '0'
4199// :125:30: note: when computing vector element at index '1'
42054200// :125:30: error: use of undefined value here causes illegal behavior
4206// :125:30: note: when computing vector element at index '0'
4201// :125:30: note: when computing vector element at index '1'
42074202// :125:30: error: use of undefined value here causes illegal behavior
4203// :125:30: note: when computing vector element at index '1'
42084204// :125:30: error: use of undefined value here causes illegal behavior
4209// :125:30: note: when computing vector element at index '0'
4205// :125:30: note: when computing vector element at index '1'
42104206// :125:30: error: use of undefined value here causes illegal behavior
4211// :125:30: note: when computing vector element at index '0'
4207// :125:30: note: when computing vector element at index '1'
42124208// :125:30: error: use of undefined value here causes illegal behavior
42134209// :125:30: note: when computing vector element at index '1'
42144210// :125:30: error: use of undefined value here causes illegal behavior
4215// :125:30: note: when computing vector element at index '0'
4211// :125:30: note: when computing vector element at index '1'
42164212// :125:30: error: use of undefined value here causes illegal behavior
4217// :125:30: note: when computing vector element at index '0'
4213// :125:30: note: when computing vector element at index '1'
4214// :125:30: error: use of undefined value here causes illegal behavior
4215// :125:30: note: when computing vector element at index '1'
4216// :125:30: error: use of undefined value here causes illegal behavior
4217// :125:30: note: when computing vector element at index '1'
4218// :129:27: error: use of undefined value here causes illegal behavior
42184219// :129:27: error: use of undefined value here causes illegal behavior
42194220// :129:27: error: use of undefined value here causes illegal behavior
4220// :129:27: note: when computing vector element at index '0'
42214221// :129:27: error: use of undefined value here causes illegal behavior
4222// :129:27: note: when computing vector element at index '0'
42234222// :129:27: error: use of undefined value here causes illegal behavior
4224// :129:27: note: when computing vector element at index '0'
42254223// :129:27: error: use of undefined value here causes illegal behavior
4226// :129:27: note: when computing vector element at index '1'
42274224// :129:27: error: use of undefined value here causes illegal behavior
4228// :129:27: note: when computing vector element at index '0'
42294225// :129:27: error: use of undefined value here causes illegal behavior
4230// :129:27: note: when computing vector element at index '0'
42314226// :129:27: error: use of undefined value here causes illegal behavior
4232// :129:27: note: when computing vector element at index '0'
42334227// :129:27: error: use of undefined value here causes illegal behavior
42344228// :129:27: error: use of undefined value here causes illegal behavior
4235// :129:27: note: when computing vector element at index '0'
42364229// :129:27: error: use of undefined value here causes illegal behavior
42374230// :129:27: note: when computing vector element at index '0'
42384231// :129:27: error: use of undefined value here causes illegal behavior
42394232// :129:27: note: when computing vector element at index '0'
42404233// :129:27: error: use of undefined value here causes illegal behavior
4241// :129:27: note: when computing vector element at index '1'
4234// :129:27: note: when computing vector element at index '0'
42424235// :129:27: error: use of undefined value here causes illegal behavior
42434236// :129:27: note: when computing vector element at index '0'
42444237// :129:27: error: use of undefined value here causes illegal behavior
......@@ -4246,6 +4239,7 @@ const std = @import("std");
42464239// :129:27: error: use of undefined value here causes illegal behavior
42474240// :129:27: note: when computing vector element at index '0'
42484241// :129:27: error: use of undefined value here causes illegal behavior
4242// :129:27: note: when computing vector element at index '0'
42494243// :129:27: error: use of undefined value here causes illegal behavior
42504244// :129:27: note: when computing vector element at index '0'
42514245// :129:27: error: use of undefined value here causes illegal behavior
......@@ -4253,7 +4247,7 @@ const std = @import("std");
42534247// :129:27: error: use of undefined value here causes illegal behavior
42544248// :129:27: note: when computing vector element at index '0'
42554249// :129:27: error: use of undefined value here causes illegal behavior
4256// :129:27: note: when computing vector element at index '1'
4250// :129:27: note: when computing vector element at index '0'
42574251// :129:27: error: use of undefined value here causes illegal behavior
42584252// :129:27: note: when computing vector element at index '0'
42594253// :129:27: error: use of undefined value here causes illegal behavior
......@@ -4261,6 +4255,7 @@ const std = @import("std");
42614255// :129:27: error: use of undefined value here causes illegal behavior
42624256// :129:27: note: when computing vector element at index '0'
42634257// :129:27: error: use of undefined value here causes illegal behavior
4258// :129:27: note: when computing vector element at index '0'
42644259// :129:27: error: use of undefined value here causes illegal behavior
42654260// :129:27: note: when computing vector element at index '0'
42664261// :129:27: error: use of undefined value here causes illegal behavior
......@@ -4268,7 +4263,7 @@ const std = @import("std");
42684263// :129:27: error: use of undefined value here causes illegal behavior
42694264// :129:27: note: when computing vector element at index '0'
42704265// :129:27: error: use of undefined value here causes illegal behavior
4271// :129:27: note: when computing vector element at index '1'
4266// :129:27: note: when computing vector element at index '0'
42724267// :129:27: error: use of undefined value here causes illegal behavior
42734268// :129:27: note: when computing vector element at index '0'
42744269// :129:27: error: use of undefined value here causes illegal behavior
......@@ -4276,6 +4271,7 @@ const std = @import("std");
42764271// :129:27: error: use of undefined value here causes illegal behavior
42774272// :129:27: note: when computing vector element at index '0'
42784273// :129:27: error: use of undefined value here causes illegal behavior
4274// :129:27: note: when computing vector element at index '0'
42794275// :129:27: error: use of undefined value here causes illegal behavior
42804276// :129:27: note: when computing vector element at index '0'
42814277// :129:27: error: use of undefined value here causes illegal behavior
......@@ -4283,7 +4279,7 @@ const std = @import("std");
42834279// :129:27: error: use of undefined value here causes illegal behavior
42844280// :129:27: note: when computing vector element at index '0'
42854281// :129:27: error: use of undefined value here causes illegal behavior
4286// :129:27: note: when computing vector element at index '1'
4282// :129:27: note: when computing vector element at index '0'
42874283// :129:27: error: use of undefined value here causes illegal behavior
42884284// :129:27: note: when computing vector element at index '0'
42894285// :129:27: error: use of undefined value here causes illegal behavior
......@@ -4291,6 +4287,7 @@ const std = @import("std");
42914287// :129:27: error: use of undefined value here causes illegal behavior
42924288// :129:27: note: when computing vector element at index '0'
42934289// :129:27: error: use of undefined value here causes illegal behavior
4290// :129:27: note: when computing vector element at index '0'
42944291// :129:27: error: use of undefined value here causes illegal behavior
42954292// :129:27: note: when computing vector element at index '0'
42964293// :129:27: error: use of undefined value here causes illegal behavior
......@@ -4298,7 +4295,7 @@ const std = @import("std");
42984295// :129:27: error: use of undefined value here causes illegal behavior
42994296// :129:27: note: when computing vector element at index '0'
43004297// :129:27: error: use of undefined value here causes illegal behavior
4301// :129:27: note: when computing vector element at index '1'
4298// :129:27: note: when computing vector element at index '0'
43024299// :129:27: error: use of undefined value here causes illegal behavior
43034300// :129:27: note: when computing vector element at index '0'
43044301// :129:27: error: use of undefined value here causes illegal behavior
......@@ -4306,6 +4303,7 @@ const std = @import("std");
43064303// :129:27: error: use of undefined value here causes illegal behavior
43074304// :129:27: note: when computing vector element at index '0'
43084305// :129:27: error: use of undefined value here causes illegal behavior
4306// :129:27: note: when computing vector element at index '0'
43094307// :129:27: error: use of undefined value here causes illegal behavior
43104308// :129:27: note: when computing vector element at index '0'
43114309// :129:27: error: use of undefined value here causes illegal behavior
......@@ -4313,7 +4311,7 @@ const std = @import("std");
43134311// :129:27: error: use of undefined value here causes illegal behavior
43144312// :129:27: note: when computing vector element at index '0'
43154313// :129:27: error: use of undefined value here causes illegal behavior
4316// :129:27: note: when computing vector element at index '1'
4314// :129:27: note: when computing vector element at index '0'
43174315// :129:27: error: use of undefined value here causes illegal behavior
43184316// :129:27: note: when computing vector element at index '0'
43194317// :129:27: error: use of undefined value here causes illegal behavior
......@@ -4321,6 +4319,7 @@ const std = @import("std");
43214319// :129:27: error: use of undefined value here causes illegal behavior
43224320// :129:27: note: when computing vector element at index '0'
43234321// :129:27: error: use of undefined value here causes illegal behavior
4322// :129:27: note: when computing vector element at index '0'
43244323// :129:27: error: use of undefined value here causes illegal behavior
43254324// :129:27: note: when computing vector element at index '0'
43264325// :129:27: error: use of undefined value here causes illegal behavior
......@@ -4328,7 +4327,7 @@ const std = @import("std");
43284327// :129:27: error: use of undefined value here causes illegal behavior
43294328// :129:27: note: when computing vector element at index '0'
43304329// :129:27: error: use of undefined value here causes illegal behavior
4331// :129:27: note: when computing vector element at index '1'
4330// :129:27: note: when computing vector element at index '0'
43324331// :129:27: error: use of undefined value here causes illegal behavior
43334332// :129:27: note: when computing vector element at index '0'
43344333// :129:27: error: use of undefined value here causes illegal behavior
......@@ -4336,6 +4335,7 @@ const std = @import("std");
43364335// :129:27: error: use of undefined value here causes illegal behavior
43374336// :129:27: note: when computing vector element at index '0'
43384337// :129:27: error: use of undefined value here causes illegal behavior
4338// :129:27: note: when computing vector element at index '0'
43394339// :129:27: error: use of undefined value here causes illegal behavior
43404340// :129:27: note: when computing vector element at index '0'
43414341// :129:27: error: use of undefined value here causes illegal behavior
......@@ -4343,7 +4343,7 @@ const std = @import("std");
43434343// :129:27: error: use of undefined value here causes illegal behavior
43444344// :129:27: note: when computing vector element at index '0'
43454345// :129:27: error: use of undefined value here causes illegal behavior
4346// :129:27: note: when computing vector element at index '1'
4346// :129:27: note: when computing vector element at index '0'
43474347// :129:27: error: use of undefined value here causes illegal behavior
43484348// :129:27: note: when computing vector element at index '0'
43494349// :129:27: error: use of undefined value here causes illegal behavior
......@@ -4351,6 +4351,7 @@ const std = @import("std");
43514351// :129:27: error: use of undefined value here causes illegal behavior
43524352// :129:27: note: when computing vector element at index '0'
43534353// :129:27: error: use of undefined value here causes illegal behavior
4354// :129:27: note: when computing vector element at index '0'
43544355// :129:27: error: use of undefined value here causes illegal behavior
43554356// :129:27: note: when computing vector element at index '0'
43564357// :129:27: error: use of undefined value here causes illegal behavior
......@@ -4360,126 +4361,120 @@ const std = @import("std");
43604361// :129:27: error: use of undefined value here causes illegal behavior
43614362// :129:27: note: when computing vector element at index '1'
43624363// :129:27: error: use of undefined value here causes illegal behavior
4363// :129:27: note: when computing vector element at index '0'
4364// :129:27: error: use of undefined value here causes illegal behavior
4365// :129:27: note: when computing vector element at index '0'
4364// :129:27: note: when computing vector element at index '1'
43664365// :129:27: error: use of undefined value here causes illegal behavior
4367// :129:27: note: when computing vector element at index '0'
4366// :129:27: note: when computing vector element at index '1'
43684367// :129:27: error: use of undefined value here causes illegal behavior
4368// :129:27: note: when computing vector element at index '1'
43694369// :129:27: error: use of undefined value here causes illegal behavior
4370// :129:27: note: when computing vector element at index '0'
4370// :129:27: note: when computing vector element at index '1'
43714371// :129:27: error: use of undefined value here causes illegal behavior
4372// :129:27: note: when computing vector element at index '0'
4372// :129:27: note: when computing vector element at index '1'
43734373// :129:27: error: use of undefined value here causes illegal behavior
4374// :129:27: note: when computing vector element at index '0'
4374// :129:27: note: when computing vector element at index '1'
43754375// :129:27: error: use of undefined value here causes illegal behavior
43764376// :129:27: note: when computing vector element at index '1'
43774377// :129:27: error: use of undefined value here causes illegal behavior
4378// :129:27: note: when computing vector element at index '0'
4378// :129:27: note: when computing vector element at index '1'
43794379// :129:27: error: use of undefined value here causes illegal behavior
4380// :129:27: note: when computing vector element at index '0'
4380// :129:27: note: when computing vector element at index '1'
43814381// :129:27: error: use of undefined value here causes illegal behavior
4382// :129:27: note: when computing vector element at index '0'
4382// :129:27: note: when computing vector element at index '1'
43834383// :129:30: error: use of undefined value here causes illegal behavior
43844384// :129:30: error: use of undefined value here causes illegal behavior
4385// :129:30: note: when computing vector element at index '0'
43864385// :129:30: error: use of undefined value here causes illegal behavior
4387// :129:30: note: when computing vector element at index '0'
43884386// :129:30: error: use of undefined value here causes illegal behavior
4389// :129:30: note: when computing vector element at index '1'
43904387// :129:30: error: use of undefined value here causes illegal behavior
4391// :129:30: note: when computing vector element at index '0'
43924388// :129:30: error: use of undefined value here causes illegal behavior
4393// :129:30: note: when computing vector element at index '0'
43944389// :129:30: error: use of undefined value here causes illegal behavior
43954390// :129:30: error: use of undefined value here causes illegal behavior
4396// :129:30: note: when computing vector element at index '0'
43974391// :129:30: error: use of undefined value here causes illegal behavior
4398// :129:30: note: when computing vector element at index '0'
43994392// :129:30: error: use of undefined value here causes illegal behavior
4400// :129:30: note: when computing vector element at index '1'
44014393// :129:30: error: use of undefined value here causes illegal behavior
4402// :129:30: note: when computing vector element at index '0'
44034394// :129:30: error: use of undefined value here causes illegal behavior
44044395// :129:30: note: when computing vector element at index '0'
44054396// :129:30: error: use of undefined value here causes illegal behavior
4406// :129:30: error: use of undefined value here causes illegal behavior
44074397// :129:30: note: when computing vector element at index '0'
44084398// :129:30: error: use of undefined value here causes illegal behavior
44094399// :129:30: note: when computing vector element at index '0'
44104400// :129:30: error: use of undefined value here causes illegal behavior
4411// :129:30: note: when computing vector element at index '1'
4412// :129:30: error: use of undefined value here causes illegal behavior
44134401// :129:30: note: when computing vector element at index '0'
44144402// :129:30: error: use of undefined value here causes illegal behavior
44154403// :129:30: note: when computing vector element at index '0'
44164404// :129:30: error: use of undefined value here causes illegal behavior
4405// :129:30: note: when computing vector element at index '0'
44174406// :129:30: error: use of undefined value here causes illegal behavior
44184407// :129:30: note: when computing vector element at index '0'
44194408// :129:30: error: use of undefined value here causes illegal behavior
44204409// :129:30: note: when computing vector element at index '0'
44214410// :129:30: error: use of undefined value here causes illegal behavior
4422// :129:30: note: when computing vector element at index '1'
4411// :129:30: note: when computing vector element at index '0'
44234412// :129:30: error: use of undefined value here causes illegal behavior
44244413// :129:30: note: when computing vector element at index '0'
44254414// :129:30: error: use of undefined value here causes illegal behavior
44264415// :129:30: note: when computing vector element at index '0'
44274416// :129:30: error: use of undefined value here causes illegal behavior
4417// :129:30: note: when computing vector element at index '0'
44284418// :129:30: error: use of undefined value here causes illegal behavior
44294419// :129:30: note: when computing vector element at index '0'
44304420// :129:30: error: use of undefined value here causes illegal behavior
44314421// :129:30: note: when computing vector element at index '0'
44324422// :129:30: error: use of undefined value here causes illegal behavior
4433// :129:30: note: when computing vector element at index '1'
4423// :129:30: note: when computing vector element at index '0'
44344424// :129:30: error: use of undefined value here causes illegal behavior
44354425// :129:30: note: when computing vector element at index '0'
44364426// :129:30: error: use of undefined value here causes illegal behavior
44374427// :129:30: note: when computing vector element at index '0'
44384428// :129:30: error: use of undefined value here causes illegal behavior
4429// :129:30: note: when computing vector element at index '0'
44394430// :129:30: error: use of undefined value here causes illegal behavior
44404431// :129:30: note: when computing vector element at index '0'
44414432// :129:30: error: use of undefined value here causes illegal behavior
44424433// :129:30: note: when computing vector element at index '0'
44434434// :129:30: error: use of undefined value here causes illegal behavior
4444// :129:30: note: when computing vector element at index '1'
4435// :129:30: note: when computing vector element at index '0'
44454436// :129:30: error: use of undefined value here causes illegal behavior
44464437// :129:30: note: when computing vector element at index '0'
44474438// :129:30: error: use of undefined value here causes illegal behavior
44484439// :129:30: note: when computing vector element at index '0'
44494440// :129:30: error: use of undefined value here causes illegal behavior
4441// :129:30: note: when computing vector element at index '0'
44504442// :129:30: error: use of undefined value here causes illegal behavior
44514443// :129:30: note: when computing vector element at index '0'
44524444// :129:30: error: use of undefined value here causes illegal behavior
44534445// :129:30: note: when computing vector element at index '0'
44544446// :129:30: error: use of undefined value here causes illegal behavior
4455// :129:30: note: when computing vector element at index '1'
4447// :129:30: note: when computing vector element at index '0'
44564448// :129:30: error: use of undefined value here causes illegal behavior
44574449// :129:30: note: when computing vector element at index '0'
44584450// :129:30: error: use of undefined value here causes illegal behavior
44594451// :129:30: note: when computing vector element at index '0'
44604452// :129:30: error: use of undefined value here causes illegal behavior
4453// :129:30: note: when computing vector element at index '0'
44614454// :129:30: error: use of undefined value here causes illegal behavior
44624455// :129:30: note: when computing vector element at index '0'
44634456// :129:30: error: use of undefined value here causes illegal behavior
44644457// :129:30: note: when computing vector element at index '0'
44654458// :129:30: error: use of undefined value here causes illegal behavior
4466// :129:30: note: when computing vector element at index '1'
4459// :129:30: note: when computing vector element at index '0'
44674460// :129:30: error: use of undefined value here causes illegal behavior
44684461// :129:30: note: when computing vector element at index '0'
44694462// :129:30: error: use of undefined value here causes illegal behavior
44704463// :129:30: note: when computing vector element at index '0'
44714464// :129:30: error: use of undefined value here causes illegal behavior
4465// :129:30: note: when computing vector element at index '0'
44724466// :129:30: error: use of undefined value here causes illegal behavior
44734467// :129:30: note: when computing vector element at index '0'
44744468// :129:30: error: use of undefined value here causes illegal behavior
44754469// :129:30: note: when computing vector element at index '0'
44764470// :129:30: error: use of undefined value here causes illegal behavior
4477// :129:30: note: when computing vector element at index '1'
4471// :129:30: note: when computing vector element at index '0'
44784472// :129:30: error: use of undefined value here causes illegal behavior
44794473// :129:30: note: when computing vector element at index '0'
44804474// :129:30: error: use of undefined value here causes illegal behavior
44814475// :129:30: note: when computing vector element at index '0'
44824476// :129:30: error: use of undefined value here causes illegal behavior
4477// :129:30: note: when computing vector element at index '0'
44834478// :129:30: error: use of undefined value here causes illegal behavior
44844479// :129:30: note: when computing vector element at index '0'
44854480// :129:30: error: use of undefined value here causes illegal behavior
......@@ -4487,44 +4482,42 @@ const std = @import("std");
44874482// :129:30: error: use of undefined value here causes illegal behavior
44884483// :129:30: note: when computing vector element at index '1'
44894484// :129:30: error: use of undefined value here causes illegal behavior
4490// :129:30: note: when computing vector element at index '0'
4485// :129:30: note: when computing vector element at index '1'
44914486// :129:30: error: use of undefined value here causes illegal behavior
4492// :129:30: note: when computing vector element at index '0'
4487// :129:30: note: when computing vector element at index '1'
4488// :129:30: error: use of undefined value here causes illegal behavior
4489// :129:30: note: when computing vector element at index '1'
44934490// :129:30: error: use of undefined value here causes illegal behavior
4491// :129:30: note: when computing vector element at index '1'
44944492// :129:30: error: use of undefined value here causes illegal behavior
4495// :129:30: note: when computing vector element at index '0'
4493// :129:30: note: when computing vector element at index '1'
44964494// :129:30: error: use of undefined value here causes illegal behavior
4497// :129:30: note: when computing vector element at index '0'
4495// :129:30: note: when computing vector element at index '1'
44984496// :129:30: error: use of undefined value here causes illegal behavior
44994497// :129:30: note: when computing vector element at index '1'
45004498// :129:30: error: use of undefined value here causes illegal behavior
4501// :129:30: note: when computing vector element at index '0'
4499// :129:30: note: when computing vector element at index '1'
45024500// :129:30: error: use of undefined value here causes illegal behavior
4503// :129:30: note: when computing vector element at index '0'
4501// :129:30: note: when computing vector element at index '1'
4502// :129:30: error: use of undefined value here causes illegal behavior
4503// :129:30: note: when computing vector element at index '1'
4504// :133:27: error: use of undefined value here causes illegal behavior
45044505// :133:27: error: use of undefined value here causes illegal behavior
45054506// :133:27: error: use of undefined value here causes illegal behavior
4506// :133:27: note: when computing vector element at index '0'
45074507// :133:27: error: use of undefined value here causes illegal behavior
4508// :133:27: note: when computing vector element at index '0'
45094508// :133:27: error: use of undefined value here causes illegal behavior
4510// :133:27: note: when computing vector element at index '0'
45114509// :133:27: error: use of undefined value here causes illegal behavior
4512// :133:27: note: when computing vector element at index '1'
45134510// :133:27: error: use of undefined value here causes illegal behavior
4514// :133:27: note: when computing vector element at index '0'
45154511// :133:27: error: use of undefined value here causes illegal behavior
4516// :133:27: note: when computing vector element at index '0'
45174512// :133:27: error: use of undefined value here causes illegal behavior
4518// :133:27: note: when computing vector element at index '0'
45194513// :133:27: error: use of undefined value here causes illegal behavior
45204514// :133:27: error: use of undefined value here causes illegal behavior
4521// :133:27: note: when computing vector element at index '0'
45224515// :133:27: error: use of undefined value here causes illegal behavior
45234516// :133:27: note: when computing vector element at index '0'
45244517// :133:27: error: use of undefined value here causes illegal behavior
45254518// :133:27: note: when computing vector element at index '0'
45264519// :133:27: error: use of undefined value here causes illegal behavior
4527// :133:27: note: when computing vector element at index '1'
4520// :133:27: note: when computing vector element at index '0'
45284521// :133:27: error: use of undefined value here causes illegal behavior
45294522// :133:27: note: when computing vector element at index '0'
45304523// :133:27: error: use of undefined value here causes illegal behavior
......@@ -4532,6 +4525,7 @@ const std = @import("std");
45324525// :133:27: error: use of undefined value here causes illegal behavior
45334526// :133:27: note: when computing vector element at index '0'
45344527// :133:27: error: use of undefined value here causes illegal behavior
4528// :133:27: note: when computing vector element at index '0'
45354529// :133:27: error: use of undefined value here causes illegal behavior
45364530// :133:27: note: when computing vector element at index '0'
45374531// :133:27: error: use of undefined value here causes illegal behavior
......@@ -4539,7 +4533,7 @@ const std = @import("std");
45394533// :133:27: error: use of undefined value here causes illegal behavior
45404534// :133:27: note: when computing vector element at index '0'
45414535// :133:27: error: use of undefined value here causes illegal behavior
4542// :133:27: note: when computing vector element at index '1'
4536// :133:27: note: when computing vector element at index '0'
45434537// :133:27: error: use of undefined value here causes illegal behavior
45444538// :133:27: note: when computing vector element at index '0'
45454539// :133:27: error: use of undefined value here causes illegal behavior
......@@ -4547,6 +4541,7 @@ const std = @import("std");
45474541// :133:27: error: use of undefined value here causes illegal behavior
45484542// :133:27: note: when computing vector element at index '0'
45494543// :133:27: error: use of undefined value here causes illegal behavior
4544// :133:27: note: when computing vector element at index '0'
45504545// :133:27: error: use of undefined value here causes illegal behavior
45514546// :133:27: note: when computing vector element at index '0'
45524547// :133:27: error: use of undefined value here causes illegal behavior
......@@ -4554,7 +4549,7 @@ const std = @import("std");
45544549// :133:27: error: use of undefined value here causes illegal behavior
45554550// :133:27: note: when computing vector element at index '0'
45564551// :133:27: error: use of undefined value here causes illegal behavior
4557// :133:27: note: when computing vector element at index '1'
4552// :133:27: note: when computing vector element at index '0'
45584553// :133:27: error: use of undefined value here causes illegal behavior
45594554// :133:27: note: when computing vector element at index '0'
45604555// :133:27: error: use of undefined value here causes illegal behavior
......@@ -4562,6 +4557,7 @@ const std = @import("std");
45624557// :133:27: error: use of undefined value here causes illegal behavior
45634558// :133:27: note: when computing vector element at index '0'
45644559// :133:27: error: use of undefined value here causes illegal behavior
4560// :133:27: note: when computing vector element at index '0'
45654561// :133:27: error: use of undefined value here causes illegal behavior
45664562// :133:27: note: when computing vector element at index '0'
45674563// :133:27: error: use of undefined value here causes illegal behavior
......@@ -4569,7 +4565,7 @@ const std = @import("std");
45694565// :133:27: error: use of undefined value here causes illegal behavior
45704566// :133:27: note: when computing vector element at index '0'
45714567// :133:27: error: use of undefined value here causes illegal behavior
4572// :133:27: note: when computing vector element at index '1'
4568// :133:27: note: when computing vector element at index '0'
45734569// :133:27: error: use of undefined value here causes illegal behavior
45744570// :133:27: note: when computing vector element at index '0'
45754571// :133:27: error: use of undefined value here causes illegal behavior
......@@ -4577,6 +4573,7 @@ const std = @import("std");
45774573// :133:27: error: use of undefined value here causes illegal behavior
45784574// :133:27: note: when computing vector element at index '0'
45794575// :133:27: error: use of undefined value here causes illegal behavior
4576// :133:27: note: when computing vector element at index '0'
45804577// :133:27: error: use of undefined value here causes illegal behavior
45814578// :133:27: note: when computing vector element at index '0'
45824579// :133:27: error: use of undefined value here causes illegal behavior
......@@ -4584,7 +4581,7 @@ const std = @import("std");
45844581// :133:27: error: use of undefined value here causes illegal behavior
45854582// :133:27: note: when computing vector element at index '0'
45864583// :133:27: error: use of undefined value here causes illegal behavior
4587// :133:27: note: when computing vector element at index '1'
4584// :133:27: note: when computing vector element at index '0'
45884585// :133:27: error: use of undefined value here causes illegal behavior
45894586// :133:27: note: when computing vector element at index '0'
45904587// :133:27: error: use of undefined value here causes illegal behavior
......@@ -4592,6 +4589,7 @@ const std = @import("std");
45924589// :133:27: error: use of undefined value here causes illegal behavior
45934590// :133:27: note: when computing vector element at index '0'
45944591// :133:27: error: use of undefined value here causes illegal behavior
4592// :133:27: note: when computing vector element at index '0'
45954593// :133:27: error: use of undefined value here causes illegal behavior
45964594// :133:27: note: when computing vector element at index '0'
45974595// :133:27: error: use of undefined value here causes illegal behavior
......@@ -4599,7 +4597,7 @@ const std = @import("std");
45994597// :133:27: error: use of undefined value here causes illegal behavior
46004598// :133:27: note: when computing vector element at index '0'
46014599// :133:27: error: use of undefined value here causes illegal behavior
4602// :133:27: note: when computing vector element at index '1'
4600// :133:27: note: when computing vector element at index '0'
46034601// :133:27: error: use of undefined value here causes illegal behavior
46044602// :133:27: note: when computing vector element at index '0'
46054603// :133:27: error: use of undefined value here causes illegal behavior
......@@ -4607,6 +4605,7 @@ const std = @import("std");
46074605// :133:27: error: use of undefined value here causes illegal behavior
46084606// :133:27: note: when computing vector element at index '0'
46094607// :133:27: error: use of undefined value here causes illegal behavior
4608// :133:27: note: when computing vector element at index '0'
46104609// :133:27: error: use of undefined value here causes illegal behavior
46114610// :133:27: note: when computing vector element at index '0'
46124611// :133:27: error: use of undefined value here causes illegal behavior
......@@ -4614,7 +4613,7 @@ const std = @import("std");
46144613// :133:27: error: use of undefined value here causes illegal behavior
46154614// :133:27: note: when computing vector element at index '0'
46164615// :133:27: error: use of undefined value here causes illegal behavior
4617// :133:27: note: when computing vector element at index '1'
4616// :133:27: note: when computing vector element at index '0'
46184617// :133:27: error: use of undefined value here causes illegal behavior
46194618// :133:27: note: when computing vector element at index '0'
46204619// :133:27: error: use of undefined value here causes illegal behavior
......@@ -4622,6 +4621,7 @@ const std = @import("std");
46224621// :133:27: error: use of undefined value here causes illegal behavior
46234622// :133:27: note: when computing vector element at index '0'
46244623// :133:27: error: use of undefined value here causes illegal behavior
4624// :133:27: note: when computing vector element at index '0'
46254625// :133:27: error: use of undefined value here causes illegal behavior
46264626// :133:27: note: when computing vector element at index '0'
46274627// :133:27: error: use of undefined value here causes illegal behavior
......@@ -4629,7 +4629,7 @@ const std = @import("std");
46294629// :133:27: error: use of undefined value here causes illegal behavior
46304630// :133:27: note: when computing vector element at index '0'
46314631// :133:27: error: use of undefined value here causes illegal behavior
4632// :133:27: note: when computing vector element at index '1'
4632// :133:27: note: when computing vector element at index '0'
46334633// :133:27: error: use of undefined value here causes illegal behavior
46344634// :133:27: note: when computing vector element at index '0'
46354635// :133:27: error: use of undefined value here causes illegal behavior
......@@ -4637,6 +4637,7 @@ const std = @import("std");
46374637// :133:27: error: use of undefined value here causes illegal behavior
46384638// :133:27: note: when computing vector element at index '0'
46394639// :133:27: error: use of undefined value here causes illegal behavior
4640// :133:27: note: when computing vector element at index '0'
46404641// :133:27: error: use of undefined value here causes illegal behavior
46414642// :133:27: note: when computing vector element at index '0'
46424643// :133:27: error: use of undefined value here causes illegal behavior
......@@ -4646,126 +4647,120 @@ const std = @import("std");
46464647// :133:27: error: use of undefined value here causes illegal behavior
46474648// :133:27: note: when computing vector element at index '1'
46484649// :133:27: error: use of undefined value here causes illegal behavior
4649// :133:27: note: when computing vector element at index '0'
4650// :133:27: error: use of undefined value here causes illegal behavior
4651// :133:27: note: when computing vector element at index '0'
4650// :133:27: note: when computing vector element at index '1'
46524651// :133:27: error: use of undefined value here causes illegal behavior
4653// :133:27: note: when computing vector element at index '0'
4652// :133:27: note: when computing vector element at index '1'
46544653// :133:27: error: use of undefined value here causes illegal behavior
4654// :133:27: note: when computing vector element at index '1'
46554655// :133:27: error: use of undefined value here causes illegal behavior
4656// :133:27: note: when computing vector element at index '0'
4656// :133:27: note: when computing vector element at index '1'
46574657// :133:27: error: use of undefined value here causes illegal behavior
4658// :133:27: note: when computing vector element at index '0'
4658// :133:27: note: when computing vector element at index '1'
46594659// :133:27: error: use of undefined value here causes illegal behavior
4660// :133:27: note: when computing vector element at index '0'
4660// :133:27: note: when computing vector element at index '1'
46614661// :133:27: error: use of undefined value here causes illegal behavior
46624662// :133:27: note: when computing vector element at index '1'
46634663// :133:27: error: use of undefined value here causes illegal behavior
4664// :133:27: note: when computing vector element at index '0'
4664// :133:27: note: when computing vector element at index '1'
46654665// :133:27: error: use of undefined value here causes illegal behavior
4666// :133:27: note: when computing vector element at index '0'
4666// :133:27: note: when computing vector element at index '1'
46674667// :133:27: error: use of undefined value here causes illegal behavior
4668// :133:27: note: when computing vector element at index '0'
4668// :133:27: note: when computing vector element at index '1'
46694669// :133:30: error: use of undefined value here causes illegal behavior
46704670// :133:30: error: use of undefined value here causes illegal behavior
4671// :133:30: note: when computing vector element at index '0'
46724671// :133:30: error: use of undefined value here causes illegal behavior
4673// :133:30: note: when computing vector element at index '0'
46744672// :133:30: error: use of undefined value here causes illegal behavior
4675// :133:30: note: when computing vector element at index '1'
46764673// :133:30: error: use of undefined value here causes illegal behavior
4677// :133:30: note: when computing vector element at index '0'
46784674// :133:30: error: use of undefined value here causes illegal behavior
4679// :133:30: note: when computing vector element at index '0'
46804675// :133:30: error: use of undefined value here causes illegal behavior
46814676// :133:30: error: use of undefined value here causes illegal behavior
4682// :133:30: note: when computing vector element at index '0'
46834677// :133:30: error: use of undefined value here causes illegal behavior
4684// :133:30: note: when computing vector element at index '0'
46854678// :133:30: error: use of undefined value here causes illegal behavior
4686// :133:30: note: when computing vector element at index '1'
46874679// :133:30: error: use of undefined value here causes illegal behavior
4688// :133:30: note: when computing vector element at index '0'
46894680// :133:30: error: use of undefined value here causes illegal behavior
46904681// :133:30: note: when computing vector element at index '0'
46914682// :133:30: error: use of undefined value here causes illegal behavior
4692// :133:30: error: use of undefined value here causes illegal behavior
46934683// :133:30: note: when computing vector element at index '0'
46944684// :133:30: error: use of undefined value here causes illegal behavior
46954685// :133:30: note: when computing vector element at index '0'
46964686// :133:30: error: use of undefined value here causes illegal behavior
4697// :133:30: note: when computing vector element at index '1'
4698// :133:30: error: use of undefined value here causes illegal behavior
46994687// :133:30: note: when computing vector element at index '0'
47004688// :133:30: error: use of undefined value here causes illegal behavior
47014689// :133:30: note: when computing vector element at index '0'
47024690// :133:30: error: use of undefined value here causes illegal behavior
4691// :133:30: note: when computing vector element at index '0'
47034692// :133:30: error: use of undefined value here causes illegal behavior
47044693// :133:30: note: when computing vector element at index '0'
47054694// :133:30: error: use of undefined value here causes illegal behavior
47064695// :133:30: note: when computing vector element at index '0'
47074696// :133:30: error: use of undefined value here causes illegal behavior
4708// :133:30: note: when computing vector element at index '1'
4697// :133:30: note: when computing vector element at index '0'
47094698// :133:30: error: use of undefined value here causes illegal behavior
47104699// :133:30: note: when computing vector element at index '0'
47114700// :133:30: error: use of undefined value here causes illegal behavior
47124701// :133:30: note: when computing vector element at index '0'
47134702// :133:30: error: use of undefined value here causes illegal behavior
4703// :133:30: note: when computing vector element at index '0'
47144704// :133:30: error: use of undefined value here causes illegal behavior
47154705// :133:30: note: when computing vector element at index '0'
47164706// :133:30: error: use of undefined value here causes illegal behavior
47174707// :133:30: note: when computing vector element at index '0'
47184708// :133:30: error: use of undefined value here causes illegal behavior
4719// :133:30: note: when computing vector element at index '1'
4709// :133:30: note: when computing vector element at index '0'
47204710// :133:30: error: use of undefined value here causes illegal behavior
47214711// :133:30: note: when computing vector element at index '0'
47224712// :133:30: error: use of undefined value here causes illegal behavior
47234713// :133:30: note: when computing vector element at index '0'
47244714// :133:30: error: use of undefined value here causes illegal behavior
4715// :133:30: note: when computing vector element at index '0'
47254716// :133:30: error: use of undefined value here causes illegal behavior
47264717// :133:30: note: when computing vector element at index '0'
47274718// :133:30: error: use of undefined value here causes illegal behavior
47284719// :133:30: note: when computing vector element at index '0'
47294720// :133:30: error: use of undefined value here causes illegal behavior
4730// :133:30: note: when computing vector element at index '1'
4721// :133:30: note: when computing vector element at index '0'
47314722// :133:30: error: use of undefined value here causes illegal behavior
47324723// :133:30: note: when computing vector element at index '0'
47334724// :133:30: error: use of undefined value here causes illegal behavior
47344725// :133:30: note: when computing vector element at index '0'
47354726// :133:30: error: use of undefined value here causes illegal behavior
4727// :133:30: note: when computing vector element at index '0'
47364728// :133:30: error: use of undefined value here causes illegal behavior
47374729// :133:30: note: when computing vector element at index '0'
47384730// :133:30: error: use of undefined value here causes illegal behavior
47394731// :133:30: note: when computing vector element at index '0'
47404732// :133:30: error: use of undefined value here causes illegal behavior
4741// :133:30: note: when computing vector element at index '1'
4733// :133:30: note: when computing vector element at index '0'
47424734// :133:30: error: use of undefined value here causes illegal behavior
47434735// :133:30: note: when computing vector element at index '0'
47444736// :133:30: error: use of undefined value here causes illegal behavior
47454737// :133:30: note: when computing vector element at index '0'
47464738// :133:30: error: use of undefined value here causes illegal behavior
4739// :133:30: note: when computing vector element at index '0'
47474740// :133:30: error: use of undefined value here causes illegal behavior
47484741// :133:30: note: when computing vector element at index '0'
47494742// :133:30: error: use of undefined value here causes illegal behavior
47504743// :133:30: note: when computing vector element at index '0'
47514744// :133:30: error: use of undefined value here causes illegal behavior
4752// :133:30: note: when computing vector element at index '1'
4745// :133:30: note: when computing vector element at index '0'
47534746// :133:30: error: use of undefined value here causes illegal behavior
47544747// :133:30: note: when computing vector element at index '0'
47554748// :133:30: error: use of undefined value here causes illegal behavior
47564749// :133:30: note: when computing vector element at index '0'
47574750// :133:30: error: use of undefined value here causes illegal behavior
4751// :133:30: note: when computing vector element at index '0'
47584752// :133:30: error: use of undefined value here causes illegal behavior
47594753// :133:30: note: when computing vector element at index '0'
47604754// :133:30: error: use of undefined value here causes illegal behavior
47614755// :133:30: note: when computing vector element at index '0'
47624756// :133:30: error: use of undefined value here causes illegal behavior
4763// :133:30: note: when computing vector element at index '1'
4757// :133:30: note: when computing vector element at index '0'
47644758// :133:30: error: use of undefined value here causes illegal behavior
47654759// :133:30: note: when computing vector element at index '0'
47664760// :133:30: error: use of undefined value here causes illegal behavior
47674761// :133:30: note: when computing vector element at index '0'
47684762// :133:30: error: use of undefined value here causes illegal behavior
4763// :133:30: note: when computing vector element at index '0'
47694764// :133:30: error: use of undefined value here causes illegal behavior
47704765// :133:30: note: when computing vector element at index '0'
47714766// :133:30: error: use of undefined value here causes illegal behavior
......@@ -4773,44 +4768,42 @@ const std = @import("std");
47734768// :133:30: error: use of undefined value here causes illegal behavior
47744769// :133:30: note: when computing vector element at index '1'
47754770// :133:30: error: use of undefined value here causes illegal behavior
4776// :133:30: note: when computing vector element at index '0'
4771// :133:30: note: when computing vector element at index '1'
47774772// :133:30: error: use of undefined value here causes illegal behavior
4778// :133:30: note: when computing vector element at index '0'
4773// :133:30: note: when computing vector element at index '1'
47794774// :133:30: error: use of undefined value here causes illegal behavior
4775// :133:30: note: when computing vector element at index '1'
47804776// :133:30: error: use of undefined value here causes illegal behavior
4781// :133:30: note: when computing vector element at index '0'
4777// :133:30: note: when computing vector element at index '1'
47824778// :133:30: error: use of undefined value here causes illegal behavior
4783// :133:30: note: when computing vector element at index '0'
4779// :133:30: note: when computing vector element at index '1'
47844780// :133:30: error: use of undefined value here causes illegal behavior
47854781// :133:30: note: when computing vector element at index '1'
47864782// :133:30: error: use of undefined value here causes illegal behavior
4787// :133:30: note: when computing vector element at index '0'
4783// :133:30: note: when computing vector element at index '1'
47884784// :133:30: error: use of undefined value here causes illegal behavior
4789// :133:30: note: when computing vector element at index '0'
4785// :133:30: note: when computing vector element at index '1'
4786// :133:30: error: use of undefined value here causes illegal behavior
4787// :133:30: note: when computing vector element at index '1'
4788// :133:30: error: use of undefined value here causes illegal behavior
4789// :133:30: note: when computing vector element at index '1'
4790// :137:17: error: use of undefined value here causes illegal behavior
47904791// :137:17: error: use of undefined value here causes illegal behavior
47914792// :137:17: error: use of undefined value here causes illegal behavior
4792// :137:17: note: when computing vector element at index '0'
47934793// :137:17: error: use of undefined value here causes illegal behavior
4794// :137:17: note: when computing vector element at index '0'
47954794// :137:17: error: use of undefined value here causes illegal behavior
4796// :137:17: note: when computing vector element at index '0'
47974795// :137:17: error: use of undefined value here causes illegal behavior
4798// :137:17: note: when computing vector element at index '1'
47994796// :137:17: error: use of undefined value here causes illegal behavior
4800// :137:17: note: when computing vector element at index '0'
48014797// :137:17: error: use of undefined value here causes illegal behavior
4802// :137:17: note: when computing vector element at index '0'
48034798// :137:17: error: use of undefined value here causes illegal behavior
4804// :137:17: note: when computing vector element at index '0'
48054799// :137:17: error: use of undefined value here causes illegal behavior
48064800// :137:17: error: use of undefined value here causes illegal behavior
4807// :137:17: note: when computing vector element at index '0'
48084801// :137:17: error: use of undefined value here causes illegal behavior
48094802// :137:17: note: when computing vector element at index '0'
48104803// :137:17: error: use of undefined value here causes illegal behavior
48114804// :137:17: note: when computing vector element at index '0'
48124805// :137:17: error: use of undefined value here causes illegal behavior
4813// :137:17: note: when computing vector element at index '1'
4806// :137:17: note: when computing vector element at index '0'
48144807// :137:17: error: use of undefined value here causes illegal behavior
48154808// :137:17: note: when computing vector element at index '0'
48164809// :137:17: error: use of undefined value here causes illegal behavior
......@@ -4818,6 +4811,7 @@ const std = @import("std");
48184811// :137:17: error: use of undefined value here causes illegal behavior
48194812// :137:17: note: when computing vector element at index '0'
48204813// :137:17: error: use of undefined value here causes illegal behavior
4814// :137:17: note: when computing vector element at index '0'
48214815// :137:17: error: use of undefined value here causes illegal behavior
48224816// :137:17: note: when computing vector element at index '0'
48234817// :137:17: error: use of undefined value here causes illegal behavior
......@@ -4825,7 +4819,7 @@ const std = @import("std");
48254819// :137:17: error: use of undefined value here causes illegal behavior
48264820// :137:17: note: when computing vector element at index '0'
48274821// :137:17: error: use of undefined value here causes illegal behavior
4828// :137:17: note: when computing vector element at index '1'
4822// :137:17: note: when computing vector element at index '0'
48294823// :137:17: error: use of undefined value here causes illegal behavior
48304824// :137:17: note: when computing vector element at index '0'
48314825// :137:17: error: use of undefined value here causes illegal behavior
......@@ -4833,6 +4827,7 @@ const std = @import("std");
48334827// :137:17: error: use of undefined value here causes illegal behavior
48344828// :137:17: note: when computing vector element at index '0'
48354829// :137:17: error: use of undefined value here causes illegal behavior
4830// :137:17: note: when computing vector element at index '0'
48364831// :137:17: error: use of undefined value here causes illegal behavior
48374832// :137:17: note: when computing vector element at index '0'
48384833// :137:17: error: use of undefined value here causes illegal behavior
......@@ -4840,7 +4835,7 @@ const std = @import("std");
48404835// :137:17: error: use of undefined value here causes illegal behavior
48414836// :137:17: note: when computing vector element at index '0'
48424837// :137:17: error: use of undefined value here causes illegal behavior
4843// :137:17: note: when computing vector element at index '1'
4838// :137:17: note: when computing vector element at index '0'
48444839// :137:17: error: use of undefined value here causes illegal behavior
48454840// :137:17: note: when computing vector element at index '0'
48464841// :137:17: error: use of undefined value here causes illegal behavior
......@@ -4848,6 +4843,7 @@ const std = @import("std");
48484843// :137:17: error: use of undefined value here causes illegal behavior
48494844// :137:17: note: when computing vector element at index '0'
48504845// :137:17: error: use of undefined value here causes illegal behavior
4846// :137:17: note: when computing vector element at index '0'
48514847// :137:17: error: use of undefined value here causes illegal behavior
48524848// :137:17: note: when computing vector element at index '0'
48534849// :137:17: error: use of undefined value here causes illegal behavior
......@@ -4855,7 +4851,7 @@ const std = @import("std");
48554851// :137:17: error: use of undefined value here causes illegal behavior
48564852// :137:17: note: when computing vector element at index '0'
48574853// :137:17: error: use of undefined value here causes illegal behavior
4858// :137:17: note: when computing vector element at index '1'
4854// :137:17: note: when computing vector element at index '0'
48594855// :137:17: error: use of undefined value here causes illegal behavior
48604856// :137:17: note: when computing vector element at index '0'
48614857// :137:17: error: use of undefined value here causes illegal behavior
......@@ -4863,6 +4859,7 @@ const std = @import("std");
48634859// :137:17: error: use of undefined value here causes illegal behavior
48644860// :137:17: note: when computing vector element at index '0'
48654861// :137:17: error: use of undefined value here causes illegal behavior
4862// :137:17: note: when computing vector element at index '0'
48664863// :137:17: error: use of undefined value here causes illegal behavior
48674864// :137:17: note: when computing vector element at index '0'
48684865// :137:17: error: use of undefined value here causes illegal behavior
......@@ -4870,7 +4867,7 @@ const std = @import("std");
48704867// :137:17: error: use of undefined value here causes illegal behavior
48714868// :137:17: note: when computing vector element at index '0'
48724869// :137:17: error: use of undefined value here causes illegal behavior
4873// :137:17: note: when computing vector element at index '1'
4870// :137:17: note: when computing vector element at index '0'
48744871// :137:17: error: use of undefined value here causes illegal behavior
48754872// :137:17: note: when computing vector element at index '0'
48764873// :137:17: error: use of undefined value here causes illegal behavior
......@@ -4878,6 +4875,7 @@ const std = @import("std");
48784875// :137:17: error: use of undefined value here causes illegal behavior
48794876// :137:17: note: when computing vector element at index '0'
48804877// :137:17: error: use of undefined value here causes illegal behavior
4878// :137:17: note: when computing vector element at index '0'
48814879// :137:17: error: use of undefined value here causes illegal behavior
48824880// :137:17: note: when computing vector element at index '0'
48834881// :137:17: error: use of undefined value here causes illegal behavior
......@@ -4885,7 +4883,7 @@ const std = @import("std");
48854883// :137:17: error: use of undefined value here causes illegal behavior
48864884// :137:17: note: when computing vector element at index '0'
48874885// :137:17: error: use of undefined value here causes illegal behavior
4888// :137:17: note: when computing vector element at index '1'
4886// :137:17: note: when computing vector element at index '0'
48894887// :137:17: error: use of undefined value here causes illegal behavior
48904888// :137:17: note: when computing vector element at index '0'
48914889// :137:17: error: use of undefined value here causes illegal behavior
......@@ -4893,6 +4891,7 @@ const std = @import("std");
48934891// :137:17: error: use of undefined value here causes illegal behavior
48944892// :137:17: note: when computing vector element at index '0'
48954893// :137:17: error: use of undefined value here causes illegal behavior
4894// :137:17: note: when computing vector element at index '0'
48964895// :137:17: error: use of undefined value here causes illegal behavior
48974896// :137:17: note: when computing vector element at index '0'
48984897// :137:17: error: use of undefined value here causes illegal behavior
......@@ -4900,7 +4899,7 @@ const std = @import("std");
49004899// :137:17: error: use of undefined value here causes illegal behavior
49014900// :137:17: note: when computing vector element at index '0'
49024901// :137:17: error: use of undefined value here causes illegal behavior
4903// :137:17: note: when computing vector element at index '1'
4902// :137:17: note: when computing vector element at index '0'
49044903// :137:17: error: use of undefined value here causes illegal behavior
49054904// :137:17: note: when computing vector element at index '0'
49064905// :137:17: error: use of undefined value here causes illegal behavior
......@@ -4908,6 +4907,7 @@ const std = @import("std");
49084907// :137:17: error: use of undefined value here causes illegal behavior
49094908// :137:17: note: when computing vector element at index '0'
49104909// :137:17: error: use of undefined value here causes illegal behavior
4910// :137:17: note: when computing vector element at index '0'
49114911// :137:17: error: use of undefined value here causes illegal behavior
49124912// :137:17: note: when computing vector element at index '0'
49134913// :137:17: error: use of undefined value here causes illegal behavior
......@@ -4915,7 +4915,7 @@ const std = @import("std");
49154915// :137:17: error: use of undefined value here causes illegal behavior
49164916// :137:17: note: when computing vector element at index '0'
49174917// :137:17: error: use of undefined value here causes illegal behavior
4918// :137:17: note: when computing vector element at index '1'
4918// :137:17: note: when computing vector element at index '0'
49194919// :137:17: error: use of undefined value here causes illegal behavior
49204920// :137:17: note: when computing vector element at index '0'
49214921// :137:17: error: use of undefined value here causes illegal behavior
......@@ -4923,6 +4923,7 @@ const std = @import("std");
49234923// :137:17: error: use of undefined value here causes illegal behavior
49244924// :137:17: note: when computing vector element at index '0'
49254925// :137:17: error: use of undefined value here causes illegal behavior
4926// :137:17: note: when computing vector element at index '0'
49264927// :137:17: error: use of undefined value here causes illegal behavior
49274928// :137:17: note: when computing vector element at index '0'
49284929// :137:17: error: use of undefined value here causes illegal behavior
......@@ -4932,126 +4933,120 @@ const std = @import("std");
49324933// :137:17: error: use of undefined value here causes illegal behavior
49334934// :137:17: note: when computing vector element at index '1'
49344935// :137:17: error: use of undefined value here causes illegal behavior
4935// :137:17: note: when computing vector element at index '0'
4936// :137:17: error: use of undefined value here causes illegal behavior
4937// :137:17: note: when computing vector element at index '0'
4936// :137:17: note: when computing vector element at index '1'
49384937// :137:17: error: use of undefined value here causes illegal behavior
4939// :137:17: note: when computing vector element at index '0'
4938// :137:17: note: when computing vector element at index '1'
49404939// :137:17: error: use of undefined value here causes illegal behavior
4940// :137:17: note: when computing vector element at index '1'
49414941// :137:17: error: use of undefined value here causes illegal behavior
4942// :137:17: note: when computing vector element at index '0'
4942// :137:17: note: when computing vector element at index '1'
49434943// :137:17: error: use of undefined value here causes illegal behavior
4944// :137:17: note: when computing vector element at index '0'
4944// :137:17: note: when computing vector element at index '1'
49454945// :137:17: error: use of undefined value here causes illegal behavior
4946// :137:17: note: when computing vector element at index '0'
4946// :137:17: note: when computing vector element at index '1'
49474947// :137:17: error: use of undefined value here causes illegal behavior
49484948// :137:17: note: when computing vector element at index '1'
49494949// :137:17: error: use of undefined value here causes illegal behavior
4950// :137:17: note: when computing vector element at index '0'
4950// :137:17: note: when computing vector element at index '1'
49514951// :137:17: error: use of undefined value here causes illegal behavior
4952// :137:17: note: when computing vector element at index '0'
4952// :137:17: note: when computing vector element at index '1'
49534953// :137:17: error: use of undefined value here causes illegal behavior
4954// :137:17: note: when computing vector element at index '0'
4954// :137:17: note: when computing vector element at index '1'
49554955// :137:21: error: use of undefined value here causes illegal behavior
49564956// :137:21: error: use of undefined value here causes illegal behavior
4957// :137:21: note: when computing vector element at index '0'
49584957// :137:21: error: use of undefined value here causes illegal behavior
4959// :137:21: note: when computing vector element at index '0'
49604958// :137:21: error: use of undefined value here causes illegal behavior
4961// :137:21: note: when computing vector element at index '1'
49624959// :137:21: error: use of undefined value here causes illegal behavior
4963// :137:21: note: when computing vector element at index '0'
49644960// :137:21: error: use of undefined value here causes illegal behavior
4965// :137:21: note: when computing vector element at index '0'
49664961// :137:21: error: use of undefined value here causes illegal behavior
49674962// :137:21: error: use of undefined value here causes illegal behavior
4968// :137:21: note: when computing vector element at index '0'
49694963// :137:21: error: use of undefined value here causes illegal behavior
4970// :137:21: note: when computing vector element at index '0'
49714964// :137:21: error: use of undefined value here causes illegal behavior
4972// :137:21: note: when computing vector element at index '1'
49734965// :137:21: error: use of undefined value here causes illegal behavior
4974// :137:21: note: when computing vector element at index '0'
49754966// :137:21: error: use of undefined value here causes illegal behavior
49764967// :137:21: note: when computing vector element at index '0'
49774968// :137:21: error: use of undefined value here causes illegal behavior
4978// :137:21: error: use of undefined value here causes illegal behavior
49794969// :137:21: note: when computing vector element at index '0'
49804970// :137:21: error: use of undefined value here causes illegal behavior
49814971// :137:21: note: when computing vector element at index '0'
49824972// :137:21: error: use of undefined value here causes illegal behavior
4983// :137:21: note: when computing vector element at index '1'
4984// :137:21: error: use of undefined value here causes illegal behavior
49854973// :137:21: note: when computing vector element at index '0'
49864974// :137:21: error: use of undefined value here causes illegal behavior
49874975// :137:21: note: when computing vector element at index '0'
49884976// :137:21: error: use of undefined value here causes illegal behavior
4977// :137:21: note: when computing vector element at index '0'
49894978// :137:21: error: use of undefined value here causes illegal behavior
49904979// :137:21: note: when computing vector element at index '0'
49914980// :137:21: error: use of undefined value here causes illegal behavior
49924981// :137:21: note: when computing vector element at index '0'
49934982// :137:21: error: use of undefined value here causes illegal behavior
4994// :137:21: note: when computing vector element at index '1'
4983// :137:21: note: when computing vector element at index '0'
49954984// :137:21: error: use of undefined value here causes illegal behavior
49964985// :137:21: note: when computing vector element at index '0'
49974986// :137:21: error: use of undefined value here causes illegal behavior
49984987// :137:21: note: when computing vector element at index '0'
49994988// :137:21: error: use of undefined value here causes illegal behavior
4989// :137:21: note: when computing vector element at index '0'
50004990// :137:21: error: use of undefined value here causes illegal behavior
50014991// :137:21: note: when computing vector element at index '0'
50024992// :137:21: error: use of undefined value here causes illegal behavior
50034993// :137:21: note: when computing vector element at index '0'
50044994// :137:21: error: use of undefined value here causes illegal behavior
5005// :137:21: note: when computing vector element at index '1'
4995// :137:21: note: when computing vector element at index '0'
50064996// :137:21: error: use of undefined value here causes illegal behavior
50074997// :137:21: note: when computing vector element at index '0'
50084998// :137:21: error: use of undefined value here causes illegal behavior
50094999// :137:21: note: when computing vector element at index '0'
50105000// :137:21: error: use of undefined value here causes illegal behavior
5001// :137:21: note: when computing vector element at index '0'
50115002// :137:21: error: use of undefined value here causes illegal behavior
50125003// :137:21: note: when computing vector element at index '0'
50135004// :137:21: error: use of undefined value here causes illegal behavior
50145005// :137:21: note: when computing vector element at index '0'
50155006// :137:21: error: use of undefined value here causes illegal behavior
5016// :137:21: note: when computing vector element at index '1'
5007// :137:21: note: when computing vector element at index '0'
50175008// :137:21: error: use of undefined value here causes illegal behavior
50185009// :137:21: note: when computing vector element at index '0'
50195010// :137:21: error: use of undefined value here causes illegal behavior
50205011// :137:21: note: when computing vector element at index '0'
50215012// :137:21: error: use of undefined value here causes illegal behavior
5013// :137:21: note: when computing vector element at index '0'
50225014// :137:21: error: use of undefined value here causes illegal behavior
50235015// :137:21: note: when computing vector element at index '0'
50245016// :137:21: error: use of undefined value here causes illegal behavior
50255017// :137:21: note: when computing vector element at index '0'
50265018// :137:21: error: use of undefined value here causes illegal behavior
5027// :137:21: note: when computing vector element at index '1'
5019// :137:21: note: when computing vector element at index '0'
50285020// :137:21: error: use of undefined value here causes illegal behavior
50295021// :137:21: note: when computing vector element at index '0'
50305022// :137:21: error: use of undefined value here causes illegal behavior
50315023// :137:21: note: when computing vector element at index '0'
50325024// :137:21: error: use of undefined value here causes illegal behavior
5025// :137:21: note: when computing vector element at index '0'
50335026// :137:21: error: use of undefined value here causes illegal behavior
50345027// :137:21: note: when computing vector element at index '0'
50355028// :137:21: error: use of undefined value here causes illegal behavior
50365029// :137:21: note: when computing vector element at index '0'
50375030// :137:21: error: use of undefined value here causes illegal behavior
5038// :137:21: note: when computing vector element at index '1'
5031// :137:21: note: when computing vector element at index '0'
50395032// :137:21: error: use of undefined value here causes illegal behavior
50405033// :137:21: note: when computing vector element at index '0'
50415034// :137:21: error: use of undefined value here causes illegal behavior
50425035// :137:21: note: when computing vector element at index '0'
50435036// :137:21: error: use of undefined value here causes illegal behavior
5037// :137:21: note: when computing vector element at index '0'
50445038// :137:21: error: use of undefined value here causes illegal behavior
50455039// :137:21: note: when computing vector element at index '0'
50465040// :137:21: error: use of undefined value here causes illegal behavior
50475041// :137:21: note: when computing vector element at index '0'
50485042// :137:21: error: use of undefined value here causes illegal behavior
5049// :137:21: note: when computing vector element at index '1'
5043// :137:21: note: when computing vector element at index '0'
50505044// :137:21: error: use of undefined value here causes illegal behavior
50515045// :137:21: note: when computing vector element at index '0'
50525046// :137:21: error: use of undefined value here causes illegal behavior
50535047// :137:21: note: when computing vector element at index '0'
50545048// :137:21: error: use of undefined value here causes illegal behavior
5049// :137:21: note: when computing vector element at index '0'
50555050// :137:21: error: use of undefined value here causes illegal behavior
50565051// :137:21: note: when computing vector element at index '0'
50575052// :137:21: error: use of undefined value here causes illegal behavior
......@@ -5059,44 +5054,42 @@ const std = @import("std");
50595054// :137:21: error: use of undefined value here causes illegal behavior
50605055// :137:21: note: when computing vector element at index '1'
50615056// :137:21: error: use of undefined value here causes illegal behavior
5062// :137:21: note: when computing vector element at index '0'
5057// :137:21: note: when computing vector element at index '1'
50635058// :137:21: error: use of undefined value here causes illegal behavior
5064// :137:21: note: when computing vector element at index '0'
5059// :137:21: note: when computing vector element at index '1'
50655060// :137:21: error: use of undefined value here causes illegal behavior
5061// :137:21: note: when computing vector element at index '1'
50665062// :137:21: error: use of undefined value here causes illegal behavior
5067// :137:21: note: when computing vector element at index '0'
5063// :137:21: note: when computing vector element at index '1'
50685064// :137:21: error: use of undefined value here causes illegal behavior
5069// :137:21: note: when computing vector element at index '0'
5065// :137:21: note: when computing vector element at index '1'
50705066// :137:21: error: use of undefined value here causes illegal behavior
50715067// :137:21: note: when computing vector element at index '1'
50725068// :137:21: error: use of undefined value here causes illegal behavior
5073// :137:21: note: when computing vector element at index '0'
5069// :137:21: note: when computing vector element at index '1'
50745070// :137:21: error: use of undefined value here causes illegal behavior
5075// :137:21: note: when computing vector element at index '0'
5071// :137:21: note: when computing vector element at index '1'
5072// :137:21: error: use of undefined value here causes illegal behavior
5073// :137:21: note: when computing vector element at index '1'
5074// :137:21: error: use of undefined value here causes illegal behavior
5075// :137:21: note: when computing vector element at index '1'
5076// :141:22: error: use of undefined value here causes illegal behavior
50765077// :141:22: error: use of undefined value here causes illegal behavior
50775078// :141:22: error: use of undefined value here causes illegal behavior
5078// :141:22: note: when computing vector element at index '0'
50795079// :141:22: error: use of undefined value here causes illegal behavior
5080// :141:22: note: when computing vector element at index '0'
50815080// :141:22: error: use of undefined value here causes illegal behavior
5082// :141:22: note: when computing vector element at index '0'
50835081// :141:22: error: use of undefined value here causes illegal behavior
5084// :141:22: note: when computing vector element at index '1'
50855082// :141:22: error: use of undefined value here causes illegal behavior
5086// :141:22: note: when computing vector element at index '0'
50875083// :141:22: error: use of undefined value here causes illegal behavior
5088// :141:22: note: when computing vector element at index '0'
50895084// :141:22: error: use of undefined value here causes illegal behavior
5090// :141:22: note: when computing vector element at index '0'
50915085// :141:22: error: use of undefined value here causes illegal behavior
50925086// :141:22: error: use of undefined value here causes illegal behavior
5093// :141:22: note: when computing vector element at index '0'
50945087// :141:22: error: use of undefined value here causes illegal behavior
50955088// :141:22: note: when computing vector element at index '0'
50965089// :141:22: error: use of undefined value here causes illegal behavior
50975090// :141:22: note: when computing vector element at index '0'
50985091// :141:22: error: use of undefined value here causes illegal behavior
5099// :141:22: note: when computing vector element at index '1'
5092// :141:22: note: when computing vector element at index '0'
51005093// :141:22: error: use of undefined value here causes illegal behavior
51015094// :141:22: note: when computing vector element at index '0'
51025095// :141:22: error: use of undefined value here causes illegal behavior
......@@ -5104,6 +5097,7 @@ const std = @import("std");
51045097// :141:22: error: use of undefined value here causes illegal behavior
51055098// :141:22: note: when computing vector element at index '0'
51065099// :141:22: error: use of undefined value here causes illegal behavior
5100// :141:22: note: when computing vector element at index '0'
51075101// :141:22: error: use of undefined value here causes illegal behavior
51085102// :141:22: note: when computing vector element at index '0'
51095103// :141:22: error: use of undefined value here causes illegal behavior
......@@ -5111,7 +5105,7 @@ const std = @import("std");
51115105// :141:22: error: use of undefined value here causes illegal behavior
51125106// :141:22: note: when computing vector element at index '0'
51135107// :141:22: error: use of undefined value here causes illegal behavior
5114// :141:22: note: when computing vector element at index '1'
5108// :141:22: note: when computing vector element at index '0'
51155109// :141:22: error: use of undefined value here causes illegal behavior
51165110// :141:22: note: when computing vector element at index '0'
51175111// :141:22: error: use of undefined value here causes illegal behavior
......@@ -5119,6 +5113,7 @@ const std = @import("std");
51195113// :141:22: error: use of undefined value here causes illegal behavior
51205114// :141:22: note: when computing vector element at index '0'
51215115// :141:22: error: use of undefined value here causes illegal behavior
5116// :141:22: note: when computing vector element at index '0'
51225117// :141:22: error: use of undefined value here causes illegal behavior
51235118// :141:22: note: when computing vector element at index '0'
51245119// :141:22: error: use of undefined value here causes illegal behavior
......@@ -5126,7 +5121,7 @@ const std = @import("std");
51265121// :141:22: error: use of undefined value here causes illegal behavior
51275122// :141:22: note: when computing vector element at index '0'
51285123// :141:22: error: use of undefined value here causes illegal behavior
5129// :141:22: note: when computing vector element at index '1'
5124// :141:22: note: when computing vector element at index '0'
51305125// :141:22: error: use of undefined value here causes illegal behavior
51315126// :141:22: note: when computing vector element at index '0'
51325127// :141:22: error: use of undefined value here causes illegal behavior
......@@ -5134,6 +5129,7 @@ const std = @import("std");
51345129// :141:22: error: use of undefined value here causes illegal behavior
51355130// :141:22: note: when computing vector element at index '0'
51365131// :141:22: error: use of undefined value here causes illegal behavior
5132// :141:22: note: when computing vector element at index '0'
51375133// :141:22: error: use of undefined value here causes illegal behavior
51385134// :141:22: note: when computing vector element at index '0'
51395135// :141:22: error: use of undefined value here causes illegal behavior
......@@ -5141,7 +5137,7 @@ const std = @import("std");
51415137// :141:22: error: use of undefined value here causes illegal behavior
51425138// :141:22: note: when computing vector element at index '0'
51435139// :141:22: error: use of undefined value here causes illegal behavior
5144// :141:22: note: when computing vector element at index '1'
5140// :141:22: note: when computing vector element at index '0'
51455141// :141:22: error: use of undefined value here causes illegal behavior
51465142// :141:22: note: when computing vector element at index '0'
51475143// :141:22: error: use of undefined value here causes illegal behavior
......@@ -5149,6 +5145,7 @@ const std = @import("std");
51495145// :141:22: error: use of undefined value here causes illegal behavior
51505146// :141:22: note: when computing vector element at index '0'
51515147// :141:22: error: use of undefined value here causes illegal behavior
5148// :141:22: note: when computing vector element at index '0'
51525149// :141:22: error: use of undefined value here causes illegal behavior
51535150// :141:22: note: when computing vector element at index '0'
51545151// :141:22: error: use of undefined value here causes illegal behavior
......@@ -5156,7 +5153,7 @@ const std = @import("std");
51565153// :141:22: error: use of undefined value here causes illegal behavior
51575154// :141:22: note: when computing vector element at index '0'
51585155// :141:22: error: use of undefined value here causes illegal behavior
5159// :141:22: note: when computing vector element at index '1'
5156// :141:22: note: when computing vector element at index '0'
51605157// :141:22: error: use of undefined value here causes illegal behavior
51615158// :141:22: note: when computing vector element at index '0'
51625159// :141:22: error: use of undefined value here causes illegal behavior
......@@ -5164,6 +5161,7 @@ const std = @import("std");
51645161// :141:22: error: use of undefined value here causes illegal behavior
51655162// :141:22: note: when computing vector element at index '0'
51665163// :141:22: error: use of undefined value here causes illegal behavior
5164// :141:22: note: when computing vector element at index '0'
51675165// :141:22: error: use of undefined value here causes illegal behavior
51685166// :141:22: note: when computing vector element at index '0'
51695167// :141:22: error: use of undefined value here causes illegal behavior
......@@ -5171,7 +5169,7 @@ const std = @import("std");
51715169// :141:22: error: use of undefined value here causes illegal behavior
51725170// :141:22: note: when computing vector element at index '0'
51735171// :141:22: error: use of undefined value here causes illegal behavior
5174// :141:22: note: when computing vector element at index '1'
5172// :141:22: note: when computing vector element at index '0'
51755173// :141:22: error: use of undefined value here causes illegal behavior
51765174// :141:22: note: when computing vector element at index '0'
51775175// :141:22: error: use of undefined value here causes illegal behavior
......@@ -5179,6 +5177,7 @@ const std = @import("std");
51795177// :141:22: error: use of undefined value here causes illegal behavior
51805178// :141:22: note: when computing vector element at index '0'
51815179// :141:22: error: use of undefined value here causes illegal behavior
5180// :141:22: note: when computing vector element at index '0'
51825181// :141:22: error: use of undefined value here causes illegal behavior
51835182// :141:22: note: when computing vector element at index '0'
51845183// :141:22: error: use of undefined value here causes illegal behavior
......@@ -5186,7 +5185,7 @@ const std = @import("std");
51865185// :141:22: error: use of undefined value here causes illegal behavior
51875186// :141:22: note: when computing vector element at index '0'
51885187// :141:22: error: use of undefined value here causes illegal behavior
5189// :141:22: note: when computing vector element at index '1'
5188// :141:22: note: when computing vector element at index '0'
51905189// :141:22: error: use of undefined value here causes illegal behavior
51915190// :141:22: note: when computing vector element at index '0'
51925191// :141:22: error: use of undefined value here causes illegal behavior
......@@ -5194,6 +5193,7 @@ const std = @import("std");
51945193// :141:22: error: use of undefined value here causes illegal behavior
51955194// :141:22: note: when computing vector element at index '0'
51965195// :141:22: error: use of undefined value here causes illegal behavior
5196// :141:22: note: when computing vector element at index '0'
51975197// :141:22: error: use of undefined value here causes illegal behavior
51985198// :141:22: note: when computing vector element at index '0'
51995199// :141:22: error: use of undefined value here causes illegal behavior
......@@ -5201,7 +5201,7 @@ const std = @import("std");
52015201// :141:22: error: use of undefined value here causes illegal behavior
52025202// :141:22: note: when computing vector element at index '0'
52035203// :141:22: error: use of undefined value here causes illegal behavior
5204// :141:22: note: when computing vector element at index '1'
5204// :141:22: note: when computing vector element at index '0'
52055205// :141:22: error: use of undefined value here causes illegal behavior
52065206// :141:22: note: when computing vector element at index '0'
52075207// :141:22: error: use of undefined value here causes illegal behavior
......@@ -5209,6 +5209,7 @@ const std = @import("std");
52095209// :141:22: error: use of undefined value here causes illegal behavior
52105210// :141:22: note: when computing vector element at index '0'
52115211// :141:22: error: use of undefined value here causes illegal behavior
5212// :141:22: note: when computing vector element at index '0'
52125213// :141:22: error: use of undefined value here causes illegal behavior
52135214// :141:22: note: when computing vector element at index '0'
52145215// :141:22: error: use of undefined value here causes illegal behavior
......@@ -5218,126 +5219,120 @@ const std = @import("std");
52185219// :141:22: error: use of undefined value here causes illegal behavior
52195220// :141:22: note: when computing vector element at index '1'
52205221// :141:22: error: use of undefined value here causes illegal behavior
5221// :141:22: note: when computing vector element at index '0'
5222// :141:22: error: use of undefined value here causes illegal behavior
5223// :141:22: note: when computing vector element at index '0'
5222// :141:22: note: when computing vector element at index '1'
52245223// :141:22: error: use of undefined value here causes illegal behavior
5225// :141:22: note: when computing vector element at index '0'
5224// :141:22: note: when computing vector element at index '1'
52265225// :141:22: error: use of undefined value here causes illegal behavior
5226// :141:22: note: when computing vector element at index '1'
52275227// :141:22: error: use of undefined value here causes illegal behavior
5228// :141:22: note: when computing vector element at index '0'
5228// :141:22: note: when computing vector element at index '1'
52295229// :141:22: error: use of undefined value here causes illegal behavior
5230// :141:22: note: when computing vector element at index '0'
5230// :141:22: note: when computing vector element at index '1'
52315231// :141:22: error: use of undefined value here causes illegal behavior
5232// :141:22: note: when computing vector element at index '0'
5232// :141:22: note: when computing vector element at index '1'
52335233// :141:22: error: use of undefined value here causes illegal behavior
52345234// :141:22: note: when computing vector element at index '1'
52355235// :141:22: error: use of undefined value here causes illegal behavior
5236// :141:22: note: when computing vector element at index '0'
5236// :141:22: note: when computing vector element at index '1'
52375237// :141:22: error: use of undefined value here causes illegal behavior
5238// :141:22: note: when computing vector element at index '0'
5238// :141:22: note: when computing vector element at index '1'
52395239// :141:22: error: use of undefined value here causes illegal behavior
5240// :141:22: note: when computing vector element at index '0'
5240// :141:22: note: when computing vector element at index '1'
52415241// :141:25: error: use of undefined value here causes illegal behavior
52425242// :141:25: error: use of undefined value here causes illegal behavior
5243// :141:25: note: when computing vector element at index '0'
52445243// :141:25: error: use of undefined value here causes illegal behavior
5245// :141:25: note: when computing vector element at index '0'
52465244// :141:25: error: use of undefined value here causes illegal behavior
5247// :141:25: note: when computing vector element at index '1'
52485245// :141:25: error: use of undefined value here causes illegal behavior
5249// :141:25: note: when computing vector element at index '0'
52505246// :141:25: error: use of undefined value here causes illegal behavior
5251// :141:25: note: when computing vector element at index '0'
52525247// :141:25: error: use of undefined value here causes illegal behavior
52535248// :141:25: error: use of undefined value here causes illegal behavior
5254// :141:25: note: when computing vector element at index '0'
52555249// :141:25: error: use of undefined value here causes illegal behavior
5256// :141:25: note: when computing vector element at index '0'
52575250// :141:25: error: use of undefined value here causes illegal behavior
5258// :141:25: note: when computing vector element at index '1'
52595251// :141:25: error: use of undefined value here causes illegal behavior
5260// :141:25: note: when computing vector element at index '0'
52615252// :141:25: error: use of undefined value here causes illegal behavior
52625253// :141:25: note: when computing vector element at index '0'
52635254// :141:25: error: use of undefined value here causes illegal behavior
5264// :141:25: error: use of undefined value here causes illegal behavior
52655255// :141:25: note: when computing vector element at index '0'
52665256// :141:25: error: use of undefined value here causes illegal behavior
52675257// :141:25: note: when computing vector element at index '0'
52685258// :141:25: error: use of undefined value here causes illegal behavior
5269// :141:25: note: when computing vector element at index '1'
5270// :141:25: error: use of undefined value here causes illegal behavior
52715259// :141:25: note: when computing vector element at index '0'
52725260// :141:25: error: use of undefined value here causes illegal behavior
52735261// :141:25: note: when computing vector element at index '0'
52745262// :141:25: error: use of undefined value here causes illegal behavior
5263// :141:25: note: when computing vector element at index '0'
52755264// :141:25: error: use of undefined value here causes illegal behavior
52765265// :141:25: note: when computing vector element at index '0'
52775266// :141:25: error: use of undefined value here causes illegal behavior
52785267// :141:25: note: when computing vector element at index '0'
52795268// :141:25: error: use of undefined value here causes illegal behavior
5280// :141:25: note: when computing vector element at index '1'
5269// :141:25: note: when computing vector element at index '0'
52815270// :141:25: error: use of undefined value here causes illegal behavior
52825271// :141:25: note: when computing vector element at index '0'
52835272// :141:25: error: use of undefined value here causes illegal behavior
52845273// :141:25: note: when computing vector element at index '0'
52855274// :141:25: error: use of undefined value here causes illegal behavior
5275// :141:25: note: when computing vector element at index '0'
52865276// :141:25: error: use of undefined value here causes illegal behavior
52875277// :141:25: note: when computing vector element at index '0'
52885278// :141:25: error: use of undefined value here causes illegal behavior
52895279// :141:25: note: when computing vector element at index '0'
52905280// :141:25: error: use of undefined value here causes illegal behavior
5291// :141:25: note: when computing vector element at index '1'
5281// :141:25: note: when computing vector element at index '0'
52925282// :141:25: error: use of undefined value here causes illegal behavior
52935283// :141:25: note: when computing vector element at index '0'
52945284// :141:25: error: use of undefined value here causes illegal behavior
52955285// :141:25: note: when computing vector element at index '0'
52965286// :141:25: error: use of undefined value here causes illegal behavior
5287// :141:25: note: when computing vector element at index '0'
52975288// :141:25: error: use of undefined value here causes illegal behavior
52985289// :141:25: note: when computing vector element at index '0'
52995290// :141:25: error: use of undefined value here causes illegal behavior
53005291// :141:25: note: when computing vector element at index '0'
53015292// :141:25: error: use of undefined value here causes illegal behavior
5302// :141:25: note: when computing vector element at index '1'
5293// :141:25: note: when computing vector element at index '0'
53035294// :141:25: error: use of undefined value here causes illegal behavior
53045295// :141:25: note: when computing vector element at index '0'
53055296// :141:25: error: use of undefined value here causes illegal behavior
53065297// :141:25: note: when computing vector element at index '0'
53075298// :141:25: error: use of undefined value here causes illegal behavior
5299// :141:25: note: when computing vector element at index '0'
53085300// :141:25: error: use of undefined value here causes illegal behavior
53095301// :141:25: note: when computing vector element at index '0'
53105302// :141:25: error: use of undefined value here causes illegal behavior
53115303// :141:25: note: when computing vector element at index '0'
53125304// :141:25: error: use of undefined value here causes illegal behavior
5313// :141:25: note: when computing vector element at index '1'
5305// :141:25: note: when computing vector element at index '0'
53145306// :141:25: error: use of undefined value here causes illegal behavior
53155307// :141:25: note: when computing vector element at index '0'
53165308// :141:25: error: use of undefined value here causes illegal behavior
53175309// :141:25: note: when computing vector element at index '0'
53185310// :141:25: error: use of undefined value here causes illegal behavior
5311// :141:25: note: when computing vector element at index '0'
53195312// :141:25: error: use of undefined value here causes illegal behavior
53205313// :141:25: note: when computing vector element at index '0'
53215314// :141:25: error: use of undefined value here causes illegal behavior
53225315// :141:25: note: when computing vector element at index '0'
53235316// :141:25: error: use of undefined value here causes illegal behavior
5324// :141:25: note: when computing vector element at index '1'
5317// :141:25: note: when computing vector element at index '0'
53255318// :141:25: error: use of undefined value here causes illegal behavior
53265319// :141:25: note: when computing vector element at index '0'
53275320// :141:25: error: use of undefined value here causes illegal behavior
53285321// :141:25: note: when computing vector element at index '0'
53295322// :141:25: error: use of undefined value here causes illegal behavior
5323// :141:25: note: when computing vector element at index '0'
53305324// :141:25: error: use of undefined value here causes illegal behavior
53315325// :141:25: note: when computing vector element at index '0'
53325326// :141:25: error: use of undefined value here causes illegal behavior
53335327// :141:25: note: when computing vector element at index '0'
53345328// :141:25: error: use of undefined value here causes illegal behavior
5335// :141:25: note: when computing vector element at index '1'
5329// :141:25: note: when computing vector element at index '0'
53365330// :141:25: error: use of undefined value here causes illegal behavior
53375331// :141:25: note: when computing vector element at index '0'
53385332// :141:25: error: use of undefined value here causes illegal behavior
53395333// :141:25: note: when computing vector element at index '0'
53405334// :141:25: error: use of undefined value here causes illegal behavior
5335// :141:25: note: when computing vector element at index '0'
53415336// :141:25: error: use of undefined value here causes illegal behavior
53425337// :141:25: note: when computing vector element at index '0'
53435338// :141:25: error: use of undefined value here causes illegal behavior
......@@ -5345,44 +5340,42 @@ const std = @import("std");
53455340// :141:25: error: use of undefined value here causes illegal behavior
53465341// :141:25: note: when computing vector element at index '1'
53475342// :141:25: error: use of undefined value here causes illegal behavior
5348// :141:25: note: when computing vector element at index '0'
5343// :141:25: note: when computing vector element at index '1'
53495344// :141:25: error: use of undefined value here causes illegal behavior
5350// :141:25: note: when computing vector element at index '0'
5345// :141:25: note: when computing vector element at index '1'
53515346// :141:25: error: use of undefined value here causes illegal behavior
5347// :141:25: note: when computing vector element at index '1'
53525348// :141:25: error: use of undefined value here causes illegal behavior
5353// :141:25: note: when computing vector element at index '0'
5349// :141:25: note: when computing vector element at index '1'
53545350// :141:25: error: use of undefined value here causes illegal behavior
5355// :141:25: note: when computing vector element at index '0'
5351// :141:25: note: when computing vector element at index '1'
53565352// :141:25: error: use of undefined value here causes illegal behavior
53575353// :141:25: note: when computing vector element at index '1'
53585354// :141:25: error: use of undefined value here causes illegal behavior
5359// :141:25: note: when computing vector element at index '0'
5355// :141:25: note: when computing vector element at index '1'
53605356// :141:25: error: use of undefined value here causes illegal behavior
5361// :141:25: note: when computing vector element at index '0'
5357// :141:25: note: when computing vector element at index '1'
5358// :141:25: error: use of undefined value here causes illegal behavior
5359// :141:25: note: when computing vector element at index '1'
5360// :141:25: error: use of undefined value here causes illegal behavior
5361// :141:25: note: when computing vector element at index '1'
5362// :145:22: error: use of undefined value here causes illegal behavior
53625363// :145:22: error: use of undefined value here causes illegal behavior
53635364// :145:22: error: use of undefined value here causes illegal behavior
5364// :145:22: note: when computing vector element at index '0'
53655365// :145:22: error: use of undefined value here causes illegal behavior
5366// :145:22: note: when computing vector element at index '0'
53675366// :145:22: error: use of undefined value here causes illegal behavior
5368// :145:22: note: when computing vector element at index '0'
53695367// :145:22: error: use of undefined value here causes illegal behavior
5370// :145:22: note: when computing vector element at index '1'
53715368// :145:22: error: use of undefined value here causes illegal behavior
5372// :145:22: note: when computing vector element at index '0'
53735369// :145:22: error: use of undefined value here causes illegal behavior
5374// :145:22: note: when computing vector element at index '0'
53755370// :145:22: error: use of undefined value here causes illegal behavior
5376// :145:22: note: when computing vector element at index '0'
53775371// :145:22: error: use of undefined value here causes illegal behavior
53785372// :145:22: error: use of undefined value here causes illegal behavior
5379// :145:22: note: when computing vector element at index '0'
53805373// :145:22: error: use of undefined value here causes illegal behavior
53815374// :145:22: note: when computing vector element at index '0'
53825375// :145:22: error: use of undefined value here causes illegal behavior
53835376// :145:22: note: when computing vector element at index '0'
53845377// :145:22: error: use of undefined value here causes illegal behavior
5385// :145:22: note: when computing vector element at index '1'
5378// :145:22: note: when computing vector element at index '0'
53865379// :145:22: error: use of undefined value here causes illegal behavior
53875380// :145:22: note: when computing vector element at index '0'
53885381// :145:22: error: use of undefined value here causes illegal behavior
......@@ -5390,6 +5383,7 @@ const std = @import("std");
53905383// :145:22: error: use of undefined value here causes illegal behavior
53915384// :145:22: note: when computing vector element at index '0'
53925385// :145:22: error: use of undefined value here causes illegal behavior
5386// :145:22: note: when computing vector element at index '0'
53935387// :145:22: error: use of undefined value here causes illegal behavior
53945388// :145:22: note: when computing vector element at index '0'
53955389// :145:22: error: use of undefined value here causes illegal behavior
......@@ -5397,7 +5391,7 @@ const std = @import("std");
53975391// :145:22: error: use of undefined value here causes illegal behavior
53985392// :145:22: note: when computing vector element at index '0'
53995393// :145:22: error: use of undefined value here causes illegal behavior
5400// :145:22: note: when computing vector element at index '1'
5394// :145:22: note: when computing vector element at index '0'
54015395// :145:22: error: use of undefined value here causes illegal behavior
54025396// :145:22: note: when computing vector element at index '0'
54035397// :145:22: error: use of undefined value here causes illegal behavior
......@@ -5405,6 +5399,7 @@ const std = @import("std");
54055399// :145:22: error: use of undefined value here causes illegal behavior
54065400// :145:22: note: when computing vector element at index '0'
54075401// :145:22: error: use of undefined value here causes illegal behavior
5402// :145:22: note: when computing vector element at index '0'
54085403// :145:22: error: use of undefined value here causes illegal behavior
54095404// :145:22: note: when computing vector element at index '0'
54105405// :145:22: error: use of undefined value here causes illegal behavior
......@@ -5412,7 +5407,7 @@ const std = @import("std");
54125407// :145:22: error: use of undefined value here causes illegal behavior
54135408// :145:22: note: when computing vector element at index '0'
54145409// :145:22: error: use of undefined value here causes illegal behavior
5415// :145:22: note: when computing vector element at index '1'
5410// :145:22: note: when computing vector element at index '0'
54165411// :145:22: error: use of undefined value here causes illegal behavior
54175412// :145:22: note: when computing vector element at index '0'
54185413// :145:22: error: use of undefined value here causes illegal behavior
......@@ -5420,6 +5415,7 @@ const std = @import("std");
54205415// :145:22: error: use of undefined value here causes illegal behavior
54215416// :145:22: note: when computing vector element at index '0'
54225417// :145:22: error: use of undefined value here causes illegal behavior
5418// :145:22: note: when computing vector element at index '0'
54235419// :145:22: error: use of undefined value here causes illegal behavior
54245420// :145:22: note: when computing vector element at index '0'
54255421// :145:22: error: use of undefined value here causes illegal behavior
......@@ -5427,7 +5423,7 @@ const std = @import("std");
54275423// :145:22: error: use of undefined value here causes illegal behavior
54285424// :145:22: note: when computing vector element at index '0'
54295425// :145:22: error: use of undefined value here causes illegal behavior
5430// :145:22: note: when computing vector element at index '1'
5426// :145:22: note: when computing vector element at index '0'
54315427// :145:22: error: use of undefined value here causes illegal behavior
54325428// :145:22: note: when computing vector element at index '0'
54335429// :145:22: error: use of undefined value here causes illegal behavior
......@@ -5435,6 +5431,7 @@ const std = @import("std");
54355431// :145:22: error: use of undefined value here causes illegal behavior
54365432// :145:22: note: when computing vector element at index '0'
54375433// :145:22: error: use of undefined value here causes illegal behavior
5434// :145:22: note: when computing vector element at index '0'
54385435// :145:22: error: use of undefined value here causes illegal behavior
54395436// :145:22: note: when computing vector element at index '0'
54405437// :145:22: error: use of undefined value here causes illegal behavior
......@@ -5442,7 +5439,7 @@ const std = @import("std");
54425439// :145:22: error: use of undefined value here causes illegal behavior
54435440// :145:22: note: when computing vector element at index '0'
54445441// :145:22: error: use of undefined value here causes illegal behavior
5445// :145:22: note: when computing vector element at index '1'
5442// :145:22: note: when computing vector element at index '0'
54465443// :145:22: error: use of undefined value here causes illegal behavior
54475444// :145:22: note: when computing vector element at index '0'
54485445// :145:22: error: use of undefined value here causes illegal behavior
......@@ -5450,6 +5447,7 @@ const std = @import("std");
54505447// :145:22: error: use of undefined value here causes illegal behavior
54515448// :145:22: note: when computing vector element at index '0'
54525449// :145:22: error: use of undefined value here causes illegal behavior
5450// :145:22: note: when computing vector element at index '0'
54535451// :145:22: error: use of undefined value here causes illegal behavior
54545452// :145:22: note: when computing vector element at index '0'
54555453// :145:22: error: use of undefined value here causes illegal behavior
......@@ -5457,7 +5455,7 @@ const std = @import("std");
54575455// :145:22: error: use of undefined value here causes illegal behavior
54585456// :145:22: note: when computing vector element at index '0'
54595457// :145:22: error: use of undefined value here causes illegal behavior
5460// :145:22: note: when computing vector element at index '1'
5458// :145:22: note: when computing vector element at index '0'
54615459// :145:22: error: use of undefined value here causes illegal behavior
54625460// :145:22: note: when computing vector element at index '0'
54635461// :145:22: error: use of undefined value here causes illegal behavior
......@@ -5465,6 +5463,7 @@ const std = @import("std");
54655463// :145:22: error: use of undefined value here causes illegal behavior
54665464// :145:22: note: when computing vector element at index '0'
54675465// :145:22: error: use of undefined value here causes illegal behavior
5466// :145:22: note: when computing vector element at index '0'
54685467// :145:22: error: use of undefined value here causes illegal behavior
54695468// :145:22: note: when computing vector element at index '0'
54705469// :145:22: error: use of undefined value here causes illegal behavior
......@@ -5472,7 +5471,7 @@ const std = @import("std");
54725471// :145:22: error: use of undefined value here causes illegal behavior
54735472// :145:22: note: when computing vector element at index '0'
54745473// :145:22: error: use of undefined value here causes illegal behavior
5475// :145:22: note: when computing vector element at index '1'
5474// :145:22: note: when computing vector element at index '0'
54765475// :145:22: error: use of undefined value here causes illegal behavior
54775476// :145:22: note: when computing vector element at index '0'
54785477// :145:22: error: use of undefined value here causes illegal behavior
......@@ -5480,6 +5479,7 @@ const std = @import("std");
54805479// :145:22: error: use of undefined value here causes illegal behavior
54815480// :145:22: note: when computing vector element at index '0'
54825481// :145:22: error: use of undefined value here causes illegal behavior
5482// :145:22: note: when computing vector element at index '0'
54835483// :145:22: error: use of undefined value here causes illegal behavior
54845484// :145:22: note: when computing vector element at index '0'
54855485// :145:22: error: use of undefined value here causes illegal behavior
......@@ -5487,7 +5487,7 @@ const std = @import("std");
54875487// :145:22: error: use of undefined value here causes illegal behavior
54885488// :145:22: note: when computing vector element at index '0'
54895489// :145:22: error: use of undefined value here causes illegal behavior
5490// :145:22: note: when computing vector element at index '1'
5490// :145:22: note: when computing vector element at index '0'
54915491// :145:22: error: use of undefined value here causes illegal behavior
54925492// :145:22: note: when computing vector element at index '0'
54935493// :145:22: error: use of undefined value here causes illegal behavior
......@@ -5495,6 +5495,7 @@ const std = @import("std");
54955495// :145:22: error: use of undefined value here causes illegal behavior
54965496// :145:22: note: when computing vector element at index '0'
54975497// :145:22: error: use of undefined value here causes illegal behavior
5498// :145:22: note: when computing vector element at index '0'
54985499// :145:22: error: use of undefined value here causes illegal behavior
54995500// :145:22: note: when computing vector element at index '0'
55005501// :145:22: error: use of undefined value here causes illegal behavior
......@@ -5504,126 +5505,120 @@ const std = @import("std");
55045505// :145:22: error: use of undefined value here causes illegal behavior
55055506// :145:22: note: when computing vector element at index '1'
55065507// :145:22: error: use of undefined value here causes illegal behavior
5507// :145:22: note: when computing vector element at index '0'
5508// :145:22: error: use of undefined value here causes illegal behavior
5509// :145:22: note: when computing vector element at index '0'
5508// :145:22: note: when computing vector element at index '1'
55105509// :145:22: error: use of undefined value here causes illegal behavior
5511// :145:22: note: when computing vector element at index '0'
5510// :145:22: note: when computing vector element at index '1'
55125511// :145:22: error: use of undefined value here causes illegal behavior
5512// :145:22: note: when computing vector element at index '1'
55135513// :145:22: error: use of undefined value here causes illegal behavior
5514// :145:22: note: when computing vector element at index '0'
5514// :145:22: note: when computing vector element at index '1'
55155515// :145:22: error: use of undefined value here causes illegal behavior
5516// :145:22: note: when computing vector element at index '0'
5516// :145:22: note: when computing vector element at index '1'
55175517// :145:22: error: use of undefined value here causes illegal behavior
5518// :145:22: note: when computing vector element at index '0'
5518// :145:22: note: when computing vector element at index '1'
55195519// :145:22: error: use of undefined value here causes illegal behavior
55205520// :145:22: note: when computing vector element at index '1'
55215521// :145:22: error: use of undefined value here causes illegal behavior
5522// :145:22: note: when computing vector element at index '0'
5522// :145:22: note: when computing vector element at index '1'
55235523// :145:22: error: use of undefined value here causes illegal behavior
5524// :145:22: note: when computing vector element at index '0'
5524// :145:22: note: when computing vector element at index '1'
55255525// :145:22: error: use of undefined value here causes illegal behavior
5526// :145:22: note: when computing vector element at index '0'
5526// :145:22: note: when computing vector element at index '1'
55275527// :145:25: error: use of undefined value here causes illegal behavior
55285528// :145:25: error: use of undefined value here causes illegal behavior
5529// :145:25: note: when computing vector element at index '0'
55305529// :145:25: error: use of undefined value here causes illegal behavior
5531// :145:25: note: when computing vector element at index '0'
55325530// :145:25: error: use of undefined value here causes illegal behavior
5533// :145:25: note: when computing vector element at index '1'
55345531// :145:25: error: use of undefined value here causes illegal behavior
5535// :145:25: note: when computing vector element at index '0'
55365532// :145:25: error: use of undefined value here causes illegal behavior
5537// :145:25: note: when computing vector element at index '0'
55385533// :145:25: error: use of undefined value here causes illegal behavior
55395534// :145:25: error: use of undefined value here causes illegal behavior
5540// :145:25: note: when computing vector element at index '0'
55415535// :145:25: error: use of undefined value here causes illegal behavior
5542// :145:25: note: when computing vector element at index '0'
55435536// :145:25: error: use of undefined value here causes illegal behavior
5544// :145:25: note: when computing vector element at index '1'
55455537// :145:25: error: use of undefined value here causes illegal behavior
5546// :145:25: note: when computing vector element at index '0'
55475538// :145:25: error: use of undefined value here causes illegal behavior
55485539// :145:25: note: when computing vector element at index '0'
55495540// :145:25: error: use of undefined value here causes illegal behavior
5550// :145:25: error: use of undefined value here causes illegal behavior
55515541// :145:25: note: when computing vector element at index '0'
55525542// :145:25: error: use of undefined value here causes illegal behavior
55535543// :145:25: note: when computing vector element at index '0'
55545544// :145:25: error: use of undefined value here causes illegal behavior
5555// :145:25: note: when computing vector element at index '1'
5556// :145:25: error: use of undefined value here causes illegal behavior
55575545// :145:25: note: when computing vector element at index '0'
55585546// :145:25: error: use of undefined value here causes illegal behavior
55595547// :145:25: note: when computing vector element at index '0'
55605548// :145:25: error: use of undefined value here causes illegal behavior
5549// :145:25: note: when computing vector element at index '0'
55615550// :145:25: error: use of undefined value here causes illegal behavior
55625551// :145:25: note: when computing vector element at index '0'
55635552// :145:25: error: use of undefined value here causes illegal behavior
55645553// :145:25: note: when computing vector element at index '0'
55655554// :145:25: error: use of undefined value here causes illegal behavior
5566// :145:25: note: when computing vector element at index '1'
5555// :145:25: note: when computing vector element at index '0'
55675556// :145:25: error: use of undefined value here causes illegal behavior
55685557// :145:25: note: when computing vector element at index '0'
55695558// :145:25: error: use of undefined value here causes illegal behavior
55705559// :145:25: note: when computing vector element at index '0'
55715560// :145:25: error: use of undefined value here causes illegal behavior
5561// :145:25: note: when computing vector element at index '0'
55725562// :145:25: error: use of undefined value here causes illegal behavior
55735563// :145:25: note: when computing vector element at index '0'
55745564// :145:25: error: use of undefined value here causes illegal behavior
55755565// :145:25: note: when computing vector element at index '0'
55765566// :145:25: error: use of undefined value here causes illegal behavior
5577// :145:25: note: when computing vector element at index '1'
5567// :145:25: note: when computing vector element at index '0'
55785568// :145:25: error: use of undefined value here causes illegal behavior
55795569// :145:25: note: when computing vector element at index '0'
55805570// :145:25: error: use of undefined value here causes illegal behavior
55815571// :145:25: note: when computing vector element at index '0'
55825572// :145:25: error: use of undefined value here causes illegal behavior
5573// :145:25: note: when computing vector element at index '0'
55835574// :145:25: error: use of undefined value here causes illegal behavior
55845575// :145:25: note: when computing vector element at index '0'
55855576// :145:25: error: use of undefined value here causes illegal behavior
55865577// :145:25: note: when computing vector element at index '0'
55875578// :145:25: error: use of undefined value here causes illegal behavior
5588// :145:25: note: when computing vector element at index '1'
5579// :145:25: note: when computing vector element at index '0'
55895580// :145:25: error: use of undefined value here causes illegal behavior
55905581// :145:25: note: when computing vector element at index '0'
55915582// :145:25: error: use of undefined value here causes illegal behavior
55925583// :145:25: note: when computing vector element at index '0'
55935584// :145:25: error: use of undefined value here causes illegal behavior
5585// :145:25: note: when computing vector element at index '0'
55945586// :145:25: error: use of undefined value here causes illegal behavior
55955587// :145:25: note: when computing vector element at index '0'
55965588// :145:25: error: use of undefined value here causes illegal behavior
55975589// :145:25: note: when computing vector element at index '0'
55985590// :145:25: error: use of undefined value here causes illegal behavior
5599// :145:25: note: when computing vector element at index '1'
5591// :145:25: note: when computing vector element at index '0'
56005592// :145:25: error: use of undefined value here causes illegal behavior
56015593// :145:25: note: when computing vector element at index '0'
56025594// :145:25: error: use of undefined value here causes illegal behavior
56035595// :145:25: note: when computing vector element at index '0'
56045596// :145:25: error: use of undefined value here causes illegal behavior
5597// :145:25: note: when computing vector element at index '0'
56055598// :145:25: error: use of undefined value here causes illegal behavior
56065599// :145:25: note: when computing vector element at index '0'
56075600// :145:25: error: use of undefined value here causes illegal behavior
56085601// :145:25: note: when computing vector element at index '0'
56095602// :145:25: error: use of undefined value here causes illegal behavior
5610// :145:25: note: when computing vector element at index '1'
5603// :145:25: note: when computing vector element at index '0'
56115604// :145:25: error: use of undefined value here causes illegal behavior
56125605// :145:25: note: when computing vector element at index '0'
56135606// :145:25: error: use of undefined value here causes illegal behavior
56145607// :145:25: note: when computing vector element at index '0'
56155608// :145:25: error: use of undefined value here causes illegal behavior
5609// :145:25: note: when computing vector element at index '0'
56165610// :145:25: error: use of undefined value here causes illegal behavior
56175611// :145:25: note: when computing vector element at index '0'
56185612// :145:25: error: use of undefined value here causes illegal behavior
56195613// :145:25: note: when computing vector element at index '0'
56205614// :145:25: error: use of undefined value here causes illegal behavior
5621// :145:25: note: when computing vector element at index '1'
5615// :145:25: note: when computing vector element at index '0'
56225616// :145:25: error: use of undefined value here causes illegal behavior
56235617// :145:25: note: when computing vector element at index '0'
56245618// :145:25: error: use of undefined value here causes illegal behavior
56255619// :145:25: note: when computing vector element at index '0'
56265620// :145:25: error: use of undefined value here causes illegal behavior
5621// :145:25: note: when computing vector element at index '0'
56275622// :145:25: error: use of undefined value here causes illegal behavior
56285623// :145:25: note: when computing vector element at index '0'
56295624// :145:25: error: use of undefined value here causes illegal behavior
......@@ -5631,20 +5626,25 @@ const std = @import("std");
56315626// :145:25: error: use of undefined value here causes illegal behavior
56325627// :145:25: note: when computing vector element at index '1'
56335628// :145:25: error: use of undefined value here causes illegal behavior
5634// :145:25: note: when computing vector element at index '0'
5629// :145:25: note: when computing vector element at index '1'
56355630// :145:25: error: use of undefined value here causes illegal behavior
5636// :145:25: note: when computing vector element at index '0'
5631// :145:25: note: when computing vector element at index '1'
5632// :145:25: error: use of undefined value here causes illegal behavior
5633// :145:25: note: when computing vector element at index '1'
56375634// :145:25: error: use of undefined value here causes illegal behavior
5635// :145:25: note: when computing vector element at index '1'
56385636// :145:25: error: use of undefined value here causes illegal behavior
5639// :145:25: note: when computing vector element at index '0'
5637// :145:25: note: when computing vector element at index '1'
56405638// :145:25: error: use of undefined value here causes illegal behavior
5641// :145:25: note: when computing vector element at index '0'
5639// :145:25: note: when computing vector element at index '1'
56425640// :145:25: error: use of undefined value here causes illegal behavior
56435641// :145:25: note: when computing vector element at index '1'
56445642// :145:25: error: use of undefined value here causes illegal behavior
5645// :145:25: note: when computing vector element at index '0'
5643// :145:25: note: when computing vector element at index '1'
56465644// :145:25: error: use of undefined value here causes illegal behavior
5647// :145:25: note: when computing vector element at index '0'
5645// :145:25: note: when computing vector element at index '1'
5646// :145:25: error: use of undefined value here causes illegal behavior
5647// :145:25: note: when computing vector element at index '1'
56485648// :151:21: error: use of undefined value here causes illegal behavior
56495649// :151:21: error: use of undefined value here causes illegal behavior
56505650// :151:21: error: use of undefined value here causes illegal behavior
......@@ -5652,21 +5652,13 @@ const std = @import("std");
56525652// :151:21: error: use of undefined value here causes illegal behavior
56535653// :151:21: error: use of undefined value here causes illegal behavior
56545654// :151:21: error: use of undefined value here causes illegal behavior
5655// :151:21: note: when computing vector element at index '1'
56565655// :151:21: error: use of undefined value here causes illegal behavior
5657// :151:21: note: when computing vector element at index '1'
56585656// :151:21: error: use of undefined value here causes illegal behavior
5659// :151:21: note: when computing vector element at index '1'
56605657// :151:21: error: use of undefined value here causes illegal behavior
5661// :151:21: note: when computing vector element at index '1'
56625658// :151:21: error: use of undefined value here causes illegal behavior
5663// :151:21: note: when computing vector element at index '0'
56645659// :151:21: error: use of undefined value here causes illegal behavior
5665// :151:21: note: when computing vector element at index '0'
56665660// :151:21: error: use of undefined value here causes illegal behavior
5667// :151:21: note: when computing vector element at index '0'
56685661// :151:21: error: use of undefined value here causes illegal behavior
5669// :151:21: note: when computing vector element at index '0'
56705662// :151:21: error: use of undefined value here causes illegal behavior
56715663// :151:21: error: use of undefined value here causes illegal behavior
56725664// :151:21: error: use of undefined value here causes illegal behavior
......@@ -5674,21 +5666,13 @@ const std = @import("std");
56745666// :151:21: error: use of undefined value here causes illegal behavior
56755667// :151:21: error: use of undefined value here causes illegal behavior
56765668// :151:21: error: use of undefined value here causes illegal behavior
5677// :151:21: note: when computing vector element at index '1'
56785669// :151:21: error: use of undefined value here causes illegal behavior
5679// :151:21: note: when computing vector element at index '1'
56805670// :151:21: error: use of undefined value here causes illegal behavior
5681// :151:21: note: when computing vector element at index '1'
56825671// :151:21: error: use of undefined value here causes illegal behavior
5683// :151:21: note: when computing vector element at index '1'
56845672// :151:21: error: use of undefined value here causes illegal behavior
5685// :151:21: note: when computing vector element at index '0'
56865673// :151:21: error: use of undefined value here causes illegal behavior
5687// :151:21: note: when computing vector element at index '0'
56885674// :151:21: error: use of undefined value here causes illegal behavior
5689// :151:21: note: when computing vector element at index '0'
56905675// :151:21: error: use of undefined value here causes illegal behavior
5691// :151:21: note: when computing vector element at index '0'
56925676// :151:21: error: use of undefined value here causes illegal behavior
56935677// :151:21: error: use of undefined value here causes illegal behavior
56945678// :151:21: error: use of undefined value here causes illegal behavior
......@@ -5696,21 +5680,13 @@ const std = @import("std");
56965680// :151:21: error: use of undefined value here causes illegal behavior
56975681// :151:21: error: use of undefined value here causes illegal behavior
56985682// :151:21: error: use of undefined value here causes illegal behavior
5699// :151:21: note: when computing vector element at index '1'
57005683// :151:21: error: use of undefined value here causes illegal behavior
5701// :151:21: note: when computing vector element at index '1'
57025684// :151:21: error: use of undefined value here causes illegal behavior
5703// :151:21: note: when computing vector element at index '1'
57045685// :151:21: error: use of undefined value here causes illegal behavior
5705// :151:21: note: when computing vector element at index '1'
57065686// :151:21: error: use of undefined value here causes illegal behavior
5707// :151:21: note: when computing vector element at index '0'
57085687// :151:21: error: use of undefined value here causes illegal behavior
5709// :151:21: note: when computing vector element at index '0'
57105688// :151:21: error: use of undefined value here causes illegal behavior
5711// :151:21: note: when computing vector element at index '0'
57125689// :151:21: error: use of undefined value here causes illegal behavior
5713// :151:21: note: when computing vector element at index '0'
57145690// :151:21: error: use of undefined value here causes illegal behavior
57155691// :151:21: error: use of undefined value here causes illegal behavior
57165692// :151:21: error: use of undefined value here causes illegal behavior
......@@ -5718,21 +5694,13 @@ const std = @import("std");
57185694// :151:21: error: use of undefined value here causes illegal behavior
57195695// :151:21: error: use of undefined value here causes illegal behavior
57205696// :151:21: error: use of undefined value here causes illegal behavior
5721// :151:21: note: when computing vector element at index '1'
57225697// :151:21: error: use of undefined value here causes illegal behavior
5723// :151:21: note: when computing vector element at index '1'
57245698// :151:21: error: use of undefined value here causes illegal behavior
5725// :151:21: note: when computing vector element at index '1'
57265699// :151:21: error: use of undefined value here causes illegal behavior
5727// :151:21: note: when computing vector element at index '1'
57285700// :151:21: error: use of undefined value here causes illegal behavior
5729// :151:21: note: when computing vector element at index '0'
57305701// :151:21: error: use of undefined value here causes illegal behavior
5731// :151:21: note: when computing vector element at index '0'
57325702// :151:21: error: use of undefined value here causes illegal behavior
5733// :151:21: note: when computing vector element at index '0'
57345703// :151:21: error: use of undefined value here causes illegal behavior
5735// :151:21: note: when computing vector element at index '0'
57365704// :151:21: error: use of undefined value here causes illegal behavior
57375705// :151:21: error: use of undefined value here causes illegal behavior
57385706// :151:21: error: use of undefined value here causes illegal behavior
......@@ -5740,13 +5708,9 @@ const std = @import("std");
57405708// :151:21: error: use of undefined value here causes illegal behavior
57415709// :151:21: error: use of undefined value here causes illegal behavior
57425710// :151:21: error: use of undefined value here causes illegal behavior
5743// :151:21: note: when computing vector element at index '1'
57445711// :151:21: error: use of undefined value here causes illegal behavior
5745// :151:21: note: when computing vector element at index '1'
57465712// :151:21: error: use of undefined value here causes illegal behavior
5747// :151:21: note: when computing vector element at index '1'
57485713// :151:21: error: use of undefined value here causes illegal behavior
5749// :151:21: note: when computing vector element at index '1'
57505714// :151:21: error: use of undefined value here causes illegal behavior
57515715// :151:21: note: when computing vector element at index '0'
57525716// :151:21: error: use of undefined value here causes illegal behavior
......@@ -5756,19 +5720,21 @@ const std = @import("std");
57565720// :151:21: error: use of undefined value here causes illegal behavior
57575721// :151:21: note: when computing vector element at index '0'
57585722// :151:21: error: use of undefined value here causes illegal behavior
5723// :151:21: note: when computing vector element at index '0'
57595724// :151:21: error: use of undefined value here causes illegal behavior
5725// :151:21: note: when computing vector element at index '0'
57605726// :151:21: error: use of undefined value here causes illegal behavior
5727// :151:21: note: when computing vector element at index '0'
57615728// :151:21: error: use of undefined value here causes illegal behavior
5729// :151:21: note: when computing vector element at index '0'
57625730// :151:21: error: use of undefined value here causes illegal behavior
5731// :151:21: note: when computing vector element at index '0'
57635732// :151:21: error: use of undefined value here causes illegal behavior
5733// :151:21: note: when computing vector element at index '0'
57645734// :151:21: error: use of undefined value here causes illegal behavior
5765// :151:21: note: when computing vector element at index '1'
5766// :151:21: error: use of undefined value here causes illegal behavior
5767// :151:21: note: when computing vector element at index '1'
5768// :151:21: error: use of undefined value here causes illegal behavior
5769// :151:21: note: when computing vector element at index '1'
5735// :151:21: note: when computing vector element at index '0'
57705736// :151:21: error: use of undefined value here causes illegal behavior
5771// :151:21: note: when computing vector element at index '1'
5737// :151:21: note: when computing vector element at index '0'
57725738// :151:21: error: use of undefined value here causes illegal behavior
57735739// :151:21: note: when computing vector element at index '0'
57745740// :151:21: error: use of undefined value here causes illegal behavior
......@@ -5778,19 +5744,25 @@ const std = @import("std");
57785744// :151:21: error: use of undefined value here causes illegal behavior
57795745// :151:21: note: when computing vector element at index '0'
57805746// :151:21: error: use of undefined value here causes illegal behavior
5747// :151:21: note: when computing vector element at index '0'
57815748// :151:21: error: use of undefined value here causes illegal behavior
5749// :151:21: note: when computing vector element at index '0'
57825750// :151:21: error: use of undefined value here causes illegal behavior
5751// :151:21: note: when computing vector element at index '0'
57835752// :151:21: error: use of undefined value here causes illegal behavior
5753// :151:21: note: when computing vector element at index '0'
57845754// :151:21: error: use of undefined value here causes illegal behavior
5755// :151:21: note: when computing vector element at index '0'
57855756// :151:21: error: use of undefined value here causes illegal behavior
5757// :151:21: note: when computing vector element at index '0'
57865758// :151:21: error: use of undefined value here causes illegal behavior
5787// :151:21: note: when computing vector element at index '1'
5759// :151:21: note: when computing vector element at index '0'
57885760// :151:21: error: use of undefined value here causes illegal behavior
5789// :151:21: note: when computing vector element at index '1'
5761// :151:21: note: when computing vector element at index '0'
57905762// :151:21: error: use of undefined value here causes illegal behavior
5791// :151:21: note: when computing vector element at index '1'
5763// :151:21: note: when computing vector element at index '0'
57925764// :151:21: error: use of undefined value here causes illegal behavior
5793// :151:21: note: when computing vector element at index '1'
5765// :151:21: note: when computing vector element at index '0'
57945766// :151:21: error: use of undefined value here causes illegal behavior
57955767// :151:21: note: when computing vector element at index '0'
57965768// :151:21: error: use of undefined value here causes illegal behavior
......@@ -5800,19 +5772,25 @@ const std = @import("std");
58005772// :151:21: error: use of undefined value here causes illegal behavior
58015773// :151:21: note: when computing vector element at index '0'
58025774// :151:21: error: use of undefined value here causes illegal behavior
5775// :151:21: note: when computing vector element at index '0'
58035776// :151:21: error: use of undefined value here causes illegal behavior
5777// :151:21: note: when computing vector element at index '0'
58045778// :151:21: error: use of undefined value here causes illegal behavior
5779// :151:21: note: when computing vector element at index '0'
58055780// :151:21: error: use of undefined value here causes illegal behavior
5781// :151:21: note: when computing vector element at index '0'
58065782// :151:21: error: use of undefined value here causes illegal behavior
5783// :151:21: note: when computing vector element at index '0'
58075784// :151:21: error: use of undefined value here causes illegal behavior
5785// :151:21: note: when computing vector element at index '0'
58085786// :151:21: error: use of undefined value here causes illegal behavior
5809// :151:21: note: when computing vector element at index '1'
5787// :151:21: note: when computing vector element at index '0'
58105788// :151:21: error: use of undefined value here causes illegal behavior
5811// :151:21: note: when computing vector element at index '1'
5789// :151:21: note: when computing vector element at index '0'
58125790// :151:21: error: use of undefined value here causes illegal behavior
5813// :151:21: note: when computing vector element at index '1'
5791// :151:21: note: when computing vector element at index '0'
58145792// :151:21: error: use of undefined value here causes illegal behavior
5815// :151:21: note: when computing vector element at index '1'
5793// :151:21: note: when computing vector element at index '0'
58165794// :151:21: error: use of undefined value here causes illegal behavior
58175795// :151:21: note: when computing vector element at index '0'
58185796// :151:21: error: use of undefined value here causes illegal behavior
......@@ -5822,11 +5800,17 @@ const std = @import("std");
58225800// :151:21: error: use of undefined value here causes illegal behavior
58235801// :151:21: note: when computing vector element at index '0'
58245802// :151:21: error: use of undefined value here causes illegal behavior
5803// :151:21: note: when computing vector element at index '1'
58255804// :151:21: error: use of undefined value here causes illegal behavior
5805// :151:21: note: when computing vector element at index '1'
58265806// :151:21: error: use of undefined value here causes illegal behavior
5807// :151:21: note: when computing vector element at index '1'
58275808// :151:21: error: use of undefined value here causes illegal behavior
5809// :151:21: note: when computing vector element at index '1'
58285810// :151:21: error: use of undefined value here causes illegal behavior
5811// :151:21: note: when computing vector element at index '1'
58295812// :151:21: error: use of undefined value here causes illegal behavior
5813// :151:21: note: when computing vector element at index '1'
58305814// :151:21: error: use of undefined value here causes illegal behavior
58315815// :151:21: note: when computing vector element at index '1'
58325816// :151:21: error: use of undefined value here causes illegal behavior
......@@ -5836,19 +5820,25 @@ const std = @import("std");
58365820// :151:21: error: use of undefined value here causes illegal behavior
58375821// :151:21: note: when computing vector element at index '1'
58385822// :151:21: error: use of undefined value here causes illegal behavior
5839// :151:21: note: when computing vector element at index '0'
5823// :151:21: note: when computing vector element at index '1'
58405824// :151:21: error: use of undefined value here causes illegal behavior
5841// :151:21: note: when computing vector element at index '0'
5825// :151:21: note: when computing vector element at index '1'
58425826// :151:21: error: use of undefined value here causes illegal behavior
5843// :151:21: note: when computing vector element at index '0'
5827// :151:21: note: when computing vector element at index '1'
58445828// :151:21: error: use of undefined value here causes illegal behavior
5845// :151:21: note: when computing vector element at index '0'
5829// :151:21: note: when computing vector element at index '1'
58465830// :151:21: error: use of undefined value here causes illegal behavior
5831// :151:21: note: when computing vector element at index '1'
58475832// :151:21: error: use of undefined value here causes illegal behavior
5833// :151:21: note: when computing vector element at index '1'
58485834// :151:21: error: use of undefined value here causes illegal behavior
5835// :151:21: note: when computing vector element at index '1'
58495836// :151:21: error: use of undefined value here causes illegal behavior
5837// :151:21: note: when computing vector element at index '1'
58505838// :151:21: error: use of undefined value here causes illegal behavior
5839// :151:21: note: when computing vector element at index '1'
58515840// :151:21: error: use of undefined value here causes illegal behavior
5841// :151:21: note: when computing vector element at index '1'
58525842// :151:21: error: use of undefined value here causes illegal behavior
58535843// :151:21: note: when computing vector element at index '1'
58545844// :151:21: error: use of undefined value here causes illegal behavior
......@@ -5858,19 +5848,25 @@ const std = @import("std");
58585848// :151:21: error: use of undefined value here causes illegal behavior
58595849// :151:21: note: when computing vector element at index '1'
58605850// :151:21: error: use of undefined value here causes illegal behavior
5861// :151:21: note: when computing vector element at index '0'
5851// :151:21: note: when computing vector element at index '1'
58625852// :151:21: error: use of undefined value here causes illegal behavior
5863// :151:21: note: when computing vector element at index '0'
5853// :151:21: note: when computing vector element at index '1'
58645854// :151:21: error: use of undefined value here causes illegal behavior
5865// :151:21: note: when computing vector element at index '0'
5855// :151:21: note: when computing vector element at index '1'
58665856// :151:21: error: use of undefined value here causes illegal behavior
5867// :151:21: note: when computing vector element at index '0'
5857// :151:21: note: when computing vector element at index '1'
58685858// :151:21: error: use of undefined value here causes illegal behavior
5859// :151:21: note: when computing vector element at index '1'
58695860// :151:21: error: use of undefined value here causes illegal behavior
5861// :151:21: note: when computing vector element at index '1'
58705862// :151:21: error: use of undefined value here causes illegal behavior
5863// :151:21: note: when computing vector element at index '1'
58715864// :151:21: error: use of undefined value here causes illegal behavior
5865// :151:21: note: when computing vector element at index '1'
58725866// :151:21: error: use of undefined value here causes illegal behavior
5867// :151:21: note: when computing vector element at index '1'
58735868// :151:21: error: use of undefined value here causes illegal behavior
5869// :151:21: note: when computing vector element at index '1'
58745870// :151:21: error: use of undefined value here causes illegal behavior
58755871// :151:21: note: when computing vector element at index '1'
58765872// :151:21: error: use of undefined value here causes illegal behavior
......@@ -5880,13 +5876,17 @@ const std = @import("std");
58805876// :151:21: error: use of undefined value here causes illegal behavior
58815877// :151:21: note: when computing vector element at index '1'
58825878// :151:21: error: use of undefined value here causes illegal behavior
5883// :151:21: note: when computing vector element at index '0'
5879// :151:21: note: when computing vector element at index '1'
58845880// :151:21: error: use of undefined value here causes illegal behavior
5885// :151:21: note: when computing vector element at index '0'
5881// :151:21: note: when computing vector element at index '1'
58865882// :151:21: error: use of undefined value here causes illegal behavior
5887// :151:21: note: when computing vector element at index '0'
5883// :151:21: note: when computing vector element at index '1'
58885884// :151:21: error: use of undefined value here causes illegal behavior
5889// :151:21: note: when computing vector element at index '0'
5885// :151:21: note: when computing vector element at index '1'
5886// :151:21: error: use of undefined value here causes illegal behavior
5887// :151:21: note: when computing vector element at index '1'
5888// :151:21: error: use of undefined value here causes illegal behavior
5889// :151:21: note: when computing vector element at index '1'
58905890// :155:30: error: use of undefined value here causes illegal behavior
58915891// :155:30: error: use of undefined value here causes illegal behavior
58925892// :155:30: error: use of undefined value here causes illegal behavior
......@@ -5894,21 +5894,13 @@ const std = @import("std");
58945894// :155:30: error: use of undefined value here causes illegal behavior
58955895// :155:30: error: use of undefined value here causes illegal behavior
58965896// :155:30: error: use of undefined value here causes illegal behavior
5897// :155:30: note: when computing vector element at index '1'
58985897// :155:30: error: use of undefined value here causes illegal behavior
5899// :155:30: note: when computing vector element at index '1'
59005898// :155:30: error: use of undefined value here causes illegal behavior
5901// :155:30: note: when computing vector element at index '1'
59025899// :155:30: error: use of undefined value here causes illegal behavior
5903// :155:30: note: when computing vector element at index '1'
59045900// :155:30: error: use of undefined value here causes illegal behavior
5905// :155:30: note: when computing vector element at index '0'
59065901// :155:30: error: use of undefined value here causes illegal behavior
5907// :155:30: note: when computing vector element at index '0'
59085902// :155:30: error: use of undefined value here causes illegal behavior
5909// :155:30: note: when computing vector element at index '0'
59105903// :155:30: error: use of undefined value here causes illegal behavior
5911// :155:30: note: when computing vector element at index '0'
59125904// :155:30: error: use of undefined value here causes illegal behavior
59135905// :155:30: error: use of undefined value here causes illegal behavior
59145906// :155:30: error: use of undefined value here causes illegal behavior
......@@ -5916,21 +5908,13 @@ const std = @import("std");
59165908// :155:30: error: use of undefined value here causes illegal behavior
59175909// :155:30: error: use of undefined value here causes illegal behavior
59185910// :155:30: error: use of undefined value here causes illegal behavior
5919// :155:30: note: when computing vector element at index '1'
59205911// :155:30: error: use of undefined value here causes illegal behavior
5921// :155:30: note: when computing vector element at index '1'
59225912// :155:30: error: use of undefined value here causes illegal behavior
5923// :155:30: note: when computing vector element at index '1'
59245913// :155:30: error: use of undefined value here causes illegal behavior
5925// :155:30: note: when computing vector element at index '1'
59265914// :155:30: error: use of undefined value here causes illegal behavior
5927// :155:30: note: when computing vector element at index '0'
59285915// :155:30: error: use of undefined value here causes illegal behavior
5929// :155:30: note: when computing vector element at index '0'
59305916// :155:30: error: use of undefined value here causes illegal behavior
5931// :155:30: note: when computing vector element at index '0'
59325917// :155:30: error: use of undefined value here causes illegal behavior
5933// :155:30: note: when computing vector element at index '0'
59345918// :155:30: error: use of undefined value here causes illegal behavior
59355919// :155:30: error: use of undefined value here causes illegal behavior
59365920// :155:30: error: use of undefined value here causes illegal behavior
......@@ -5938,21 +5922,13 @@ const std = @import("std");
59385922// :155:30: error: use of undefined value here causes illegal behavior
59395923// :155:30: error: use of undefined value here causes illegal behavior
59405924// :155:30: error: use of undefined value here causes illegal behavior
5941// :155:30: note: when computing vector element at index '1'
59425925// :155:30: error: use of undefined value here causes illegal behavior
5943// :155:30: note: when computing vector element at index '1'
59445926// :155:30: error: use of undefined value here causes illegal behavior
5945// :155:30: note: when computing vector element at index '1'
59465927// :155:30: error: use of undefined value here causes illegal behavior
5947// :155:30: note: when computing vector element at index '1'
59485928// :155:30: error: use of undefined value here causes illegal behavior
5949// :155:30: note: when computing vector element at index '0'
59505929// :155:30: error: use of undefined value here causes illegal behavior
5951// :155:30: note: when computing vector element at index '0'
59525930// :155:30: error: use of undefined value here causes illegal behavior
5953// :155:30: note: when computing vector element at index '0'
59545931// :155:30: error: use of undefined value here causes illegal behavior
5955// :155:30: note: when computing vector element at index '0'
59565932// :155:30: error: use of undefined value here causes illegal behavior
59575933// :155:30: error: use of undefined value here causes illegal behavior
59585934// :155:30: error: use of undefined value here causes illegal behavior
......@@ -5960,21 +5936,13 @@ const std = @import("std");
59605936// :155:30: error: use of undefined value here causes illegal behavior
59615937// :155:30: error: use of undefined value here causes illegal behavior
59625938// :155:30: error: use of undefined value here causes illegal behavior
5963// :155:30: note: when computing vector element at index '1'
59645939// :155:30: error: use of undefined value here causes illegal behavior
5965// :155:30: note: when computing vector element at index '1'
59665940// :155:30: error: use of undefined value here causes illegal behavior
5967// :155:30: note: when computing vector element at index '1'
59685941// :155:30: error: use of undefined value here causes illegal behavior
5969// :155:30: note: when computing vector element at index '1'
59705942// :155:30: error: use of undefined value here causes illegal behavior
5971// :155:30: note: when computing vector element at index '0'
59725943// :155:30: error: use of undefined value here causes illegal behavior
5973// :155:30: note: when computing vector element at index '0'
59745944// :155:30: error: use of undefined value here causes illegal behavior
5975// :155:30: note: when computing vector element at index '0'
59765945// :155:30: error: use of undefined value here causes illegal behavior
5977// :155:30: note: when computing vector element at index '0'
59785946// :155:30: error: use of undefined value here causes illegal behavior
59795947// :155:30: error: use of undefined value here causes illegal behavior
59805948// :155:30: error: use of undefined value here causes illegal behavior
......@@ -5982,13 +5950,9 @@ const std = @import("std");
59825950// :155:30: error: use of undefined value here causes illegal behavior
59835951// :155:30: error: use of undefined value here causes illegal behavior
59845952// :155:30: error: use of undefined value here causes illegal behavior
5985// :155:30: note: when computing vector element at index '1'
59865953// :155:30: error: use of undefined value here causes illegal behavior
5987// :155:30: note: when computing vector element at index '1'
59885954// :155:30: error: use of undefined value here causes illegal behavior
5989// :155:30: note: when computing vector element at index '1'
59905955// :155:30: error: use of undefined value here causes illegal behavior
5991// :155:30: note: when computing vector element at index '1'
59925956// :155:30: error: use of undefined value here causes illegal behavior
59935957// :155:30: note: when computing vector element at index '0'
59945958// :155:30: error: use of undefined value here causes illegal behavior
......@@ -5998,19 +5962,21 @@ const std = @import("std");
59985962// :155:30: error: use of undefined value here causes illegal behavior
59995963// :155:30: note: when computing vector element at index '0'
60005964// :155:30: error: use of undefined value here causes illegal behavior
5965// :155:30: note: when computing vector element at index '0'
60015966// :155:30: error: use of undefined value here causes illegal behavior
5967// :155:30: note: when computing vector element at index '0'
60025968// :155:30: error: use of undefined value here causes illegal behavior
5969// :155:30: note: when computing vector element at index '0'
60035970// :155:30: error: use of undefined value here causes illegal behavior
5971// :155:30: note: when computing vector element at index '0'
60045972// :155:30: error: use of undefined value here causes illegal behavior
5973// :155:30: note: when computing vector element at index '0'
60055974// :155:30: error: use of undefined value here causes illegal behavior
5975// :155:30: note: when computing vector element at index '0'
60065976// :155:30: error: use of undefined value here causes illegal behavior
6007// :155:30: note: when computing vector element at index '1'
6008// :155:30: error: use of undefined value here causes illegal behavior
6009// :155:30: note: when computing vector element at index '1'
6010// :155:30: error: use of undefined value here causes illegal behavior
6011// :155:30: note: when computing vector element at index '1'
5977// :155:30: note: when computing vector element at index '0'
60125978// :155:30: error: use of undefined value here causes illegal behavior
6013// :155:30: note: when computing vector element at index '1'
5979// :155:30: note: when computing vector element at index '0'
60145980// :155:30: error: use of undefined value here causes illegal behavior
60155981// :155:30: note: when computing vector element at index '0'
60165982// :155:30: error: use of undefined value here causes illegal behavior
......@@ -6020,19 +5986,25 @@ const std = @import("std");
60205986// :155:30: error: use of undefined value here causes illegal behavior
60215987// :155:30: note: when computing vector element at index '0'
60225988// :155:30: error: use of undefined value here causes illegal behavior
5989// :155:30: note: when computing vector element at index '0'
60235990// :155:30: error: use of undefined value here causes illegal behavior
5991// :155:30: note: when computing vector element at index '0'
60245992// :155:30: error: use of undefined value here causes illegal behavior
5993// :155:30: note: when computing vector element at index '0'
60255994// :155:30: error: use of undefined value here causes illegal behavior
5995// :155:30: note: when computing vector element at index '0'
60265996// :155:30: error: use of undefined value here causes illegal behavior
5997// :155:30: note: when computing vector element at index '0'
60275998// :155:30: error: use of undefined value here causes illegal behavior
5999// :155:30: note: when computing vector element at index '0'
60286000// :155:30: error: use of undefined value here causes illegal behavior
6029// :155:30: note: when computing vector element at index '1'
6001// :155:30: note: when computing vector element at index '0'
60306002// :155:30: error: use of undefined value here causes illegal behavior
6031// :155:30: note: when computing vector element at index '1'
6003// :155:30: note: when computing vector element at index '0'
60326004// :155:30: error: use of undefined value here causes illegal behavior
6033// :155:30: note: when computing vector element at index '1'
6005// :155:30: note: when computing vector element at index '0'
60346006// :155:30: error: use of undefined value here causes illegal behavior
6035// :155:30: note: when computing vector element at index '1'
6007// :155:30: note: when computing vector element at index '0'
60366008// :155:30: error: use of undefined value here causes illegal behavior
60376009// :155:30: note: when computing vector element at index '0'
60386010// :155:30: error: use of undefined value here causes illegal behavior
......@@ -6042,19 +6014,25 @@ const std = @import("std");
60426014// :155:30: error: use of undefined value here causes illegal behavior
60436015// :155:30: note: when computing vector element at index '0'
60446016// :155:30: error: use of undefined value here causes illegal behavior
6017// :155:30: note: when computing vector element at index '0'
60456018// :155:30: error: use of undefined value here causes illegal behavior
6019// :155:30: note: when computing vector element at index '0'
60466020// :155:30: error: use of undefined value here causes illegal behavior
6021// :155:30: note: when computing vector element at index '0'
60476022// :155:30: error: use of undefined value here causes illegal behavior
6023// :155:30: note: when computing vector element at index '0'
60486024// :155:30: error: use of undefined value here causes illegal behavior
6025// :155:30: note: when computing vector element at index '0'
60496026// :155:30: error: use of undefined value here causes illegal behavior
6027// :155:30: note: when computing vector element at index '0'
60506028// :155:30: error: use of undefined value here causes illegal behavior
6051// :155:30: note: when computing vector element at index '1'
6029// :155:30: note: when computing vector element at index '0'
60526030// :155:30: error: use of undefined value here causes illegal behavior
6053// :155:30: note: when computing vector element at index '1'
6031// :155:30: note: when computing vector element at index '0'
60546032// :155:30: error: use of undefined value here causes illegal behavior
6055// :155:30: note: when computing vector element at index '1'
6033// :155:30: note: when computing vector element at index '0'
60566034// :155:30: error: use of undefined value here causes illegal behavior
6057// :155:30: note: when computing vector element at index '1'
6035// :155:30: note: when computing vector element at index '0'
60586036// :155:30: error: use of undefined value here causes illegal behavior
60596037// :155:30: note: when computing vector element at index '0'
60606038// :155:30: error: use of undefined value here causes illegal behavior
......@@ -6064,11 +6042,17 @@ const std = @import("std");
60646042// :155:30: error: use of undefined value here causes illegal behavior
60656043// :155:30: note: when computing vector element at index '0'
60666044// :155:30: error: use of undefined value here causes illegal behavior
6045// :155:30: note: when computing vector element at index '1'
60676046// :155:30: error: use of undefined value here causes illegal behavior
6047// :155:30: note: when computing vector element at index '1'
60686048// :155:30: error: use of undefined value here causes illegal behavior
6049// :155:30: note: when computing vector element at index '1'
60696050// :155:30: error: use of undefined value here causes illegal behavior
6051// :155:30: note: when computing vector element at index '1'
60706052// :155:30: error: use of undefined value here causes illegal behavior
6053// :155:30: note: when computing vector element at index '1'
60716054// :155:30: error: use of undefined value here causes illegal behavior
6055// :155:30: note: when computing vector element at index '1'
60726056// :155:30: error: use of undefined value here causes illegal behavior
60736057// :155:30: note: when computing vector element at index '1'
60746058// :155:30: error: use of undefined value here causes illegal behavior
......@@ -6078,19 +6062,25 @@ const std = @import("std");
60786062// :155:30: error: use of undefined value here causes illegal behavior
60796063// :155:30: note: when computing vector element at index '1'
60806064// :155:30: error: use of undefined value here causes illegal behavior
6081// :155:30: note: when computing vector element at index '0'
6065// :155:30: note: when computing vector element at index '1'
60826066// :155:30: error: use of undefined value here causes illegal behavior
6083// :155:30: note: when computing vector element at index '0'
6067// :155:30: note: when computing vector element at index '1'
60846068// :155:30: error: use of undefined value here causes illegal behavior
6085// :155:30: note: when computing vector element at index '0'
6069// :155:30: note: when computing vector element at index '1'
60866070// :155:30: error: use of undefined value here causes illegal behavior
6087// :155:30: note: when computing vector element at index '0'
6071// :155:30: note: when computing vector element at index '1'
60886072// :155:30: error: use of undefined value here causes illegal behavior
6073// :155:30: note: when computing vector element at index '1'
60896074// :155:30: error: use of undefined value here causes illegal behavior
6075// :155:30: note: when computing vector element at index '1'
60906076// :155:30: error: use of undefined value here causes illegal behavior
6077// :155:30: note: when computing vector element at index '1'
60916078// :155:30: error: use of undefined value here causes illegal behavior
6079// :155:30: note: when computing vector element at index '1'
60926080// :155:30: error: use of undefined value here causes illegal behavior
6081// :155:30: note: when computing vector element at index '1'
60936082// :155:30: error: use of undefined value here causes illegal behavior
6083// :155:30: note: when computing vector element at index '1'
60946084// :155:30: error: use of undefined value here causes illegal behavior
60956085// :155:30: note: when computing vector element at index '1'
60966086// :155:30: error: use of undefined value here causes illegal behavior
......@@ -6100,19 +6090,25 @@ const std = @import("std");
61006090// :155:30: error: use of undefined value here causes illegal behavior
61016091// :155:30: note: when computing vector element at index '1'
61026092// :155:30: error: use of undefined value here causes illegal behavior
6103// :155:30: note: when computing vector element at index '0'
6093// :155:30: note: when computing vector element at index '1'
61046094// :155:30: error: use of undefined value here causes illegal behavior
6105// :155:30: note: when computing vector element at index '0'
6095// :155:30: note: when computing vector element at index '1'
61066096// :155:30: error: use of undefined value here causes illegal behavior
6107// :155:30: note: when computing vector element at index '0'
6097// :155:30: note: when computing vector element at index '1'
61086098// :155:30: error: use of undefined value here causes illegal behavior
6109// :155:30: note: when computing vector element at index '0'
6099// :155:30: note: when computing vector element at index '1'
61106100// :155:30: error: use of undefined value here causes illegal behavior
6101// :155:30: note: when computing vector element at index '1'
61116102// :155:30: error: use of undefined value here causes illegal behavior
6103// :155:30: note: when computing vector element at index '1'
61126104// :155:30: error: use of undefined value here causes illegal behavior
6105// :155:30: note: when computing vector element at index '1'
61136106// :155:30: error: use of undefined value here causes illegal behavior
6107// :155:30: note: when computing vector element at index '1'
61146108// :155:30: error: use of undefined value here causes illegal behavior
6109// :155:30: note: when computing vector element at index '1'
61156110// :155:30: error: use of undefined value here causes illegal behavior
6111// :155:30: note: when computing vector element at index '1'
61166112// :155:30: error: use of undefined value here causes illegal behavior
61176113// :155:30: note: when computing vector element at index '1'
61186114// :155:30: error: use of undefined value here causes illegal behavior
......@@ -6122,13 +6118,17 @@ const std = @import("std");
61226118// :155:30: error: use of undefined value here causes illegal behavior
61236119// :155:30: note: when computing vector element at index '1'
61246120// :155:30: error: use of undefined value here causes illegal behavior
6125// :155:30: note: when computing vector element at index '0'
6121// :155:30: note: when computing vector element at index '1'
61266122// :155:30: error: use of undefined value here causes illegal behavior
6127// :155:30: note: when computing vector element at index '0'
6123// :155:30: note: when computing vector element at index '1'
61286124// :155:30: error: use of undefined value here causes illegal behavior
6129// :155:30: note: when computing vector element at index '0'
6125// :155:30: note: when computing vector element at index '1'
61306126// :155:30: error: use of undefined value here causes illegal behavior
6131// :155:30: note: when computing vector element at index '0'
6127// :155:30: note: when computing vector element at index '1'
6128// :155:30: error: use of undefined value here causes illegal behavior
6129// :155:30: note: when computing vector element at index '1'
6130// :155:30: error: use of undefined value here causes illegal behavior
6131// :155:30: note: when computing vector element at index '1'
61326132// :159:30: error: use of undefined value here causes illegal behavior
61336133// :159:30: error: use of undefined value here causes illegal behavior
61346134// :159:30: error: use of undefined value here causes illegal behavior
......@@ -6136,21 +6136,13 @@ const std = @import("std");
61366136// :159:30: error: use of undefined value here causes illegal behavior
61376137// :159:30: error: use of undefined value here causes illegal behavior
61386138// :159:30: error: use of undefined value here causes illegal behavior
6139// :159:30: note: when computing vector element at index '1'
61406139// :159:30: error: use of undefined value here causes illegal behavior
6141// :159:30: note: when computing vector element at index '1'
61426140// :159:30: error: use of undefined value here causes illegal behavior
6143// :159:30: note: when computing vector element at index '1'
61446141// :159:30: error: use of undefined value here causes illegal behavior
6145// :159:30: note: when computing vector element at index '1'
61466142// :159:30: error: use of undefined value here causes illegal behavior
6147// :159:30: note: when computing vector element at index '0'
61486143// :159:30: error: use of undefined value here causes illegal behavior
6149// :159:30: note: when computing vector element at index '0'
61506144// :159:30: error: use of undefined value here causes illegal behavior
6151// :159:30: note: when computing vector element at index '0'
61526145// :159:30: error: use of undefined value here causes illegal behavior
6153// :159:30: note: when computing vector element at index '0'
61546146// :159:30: error: use of undefined value here causes illegal behavior
61556147// :159:30: error: use of undefined value here causes illegal behavior
61566148// :159:30: error: use of undefined value here causes illegal behavior
......@@ -6158,21 +6150,13 @@ const std = @import("std");
61586150// :159:30: error: use of undefined value here causes illegal behavior
61596151// :159:30: error: use of undefined value here causes illegal behavior
61606152// :159:30: error: use of undefined value here causes illegal behavior
6161// :159:30: note: when computing vector element at index '1'
61626153// :159:30: error: use of undefined value here causes illegal behavior
6163// :159:30: note: when computing vector element at index '1'
61646154// :159:30: error: use of undefined value here causes illegal behavior
6165// :159:30: note: when computing vector element at index '1'
61666155// :159:30: error: use of undefined value here causes illegal behavior
6167// :159:30: note: when computing vector element at index '1'
61686156// :159:30: error: use of undefined value here causes illegal behavior
6169// :159:30: note: when computing vector element at index '0'
61706157// :159:30: error: use of undefined value here causes illegal behavior
6171// :159:30: note: when computing vector element at index '0'
61726158// :159:30: error: use of undefined value here causes illegal behavior
6173// :159:30: note: when computing vector element at index '0'
61746159// :159:30: error: use of undefined value here causes illegal behavior
6175// :159:30: note: when computing vector element at index '0'
61766160// :159:30: error: use of undefined value here causes illegal behavior
61776161// :159:30: error: use of undefined value here causes illegal behavior
61786162// :159:30: error: use of undefined value here causes illegal behavior
......@@ -6180,21 +6164,13 @@ const std = @import("std");
61806164// :159:30: error: use of undefined value here causes illegal behavior
61816165// :159:30: error: use of undefined value here causes illegal behavior
61826166// :159:30: error: use of undefined value here causes illegal behavior
6183// :159:30: note: when computing vector element at index '1'
61846167// :159:30: error: use of undefined value here causes illegal behavior
6185// :159:30: note: when computing vector element at index '1'
61866168// :159:30: error: use of undefined value here causes illegal behavior
6187// :159:30: note: when computing vector element at index '1'
61886169// :159:30: error: use of undefined value here causes illegal behavior
6189// :159:30: note: when computing vector element at index '1'
61906170// :159:30: error: use of undefined value here causes illegal behavior
6191// :159:30: note: when computing vector element at index '0'
61926171// :159:30: error: use of undefined value here causes illegal behavior
6193// :159:30: note: when computing vector element at index '0'
61946172// :159:30: error: use of undefined value here causes illegal behavior
6195// :159:30: note: when computing vector element at index '0'
61966173// :159:30: error: use of undefined value here causes illegal behavior
6197// :159:30: note: when computing vector element at index '0'
61986174// :159:30: error: use of undefined value here causes illegal behavior
61996175// :159:30: error: use of undefined value here causes illegal behavior
62006176// :159:30: error: use of undefined value here causes illegal behavior
......@@ -6202,21 +6178,13 @@ const std = @import("std");
62026178// :159:30: error: use of undefined value here causes illegal behavior
62036179// :159:30: error: use of undefined value here causes illegal behavior
62046180// :159:30: error: use of undefined value here causes illegal behavior
6205// :159:30: note: when computing vector element at index '1'
62066181// :159:30: error: use of undefined value here causes illegal behavior
6207// :159:30: note: when computing vector element at index '1'
62086182// :159:30: error: use of undefined value here causes illegal behavior
6209// :159:30: note: when computing vector element at index '1'
62106183// :159:30: error: use of undefined value here causes illegal behavior
6211// :159:30: note: when computing vector element at index '1'
62126184// :159:30: error: use of undefined value here causes illegal behavior
6213// :159:30: note: when computing vector element at index '0'
62146185// :159:30: error: use of undefined value here causes illegal behavior
6215// :159:30: note: when computing vector element at index '0'
62166186// :159:30: error: use of undefined value here causes illegal behavior
6217// :159:30: note: when computing vector element at index '0'
62186187// :159:30: error: use of undefined value here causes illegal behavior
6219// :159:30: note: when computing vector element at index '0'
62206188// :159:30: error: use of undefined value here causes illegal behavior
62216189// :159:30: error: use of undefined value here causes illegal behavior
62226190// :159:30: error: use of undefined value here causes illegal behavior
......@@ -6224,13 +6192,9 @@ const std = @import("std");
62246192// :159:30: error: use of undefined value here causes illegal behavior
62256193// :159:30: error: use of undefined value here causes illegal behavior
62266194// :159:30: error: use of undefined value here causes illegal behavior
6227// :159:30: note: when computing vector element at index '1'
62286195// :159:30: error: use of undefined value here causes illegal behavior
6229// :159:30: note: when computing vector element at index '1'
62306196// :159:30: error: use of undefined value here causes illegal behavior
6231// :159:30: note: when computing vector element at index '1'
62326197// :159:30: error: use of undefined value here causes illegal behavior
6233// :159:30: note: when computing vector element at index '1'
62346198// :159:30: error: use of undefined value here causes illegal behavior
62356199// :159:30: note: when computing vector element at index '0'
62366200// :159:30: error: use of undefined value here causes illegal behavior
......@@ -6240,19 +6204,21 @@ const std = @import("std");
62406204// :159:30: error: use of undefined value here causes illegal behavior
62416205// :159:30: note: when computing vector element at index '0'
62426206// :159:30: error: use of undefined value here causes illegal behavior
6207// :159:30: note: when computing vector element at index '0'
62436208// :159:30: error: use of undefined value here causes illegal behavior
6209// :159:30: note: when computing vector element at index '0'
62446210// :159:30: error: use of undefined value here causes illegal behavior
6211// :159:30: note: when computing vector element at index '0'
62456212// :159:30: error: use of undefined value here causes illegal behavior
6213// :159:30: note: when computing vector element at index '0'
62466214// :159:30: error: use of undefined value here causes illegal behavior
6215// :159:30: note: when computing vector element at index '0'
62476216// :159:30: error: use of undefined value here causes illegal behavior
6217// :159:30: note: when computing vector element at index '0'
62486218// :159:30: error: use of undefined value here causes illegal behavior
6249// :159:30: note: when computing vector element at index '1'
6250// :159:30: error: use of undefined value here causes illegal behavior
6251// :159:30: note: when computing vector element at index '1'
6252// :159:30: error: use of undefined value here causes illegal behavior
6253// :159:30: note: when computing vector element at index '1'
6219// :159:30: note: when computing vector element at index '0'
62546220// :159:30: error: use of undefined value here causes illegal behavior
6255// :159:30: note: when computing vector element at index '1'
6221// :159:30: note: when computing vector element at index '0'
62566222// :159:30: error: use of undefined value here causes illegal behavior
62576223// :159:30: note: when computing vector element at index '0'
62586224// :159:30: error: use of undefined value here causes illegal behavior
......@@ -6262,19 +6228,25 @@ const std = @import("std");
62626228// :159:30: error: use of undefined value here causes illegal behavior
62636229// :159:30: note: when computing vector element at index '0'
62646230// :159:30: error: use of undefined value here causes illegal behavior
6231// :159:30: note: when computing vector element at index '0'
62656232// :159:30: error: use of undefined value here causes illegal behavior
6233// :159:30: note: when computing vector element at index '0'
62666234// :159:30: error: use of undefined value here causes illegal behavior
6235// :159:30: note: when computing vector element at index '0'
62676236// :159:30: error: use of undefined value here causes illegal behavior
6237// :159:30: note: when computing vector element at index '0'
62686238// :159:30: error: use of undefined value here causes illegal behavior
6239// :159:30: note: when computing vector element at index '0'
62696240// :159:30: error: use of undefined value here causes illegal behavior
6241// :159:30: note: when computing vector element at index '0'
62706242// :159:30: error: use of undefined value here causes illegal behavior
6271// :159:30: note: when computing vector element at index '1'
6243// :159:30: note: when computing vector element at index '0'
62726244// :159:30: error: use of undefined value here causes illegal behavior
6273// :159:30: note: when computing vector element at index '1'
6245// :159:30: note: when computing vector element at index '0'
62746246// :159:30: error: use of undefined value here causes illegal behavior
6275// :159:30: note: when computing vector element at index '1'
6247// :159:30: note: when computing vector element at index '0'
62766248// :159:30: error: use of undefined value here causes illegal behavior
6277// :159:30: note: when computing vector element at index '1'
6249// :159:30: note: when computing vector element at index '0'
62786250// :159:30: error: use of undefined value here causes illegal behavior
62796251// :159:30: note: when computing vector element at index '0'
62806252// :159:30: error: use of undefined value here causes illegal behavior
......@@ -6284,19 +6256,25 @@ const std = @import("std");
62846256// :159:30: error: use of undefined value here causes illegal behavior
62856257// :159:30: note: when computing vector element at index '0'
62866258// :159:30: error: use of undefined value here causes illegal behavior
6259// :159:30: note: when computing vector element at index '0'
62876260// :159:30: error: use of undefined value here causes illegal behavior
6261// :159:30: note: when computing vector element at index '0'
62886262// :159:30: error: use of undefined value here causes illegal behavior
6263// :159:30: note: when computing vector element at index '0'
62896264// :159:30: error: use of undefined value here causes illegal behavior
6265// :159:30: note: when computing vector element at index '0'
62906266// :159:30: error: use of undefined value here causes illegal behavior
6267// :159:30: note: when computing vector element at index '0'
62916268// :159:30: error: use of undefined value here causes illegal behavior
6269// :159:30: note: when computing vector element at index '0'
62926270// :159:30: error: use of undefined value here causes illegal behavior
6293// :159:30: note: when computing vector element at index '1'
6271// :159:30: note: when computing vector element at index '0'
62946272// :159:30: error: use of undefined value here causes illegal behavior
6295// :159:30: note: when computing vector element at index '1'
6273// :159:30: note: when computing vector element at index '0'
62966274// :159:30: error: use of undefined value here causes illegal behavior
6297// :159:30: note: when computing vector element at index '1'
6275// :159:30: note: when computing vector element at index '0'
62986276// :159:30: error: use of undefined value here causes illegal behavior
6299// :159:30: note: when computing vector element at index '1'
6277// :159:30: note: when computing vector element at index '0'
63006278// :159:30: error: use of undefined value here causes illegal behavior
63016279// :159:30: note: when computing vector element at index '0'
63026280// :159:30: error: use of undefined value here causes illegal behavior
......@@ -6306,11 +6284,17 @@ const std = @import("std");
63066284// :159:30: error: use of undefined value here causes illegal behavior
63076285// :159:30: note: when computing vector element at index '0'
63086286// :159:30: error: use of undefined value here causes illegal behavior
6287// :159:30: note: when computing vector element at index '1'
63096288// :159:30: error: use of undefined value here causes illegal behavior
6289// :159:30: note: when computing vector element at index '1'
63106290// :159:30: error: use of undefined value here causes illegal behavior
6291// :159:30: note: when computing vector element at index '1'
63116292// :159:30: error: use of undefined value here causes illegal behavior
6293// :159:30: note: when computing vector element at index '1'
63126294// :159:30: error: use of undefined value here causes illegal behavior
6295// :159:30: note: when computing vector element at index '1'
63136296// :159:30: error: use of undefined value here causes illegal behavior
6297// :159:30: note: when computing vector element at index '1'
63146298// :159:30: error: use of undefined value here causes illegal behavior
63156299// :159:30: note: when computing vector element at index '1'
63166300// :159:30: error: use of undefined value here causes illegal behavior
......@@ -6320,19 +6304,25 @@ const std = @import("std");
63206304// :159:30: error: use of undefined value here causes illegal behavior
63216305// :159:30: note: when computing vector element at index '1'
63226306// :159:30: error: use of undefined value here causes illegal behavior
6323// :159:30: note: when computing vector element at index '0'
6307// :159:30: note: when computing vector element at index '1'
63246308// :159:30: error: use of undefined value here causes illegal behavior
6325// :159:30: note: when computing vector element at index '0'
6309// :159:30: note: when computing vector element at index '1'
63266310// :159:30: error: use of undefined value here causes illegal behavior
6327// :159:30: note: when computing vector element at index '0'
6311// :159:30: note: when computing vector element at index '1'
63286312// :159:30: error: use of undefined value here causes illegal behavior
6329// :159:30: note: when computing vector element at index '0'
6313// :159:30: note: when computing vector element at index '1'
63306314// :159:30: error: use of undefined value here causes illegal behavior
6315// :159:30: note: when computing vector element at index '1'
63316316// :159:30: error: use of undefined value here causes illegal behavior
6317// :159:30: note: when computing vector element at index '1'
63326318// :159:30: error: use of undefined value here causes illegal behavior
6319// :159:30: note: when computing vector element at index '1'
63336320// :159:30: error: use of undefined value here causes illegal behavior
6321// :159:30: note: when computing vector element at index '1'
63346322// :159:30: error: use of undefined value here causes illegal behavior
6323// :159:30: note: when computing vector element at index '1'
63356324// :159:30: error: use of undefined value here causes illegal behavior
6325// :159:30: note: when computing vector element at index '1'
63366326// :159:30: error: use of undefined value here causes illegal behavior
63376327// :159:30: note: when computing vector element at index '1'
63386328// :159:30: error: use of undefined value here causes illegal behavior
......@@ -6342,19 +6332,27 @@ const std = @import("std");
63426332// :159:30: error: use of undefined value here causes illegal behavior
63436333// :159:30: note: when computing vector element at index '1'
63446334// :159:30: error: use of undefined value here causes illegal behavior
6345// :159:30: note: when computing vector element at index '0'
6335// :159:30: note: when computing vector element at index '1'
63466336// :159:30: error: use of undefined value here causes illegal behavior
6347// :159:30: note: when computing vector element at index '0'
6337// :159:30: note: when computing vector element at index '1'
63486338// :159:30: error: use of undefined value here causes illegal behavior
6349// :159:30: note: when computing vector element at index '0'
6339// :159:30: note: when computing vector element at index '1'
63506340// :159:30: error: use of undefined value here causes illegal behavior
6351// :159:30: note: when computing vector element at index '0'
6341// :159:30: note: when computing vector element at index '1'
6342// :159:30: error: use of undefined value here causes illegal behavior
6343// :159:30: note: when computing vector element at index '1'
63526344// :159:30: error: use of undefined value here causes illegal behavior
6345// :159:30: note: when computing vector element at index '1'
63536346// :159:30: error: use of undefined value here causes illegal behavior
6347// :159:30: note: when computing vector element at index '1'
63546348// :159:30: error: use of undefined value here causes illegal behavior
6349// :159:30: note: when computing vector element at index '1'
63556350// :159:30: error: use of undefined value here causes illegal behavior
6351// :159:30: note: when computing vector element at index '1'
63566352// :159:30: error: use of undefined value here causes illegal behavior
6353// :159:30: note: when computing vector element at index '1'
63576354// :159:30: error: use of undefined value here causes illegal behavior
6355// :159:30: note: when computing vector element at index '1'
63586356// :159:30: error: use of undefined value here causes illegal behavior
63596357// :159:30: note: when computing vector element at index '1'
63606358// :159:30: error: use of undefined value here causes illegal behavior
......@@ -6364,13 +6362,15 @@ const std = @import("std");
63646362// :159:30: error: use of undefined value here causes illegal behavior
63656363// :159:30: note: when computing vector element at index '1'
63666364// :159:30: error: use of undefined value here causes illegal behavior
6367// :159:30: note: when computing vector element at index '0'
6365// :159:30: note: when computing vector element at index '1'
63686366// :159:30: error: use of undefined value here causes illegal behavior
6369// :159:30: note: when computing vector element at index '0'
6367// :159:30: note: when computing vector element at index '1'
63706368// :159:30: error: use of undefined value here causes illegal behavior
6371// :159:30: note: when computing vector element at index '0'
6369// :159:30: note: when computing vector element at index '1'
63726370// :159:30: error: use of undefined value here causes illegal behavior
6373// :159:30: note: when computing vector element at index '0'
6371// :159:30: note: when computing vector element at index '1'
6372// :159:30: error: use of undefined value here causes illegal behavior
6373// :159:30: note: when computing vector element at index '1'
63746374// :163:30: error: use of undefined value here causes illegal behavior
63756375// :163:30: error: use of undefined value here causes illegal behavior
63766376// :163:30: error: use of undefined value here causes illegal behavior
......@@ -6378,21 +6378,13 @@ const std = @import("std");
63786378// :163:30: error: use of undefined value here causes illegal behavior
63796379// :163:30: error: use of undefined value here causes illegal behavior
63806380// :163:30: error: use of undefined value here causes illegal behavior
6381// :163:30: note: when computing vector element at index '1'
63826381// :163:30: error: use of undefined value here causes illegal behavior
6383// :163:30: note: when computing vector element at index '1'
63846382// :163:30: error: use of undefined value here causes illegal behavior
6385// :163:30: note: when computing vector element at index '1'
63866383// :163:30: error: use of undefined value here causes illegal behavior
6387// :163:30: note: when computing vector element at index '1'
63886384// :163:30: error: use of undefined value here causes illegal behavior
6389// :163:30: note: when computing vector element at index '0'
63906385// :163:30: error: use of undefined value here causes illegal behavior
6391// :163:30: note: when computing vector element at index '0'
63926386// :163:30: error: use of undefined value here causes illegal behavior
6393// :163:30: note: when computing vector element at index '0'
63946387// :163:30: error: use of undefined value here causes illegal behavior
6395// :163:30: note: when computing vector element at index '0'
63966388// :163:30: error: use of undefined value here causes illegal behavior
63976389// :163:30: error: use of undefined value here causes illegal behavior
63986390// :163:30: error: use of undefined value here causes illegal behavior
......@@ -6400,21 +6392,13 @@ const std = @import("std");
64006392// :163:30: error: use of undefined value here causes illegal behavior
64016393// :163:30: error: use of undefined value here causes illegal behavior
64026394// :163:30: error: use of undefined value here causes illegal behavior
6403// :163:30: note: when computing vector element at index '1'
64046395// :163:30: error: use of undefined value here causes illegal behavior
6405// :163:30: note: when computing vector element at index '1'
64066396// :163:30: error: use of undefined value here causes illegal behavior
6407// :163:30: note: when computing vector element at index '1'
64086397// :163:30: error: use of undefined value here causes illegal behavior
6409// :163:30: note: when computing vector element at index '1'
64106398// :163:30: error: use of undefined value here causes illegal behavior
6411// :163:30: note: when computing vector element at index '0'
64126399// :163:30: error: use of undefined value here causes illegal behavior
6413// :163:30: note: when computing vector element at index '0'
64146400// :163:30: error: use of undefined value here causes illegal behavior
6415// :163:30: note: when computing vector element at index '0'
64166401// :163:30: error: use of undefined value here causes illegal behavior
6417// :163:30: note: when computing vector element at index '0'
64186402// :163:30: error: use of undefined value here causes illegal behavior
64196403// :163:30: error: use of undefined value here causes illegal behavior
64206404// :163:30: error: use of undefined value here causes illegal behavior
......@@ -6422,21 +6406,13 @@ const std = @import("std");
64226406// :163:30: error: use of undefined value here causes illegal behavior
64236407// :163:30: error: use of undefined value here causes illegal behavior
64246408// :163:30: error: use of undefined value here causes illegal behavior
6425// :163:30: note: when computing vector element at index '1'
64266409// :163:30: error: use of undefined value here causes illegal behavior
6427// :163:30: note: when computing vector element at index '1'
64286410// :163:30: error: use of undefined value here causes illegal behavior
6429// :163:30: note: when computing vector element at index '1'
64306411// :163:30: error: use of undefined value here causes illegal behavior
6431// :163:30: note: when computing vector element at index '1'
64326412// :163:30: error: use of undefined value here causes illegal behavior
6433// :163:30: note: when computing vector element at index '0'
64346413// :163:30: error: use of undefined value here causes illegal behavior
6435// :163:30: note: when computing vector element at index '0'
64366414// :163:30: error: use of undefined value here causes illegal behavior
6437// :163:30: note: when computing vector element at index '0'
64386415// :163:30: error: use of undefined value here causes illegal behavior
6439// :163:30: note: when computing vector element at index '0'
64406416// :163:30: error: use of undefined value here causes illegal behavior
64416417// :163:30: error: use of undefined value here causes illegal behavior
64426418// :163:30: error: use of undefined value here causes illegal behavior
......@@ -6444,21 +6420,13 @@ const std = @import("std");
64446420// :163:30: error: use of undefined value here causes illegal behavior
64456421// :163:30: error: use of undefined value here causes illegal behavior
64466422// :163:30: error: use of undefined value here causes illegal behavior
6447// :163:30: note: when computing vector element at index '1'
64486423// :163:30: error: use of undefined value here causes illegal behavior
6449// :163:30: note: when computing vector element at index '1'
64506424// :163:30: error: use of undefined value here causes illegal behavior
6451// :163:30: note: when computing vector element at index '1'
64526425// :163:30: error: use of undefined value here causes illegal behavior
6453// :163:30: note: when computing vector element at index '1'
64546426// :163:30: error: use of undefined value here causes illegal behavior
6455// :163:30: note: when computing vector element at index '0'
64566427// :163:30: error: use of undefined value here causes illegal behavior
6457// :163:30: note: when computing vector element at index '0'
64586428// :163:30: error: use of undefined value here causes illegal behavior
6459// :163:30: note: when computing vector element at index '0'
64606429// :163:30: error: use of undefined value here causes illegal behavior
6461// :163:30: note: when computing vector element at index '0'
64626430// :163:30: error: use of undefined value here causes illegal behavior
64636431// :163:30: error: use of undefined value here causes illegal behavior
64646432// :163:30: error: use of undefined value here causes illegal behavior
......@@ -6466,13 +6434,9 @@ const std = @import("std");
64666434// :163:30: error: use of undefined value here causes illegal behavior
64676435// :163:30: error: use of undefined value here causes illegal behavior
64686436// :163:30: error: use of undefined value here causes illegal behavior
6469// :163:30: note: when computing vector element at index '1'
64706437// :163:30: error: use of undefined value here causes illegal behavior
6471// :163:30: note: when computing vector element at index '1'
64726438// :163:30: error: use of undefined value here causes illegal behavior
6473// :163:30: note: when computing vector element at index '1'
64746439// :163:30: error: use of undefined value here causes illegal behavior
6475// :163:30: note: when computing vector element at index '1'
64766440// :163:30: error: use of undefined value here causes illegal behavior
64776441// :163:30: note: when computing vector element at index '0'
64786442// :163:30: error: use of undefined value here causes illegal behavior
......@@ -6482,19 +6446,21 @@ const std = @import("std");
64826446// :163:30: error: use of undefined value here causes illegal behavior
64836447// :163:30: note: when computing vector element at index '0'
64846448// :163:30: error: use of undefined value here causes illegal behavior
6449// :163:30: note: when computing vector element at index '0'
64856450// :163:30: error: use of undefined value here causes illegal behavior
6451// :163:30: note: when computing vector element at index '0'
64866452// :163:30: error: use of undefined value here causes illegal behavior
6453// :163:30: note: when computing vector element at index '0'
64876454// :163:30: error: use of undefined value here causes illegal behavior
6455// :163:30: note: when computing vector element at index '0'
64886456// :163:30: error: use of undefined value here causes illegal behavior
6457// :163:30: note: when computing vector element at index '0'
64896458// :163:30: error: use of undefined value here causes illegal behavior
6459// :163:30: note: when computing vector element at index '0'
64906460// :163:30: error: use of undefined value here causes illegal behavior
6491// :163:30: note: when computing vector element at index '1'
6492// :163:30: error: use of undefined value here causes illegal behavior
6493// :163:30: note: when computing vector element at index '1'
6494// :163:30: error: use of undefined value here causes illegal behavior
6495// :163:30: note: when computing vector element at index '1'
6461// :163:30: note: when computing vector element at index '0'
64966462// :163:30: error: use of undefined value here causes illegal behavior
6497// :163:30: note: when computing vector element at index '1'
6463// :163:30: note: when computing vector element at index '0'
64986464// :163:30: error: use of undefined value here causes illegal behavior
64996465// :163:30: note: when computing vector element at index '0'
65006466// :163:30: error: use of undefined value here causes illegal behavior
......@@ -6504,19 +6470,25 @@ const std = @import("std");
65046470// :163:30: error: use of undefined value here causes illegal behavior
65056471// :163:30: note: when computing vector element at index '0'
65066472// :163:30: error: use of undefined value here causes illegal behavior
6473// :163:30: note: when computing vector element at index '0'
65076474// :163:30: error: use of undefined value here causes illegal behavior
6475// :163:30: note: when computing vector element at index '0'
65086476// :163:30: error: use of undefined value here causes illegal behavior
6477// :163:30: note: when computing vector element at index '0'
65096478// :163:30: error: use of undefined value here causes illegal behavior
6479// :163:30: note: when computing vector element at index '0'
65106480// :163:30: error: use of undefined value here causes illegal behavior
6481// :163:30: note: when computing vector element at index '0'
65116482// :163:30: error: use of undefined value here causes illegal behavior
6483// :163:30: note: when computing vector element at index '0'
65126484// :163:30: error: use of undefined value here causes illegal behavior
6513// :163:30: note: when computing vector element at index '1'
6485// :163:30: note: when computing vector element at index '0'
65146486// :163:30: error: use of undefined value here causes illegal behavior
6515// :163:30: note: when computing vector element at index '1'
6487// :163:30: note: when computing vector element at index '0'
65166488// :163:30: error: use of undefined value here causes illegal behavior
6517// :163:30: note: when computing vector element at index '1'
6489// :163:30: note: when computing vector element at index '0'
65186490// :163:30: error: use of undefined value here causes illegal behavior
6519// :163:30: note: when computing vector element at index '1'
6491// :163:30: note: when computing vector element at index '0'
65206492// :163:30: error: use of undefined value here causes illegal behavior
65216493// :163:30: note: when computing vector element at index '0'
65226494// :163:30: error: use of undefined value here causes illegal behavior
......@@ -6526,19 +6498,25 @@ const std = @import("std");
65266498// :163:30: error: use of undefined value here causes illegal behavior
65276499// :163:30: note: when computing vector element at index '0'
65286500// :163:30: error: use of undefined value here causes illegal behavior
6501// :163:30: note: when computing vector element at index '0'
65296502// :163:30: error: use of undefined value here causes illegal behavior
6503// :163:30: note: when computing vector element at index '0'
65306504// :163:30: error: use of undefined value here causes illegal behavior
6505// :163:30: note: when computing vector element at index '0'
65316506// :163:30: error: use of undefined value here causes illegal behavior
6507// :163:30: note: when computing vector element at index '0'
65326508// :163:30: error: use of undefined value here causes illegal behavior
6509// :163:30: note: when computing vector element at index '0'
65336510// :163:30: error: use of undefined value here causes illegal behavior
6511// :163:30: note: when computing vector element at index '0'
65346512// :163:30: error: use of undefined value here causes illegal behavior
6535// :163:30: note: when computing vector element at index '1'
6513// :163:30: note: when computing vector element at index '0'
65366514// :163:30: error: use of undefined value here causes illegal behavior
6537// :163:30: note: when computing vector element at index '1'
6515// :163:30: note: when computing vector element at index '0'
65386516// :163:30: error: use of undefined value here causes illegal behavior
6539// :163:30: note: when computing vector element at index '1'
6517// :163:30: note: when computing vector element at index '0'
65406518// :163:30: error: use of undefined value here causes illegal behavior
6541// :163:30: note: when computing vector element at index '1'
6519// :163:30: note: when computing vector element at index '0'
65426520// :163:30: error: use of undefined value here causes illegal behavior
65436521// :163:30: note: when computing vector element at index '0'
65446522// :163:30: error: use of undefined value here causes illegal behavior
......@@ -6548,11 +6526,19 @@ const std = @import("std");
65486526// :163:30: error: use of undefined value here causes illegal behavior
65496527// :163:30: note: when computing vector element at index '0'
65506528// :163:30: error: use of undefined value here causes illegal behavior
6529// :163:30: note: when computing vector element at index '1'
6530// :163:30: error: use of undefined value here causes illegal behavior
6531// :163:30: note: when computing vector element at index '1'
65516532// :163:30: error: use of undefined value here causes illegal behavior
6533// :163:30: note: when computing vector element at index '1'
65526534// :163:30: error: use of undefined value here causes illegal behavior
6535// :163:30: note: when computing vector element at index '1'
65536536// :163:30: error: use of undefined value here causes illegal behavior
6537// :163:30: note: when computing vector element at index '1'
65546538// :163:30: error: use of undefined value here causes illegal behavior
6539// :163:30: note: when computing vector element at index '1'
65556540// :163:30: error: use of undefined value here causes illegal behavior
6541// :163:30: note: when computing vector element at index '1'
65566542// :163:30: error: use of undefined value here causes illegal behavior
65576543// :163:30: note: when computing vector element at index '1'
65586544// :163:30: error: use of undefined value here causes illegal behavior
......@@ -6562,19 +6548,27 @@ const std = @import("std");
65626548// :163:30: error: use of undefined value here causes illegal behavior
65636549// :163:30: note: when computing vector element at index '1'
65646550// :163:30: error: use of undefined value here causes illegal behavior
6565// :163:30: note: when computing vector element at index '0'
6551// :163:30: note: when computing vector element at index '1'
65666552// :163:30: error: use of undefined value here causes illegal behavior
6567// :163:30: note: when computing vector element at index '0'
6553// :163:30: note: when computing vector element at index '1'
65686554// :163:30: error: use of undefined value here causes illegal behavior
6569// :163:30: note: when computing vector element at index '0'
6555// :163:30: note: when computing vector element at index '1'
65706556// :163:30: error: use of undefined value here causes illegal behavior
6571// :163:30: note: when computing vector element at index '0'
6557// :163:30: note: when computing vector element at index '1'
6558// :163:30: error: use of undefined value here causes illegal behavior
6559// :163:30: note: when computing vector element at index '1'
65726560// :163:30: error: use of undefined value here causes illegal behavior
6561// :163:30: note: when computing vector element at index '1'
65736562// :163:30: error: use of undefined value here causes illegal behavior
6563// :163:30: note: when computing vector element at index '1'
65746564// :163:30: error: use of undefined value here causes illegal behavior
6565// :163:30: note: when computing vector element at index '1'
65756566// :163:30: error: use of undefined value here causes illegal behavior
6567// :163:30: note: when computing vector element at index '1'
65766568// :163:30: error: use of undefined value here causes illegal behavior
6569// :163:30: note: when computing vector element at index '1'
65776570// :163:30: error: use of undefined value here causes illegal behavior
6571// :163:30: note: when computing vector element at index '1'
65786572// :163:30: error: use of undefined value here causes illegal behavior
65796573// :163:30: note: when computing vector element at index '1'
65806574// :163:30: error: use of undefined value here causes illegal behavior
......@@ -6584,19 +6578,25 @@ const std = @import("std");
65846578// :163:30: error: use of undefined value here causes illegal behavior
65856579// :163:30: note: when computing vector element at index '1'
65866580// :163:30: error: use of undefined value here causes illegal behavior
6587// :163:30: note: when computing vector element at index '0'
6581// :163:30: note: when computing vector element at index '1'
65886582// :163:30: error: use of undefined value here causes illegal behavior
6589// :163:30: note: when computing vector element at index '0'
6583// :163:30: note: when computing vector element at index '1'
65906584// :163:30: error: use of undefined value here causes illegal behavior
6591// :163:30: note: when computing vector element at index '0'
6585// :163:30: note: when computing vector element at index '1'
65926586// :163:30: error: use of undefined value here causes illegal behavior
6593// :163:30: note: when computing vector element at index '0'
6587// :163:30: note: when computing vector element at index '1'
65946588// :163:30: error: use of undefined value here causes illegal behavior
6589// :163:30: note: when computing vector element at index '1'
65956590// :163:30: error: use of undefined value here causes illegal behavior
6591// :163:30: note: when computing vector element at index '1'
65966592// :163:30: error: use of undefined value here causes illegal behavior
6593// :163:30: note: when computing vector element at index '1'
65976594// :163:30: error: use of undefined value here causes illegal behavior
6595// :163:30: note: when computing vector element at index '1'
65986596// :163:30: error: use of undefined value here causes illegal behavior
6597// :163:30: note: when computing vector element at index '1'
65996598// :163:30: error: use of undefined value here causes illegal behavior
6599// :163:30: note: when computing vector element at index '1'
66006600// :163:30: error: use of undefined value here causes illegal behavior
66016601// :163:30: note: when computing vector element at index '1'
66026602// :163:30: error: use of undefined value here causes illegal behavior
......@@ -6606,13 +6606,13 @@ const std = @import("std");
66066606// :163:30: error: use of undefined value here causes illegal behavior
66076607// :163:30: note: when computing vector element at index '1'
66086608// :163:30: error: use of undefined value here causes illegal behavior
6609// :163:30: note: when computing vector element at index '0'
6609// :163:30: note: when computing vector element at index '1'
66106610// :163:30: error: use of undefined value here causes illegal behavior
6611// :163:30: note: when computing vector element at index '0'
6611// :163:30: note: when computing vector element at index '1'
66126612// :163:30: error: use of undefined value here causes illegal behavior
6613// :163:30: note: when computing vector element at index '0'
6613// :163:30: note: when computing vector element at index '1'
66146614// :163:30: error: use of undefined value here causes illegal behavior
6615// :163:30: note: when computing vector element at index '0'
6615// :163:30: note: when computing vector element at index '1'
66166616// :167:25: error: use of undefined value here causes illegal behavior
66176617// :167:25: error: use of undefined value here causes illegal behavior
66186618// :167:25: error: use of undefined value here causes illegal behavior
......@@ -6620,21 +6620,13 @@ const std = @import("std");
66206620// :167:25: error: use of undefined value here causes illegal behavior
66216621// :167:25: error: use of undefined value here causes illegal behavior
66226622// :167:25: error: use of undefined value here causes illegal behavior
6623// :167:25: note: when computing vector element at index '1'
66246623// :167:25: error: use of undefined value here causes illegal behavior
6625// :167:25: note: when computing vector element at index '1'
66266624// :167:25: error: use of undefined value here causes illegal behavior
6627// :167:25: note: when computing vector element at index '1'
66286625// :167:25: error: use of undefined value here causes illegal behavior
6629// :167:25: note: when computing vector element at index '1'
66306626// :167:25: error: use of undefined value here causes illegal behavior
6631// :167:25: note: when computing vector element at index '0'
66326627// :167:25: error: use of undefined value here causes illegal behavior
6633// :167:25: note: when computing vector element at index '0'
66346628// :167:25: error: use of undefined value here causes illegal behavior
6635// :167:25: note: when computing vector element at index '0'
66366629// :167:25: error: use of undefined value here causes illegal behavior
6637// :167:25: note: when computing vector element at index '0'
66386630// :167:25: error: use of undefined value here causes illegal behavior
66396631// :167:25: error: use of undefined value here causes illegal behavior
66406632// :167:25: error: use of undefined value here causes illegal behavior
......@@ -6642,21 +6634,13 @@ const std = @import("std");
66426634// :167:25: error: use of undefined value here causes illegal behavior
66436635// :167:25: error: use of undefined value here causes illegal behavior
66446636// :167:25: error: use of undefined value here causes illegal behavior
6645// :167:25: note: when computing vector element at index '1'
66466637// :167:25: error: use of undefined value here causes illegal behavior
6647// :167:25: note: when computing vector element at index '1'
66486638// :167:25: error: use of undefined value here causes illegal behavior
6649// :167:25: note: when computing vector element at index '1'
66506639// :167:25: error: use of undefined value here causes illegal behavior
6651// :167:25: note: when computing vector element at index '1'
66526640// :167:25: error: use of undefined value here causes illegal behavior
6653// :167:25: note: when computing vector element at index '0'
66546641// :167:25: error: use of undefined value here causes illegal behavior
6655// :167:25: note: when computing vector element at index '0'
66566642// :167:25: error: use of undefined value here causes illegal behavior
6657// :167:25: note: when computing vector element at index '0'
66586643// :167:25: error: use of undefined value here causes illegal behavior
6659// :167:25: note: when computing vector element at index '0'
66606644// :167:25: error: use of undefined value here causes illegal behavior
66616645// :167:25: error: use of undefined value here causes illegal behavior
66626646// :167:25: error: use of undefined value here causes illegal behavior
......@@ -6664,21 +6648,13 @@ const std = @import("std");
66646648// :167:25: error: use of undefined value here causes illegal behavior
66656649// :167:25: error: use of undefined value here causes illegal behavior
66666650// :167:25: error: use of undefined value here causes illegal behavior
6667// :167:25: note: when computing vector element at index '1'
66686651// :167:25: error: use of undefined value here causes illegal behavior
6669// :167:25: note: when computing vector element at index '1'
66706652// :167:25: error: use of undefined value here causes illegal behavior
6671// :167:25: note: when computing vector element at index '1'
66726653// :167:25: error: use of undefined value here causes illegal behavior
6673// :167:25: note: when computing vector element at index '1'
66746654// :167:25: error: use of undefined value here causes illegal behavior
6675// :167:25: note: when computing vector element at index '0'
66766655// :167:25: error: use of undefined value here causes illegal behavior
6677// :167:25: note: when computing vector element at index '0'
66786656// :167:25: error: use of undefined value here causes illegal behavior
6679// :167:25: note: when computing vector element at index '0'
66806657// :167:25: error: use of undefined value here causes illegal behavior
6681// :167:25: note: when computing vector element at index '0'
66826658// :167:25: error: use of undefined value here causes illegal behavior
66836659// :167:25: error: use of undefined value here causes illegal behavior
66846660// :167:25: error: use of undefined value here causes illegal behavior
......@@ -6686,21 +6662,13 @@ const std = @import("std");
66866662// :167:25: error: use of undefined value here causes illegal behavior
66876663// :167:25: error: use of undefined value here causes illegal behavior
66886664// :167:25: error: use of undefined value here causes illegal behavior
6689// :167:25: note: when computing vector element at index '1'
66906665// :167:25: error: use of undefined value here causes illegal behavior
6691// :167:25: note: when computing vector element at index '1'
66926666// :167:25: error: use of undefined value here causes illegal behavior
6693// :167:25: note: when computing vector element at index '1'
66946667// :167:25: error: use of undefined value here causes illegal behavior
6695// :167:25: note: when computing vector element at index '1'
66966668// :167:25: error: use of undefined value here causes illegal behavior
6697// :167:25: note: when computing vector element at index '0'
66986669// :167:25: error: use of undefined value here causes illegal behavior
6699// :167:25: note: when computing vector element at index '0'
67006670// :167:25: error: use of undefined value here causes illegal behavior
6701// :167:25: note: when computing vector element at index '0'
67026671// :167:25: error: use of undefined value here causes illegal behavior
6703// :167:25: note: when computing vector element at index '0'
67046672// :167:25: error: use of undefined value here causes illegal behavior
67056673// :167:25: error: use of undefined value here causes illegal behavior
67066674// :167:25: error: use of undefined value here causes illegal behavior
......@@ -6708,13 +6676,9 @@ const std = @import("std");
67086676// :167:25: error: use of undefined value here causes illegal behavior
67096677// :167:25: error: use of undefined value here causes illegal behavior
67106678// :167:25: error: use of undefined value here causes illegal behavior
6711// :167:25: note: when computing vector element at index '1'
67126679// :167:25: error: use of undefined value here causes illegal behavior
6713// :167:25: note: when computing vector element at index '1'
67146680// :167:25: error: use of undefined value here causes illegal behavior
6715// :167:25: note: when computing vector element at index '1'
67166681// :167:25: error: use of undefined value here causes illegal behavior
6717// :167:25: note: when computing vector element at index '1'
67186682// :167:25: error: use of undefined value here causes illegal behavior
67196683// :167:25: note: when computing vector element at index '0'
67206684// :167:25: error: use of undefined value here causes illegal behavior
......@@ -6724,19 +6688,21 @@ const std = @import("std");
67246688// :167:25: error: use of undefined value here causes illegal behavior
67256689// :167:25: note: when computing vector element at index '0'
67266690// :167:25: error: use of undefined value here causes illegal behavior
6691// :167:25: note: when computing vector element at index '0'
67276692// :167:25: error: use of undefined value here causes illegal behavior
6693// :167:25: note: when computing vector element at index '0'
67286694// :167:25: error: use of undefined value here causes illegal behavior
6695// :167:25: note: when computing vector element at index '0'
67296696// :167:25: error: use of undefined value here causes illegal behavior
6697// :167:25: note: when computing vector element at index '0'
67306698// :167:25: error: use of undefined value here causes illegal behavior
6699// :167:25: note: when computing vector element at index '0'
67316700// :167:25: error: use of undefined value here causes illegal behavior
6701// :167:25: note: when computing vector element at index '0'
67326702// :167:25: error: use of undefined value here causes illegal behavior
6733// :167:25: note: when computing vector element at index '1'
6734// :167:25: error: use of undefined value here causes illegal behavior
6735// :167:25: note: when computing vector element at index '1'
6736// :167:25: error: use of undefined value here causes illegal behavior
6737// :167:25: note: when computing vector element at index '1'
6703// :167:25: note: when computing vector element at index '0'
67386704// :167:25: error: use of undefined value here causes illegal behavior
6739// :167:25: note: when computing vector element at index '1'
6705// :167:25: note: when computing vector element at index '0'
67406706// :167:25: error: use of undefined value here causes illegal behavior
67416707// :167:25: note: when computing vector element at index '0'
67426708// :167:25: error: use of undefined value here causes illegal behavior
......@@ -6746,19 +6712,25 @@ const std = @import("std");
67466712// :167:25: error: use of undefined value here causes illegal behavior
67476713// :167:25: note: when computing vector element at index '0'
67486714// :167:25: error: use of undefined value here causes illegal behavior
6715// :167:25: note: when computing vector element at index '0'
67496716// :167:25: error: use of undefined value here causes illegal behavior
6717// :167:25: note: when computing vector element at index '0'
67506718// :167:25: error: use of undefined value here causes illegal behavior
6719// :167:25: note: when computing vector element at index '0'
67516720// :167:25: error: use of undefined value here causes illegal behavior
6721// :167:25: note: when computing vector element at index '0'
67526722// :167:25: error: use of undefined value here causes illegal behavior
6723// :167:25: note: when computing vector element at index '0'
67536724// :167:25: error: use of undefined value here causes illegal behavior
6725// :167:25: note: when computing vector element at index '0'
67546726// :167:25: error: use of undefined value here causes illegal behavior
6755// :167:25: note: when computing vector element at index '1'
6727// :167:25: note: when computing vector element at index '0'
67566728// :167:25: error: use of undefined value here causes illegal behavior
6757// :167:25: note: when computing vector element at index '1'
6729// :167:25: note: when computing vector element at index '0'
67586730// :167:25: error: use of undefined value here causes illegal behavior
6759// :167:25: note: when computing vector element at index '1'
6731// :167:25: note: when computing vector element at index '0'
67606732// :167:25: error: use of undefined value here causes illegal behavior
6761// :167:25: note: when computing vector element at index '1'
6733// :167:25: note: when computing vector element at index '0'
67626734// :167:25: error: use of undefined value here causes illegal behavior
67636735// :167:25: note: when computing vector element at index '0'
67646736// :167:25: error: use of undefined value here causes illegal behavior
......@@ -6768,19 +6740,25 @@ const std = @import("std");
67686740// :167:25: error: use of undefined value here causes illegal behavior
67696741// :167:25: note: when computing vector element at index '0'
67706742// :167:25: error: use of undefined value here causes illegal behavior
6743// :167:25: note: when computing vector element at index '0'
67716744// :167:25: error: use of undefined value here causes illegal behavior
6745// :167:25: note: when computing vector element at index '0'
67726746// :167:25: error: use of undefined value here causes illegal behavior
6747// :167:25: note: when computing vector element at index '0'
67736748// :167:25: error: use of undefined value here causes illegal behavior
6749// :167:25: note: when computing vector element at index '0'
67746750// :167:25: error: use of undefined value here causes illegal behavior
6751// :167:25: note: when computing vector element at index '0'
67756752// :167:25: error: use of undefined value here causes illegal behavior
6753// :167:25: note: when computing vector element at index '0'
67766754// :167:25: error: use of undefined value here causes illegal behavior
6777// :167:25: note: when computing vector element at index '1'
6755// :167:25: note: when computing vector element at index '0'
67786756// :167:25: error: use of undefined value here causes illegal behavior
6779// :167:25: note: when computing vector element at index '1'
6757// :167:25: note: when computing vector element at index '0'
67806758// :167:25: error: use of undefined value here causes illegal behavior
6781// :167:25: note: when computing vector element at index '1'
6759// :167:25: note: when computing vector element at index '0'
67826760// :167:25: error: use of undefined value here causes illegal behavior
6783// :167:25: note: when computing vector element at index '1'
6761// :167:25: note: when computing vector element at index '0'
67846762// :167:25: error: use of undefined value here causes illegal behavior
67856763// :167:25: note: when computing vector element at index '0'
67866764// :167:25: error: use of undefined value here causes illegal behavior
......@@ -6790,11 +6768,21 @@ const std = @import("std");
67906768// :167:25: error: use of undefined value here causes illegal behavior
67916769// :167:25: note: when computing vector element at index '0'
67926770// :167:25: error: use of undefined value here causes illegal behavior
6771// :167:25: note: when computing vector element at index '1'
6772// :167:25: error: use of undefined value here causes illegal behavior
6773// :167:25: note: when computing vector element at index '1'
6774// :167:25: error: use of undefined value here causes illegal behavior
6775// :167:25: note: when computing vector element at index '1'
67936776// :167:25: error: use of undefined value here causes illegal behavior
6777// :167:25: note: when computing vector element at index '1'
67946778// :167:25: error: use of undefined value here causes illegal behavior
6779// :167:25: note: when computing vector element at index '1'
67956780// :167:25: error: use of undefined value here causes illegal behavior
6781// :167:25: note: when computing vector element at index '1'
67966782// :167:25: error: use of undefined value here causes illegal behavior
6783// :167:25: note: when computing vector element at index '1'
67976784// :167:25: error: use of undefined value here causes illegal behavior
6785// :167:25: note: when computing vector element at index '1'
67986786// :167:25: error: use of undefined value here causes illegal behavior
67996787// :167:25: note: when computing vector element at index '1'
68006788// :167:25: error: use of undefined value here causes illegal behavior
......@@ -6804,19 +6792,25 @@ const std = @import("std");
68046792// :167:25: error: use of undefined value here causes illegal behavior
68056793// :167:25: note: when computing vector element at index '1'
68066794// :167:25: error: use of undefined value here causes illegal behavior
6807// :167:25: note: when computing vector element at index '0'
6795// :167:25: note: when computing vector element at index '1'
68086796// :167:25: error: use of undefined value here causes illegal behavior
6809// :167:25: note: when computing vector element at index '0'
6797// :167:25: note: when computing vector element at index '1'
68106798// :167:25: error: use of undefined value here causes illegal behavior
6811// :167:25: note: when computing vector element at index '0'
6799// :167:25: note: when computing vector element at index '1'
68126800// :167:25: error: use of undefined value here causes illegal behavior
6813// :167:25: note: when computing vector element at index '0'
6801// :167:25: note: when computing vector element at index '1'
68146802// :167:25: error: use of undefined value here causes illegal behavior
6803// :167:25: note: when computing vector element at index '1'
68156804// :167:25: error: use of undefined value here causes illegal behavior
6805// :167:25: note: when computing vector element at index '1'
68166806// :167:25: error: use of undefined value here causes illegal behavior
6807// :167:25: note: when computing vector element at index '1'
68176808// :167:25: error: use of undefined value here causes illegal behavior
6809// :167:25: note: when computing vector element at index '1'
68186810// :167:25: error: use of undefined value here causes illegal behavior
6811// :167:25: note: when computing vector element at index '1'
68196812// :167:25: error: use of undefined value here causes illegal behavior
6813// :167:25: note: when computing vector element at index '1'
68206814// :167:25: error: use of undefined value here causes illegal behavior
68216815// :167:25: note: when computing vector element at index '1'
68226816// :167:25: error: use of undefined value here causes illegal behavior
......@@ -6826,19 +6820,25 @@ const std = @import("std");
68266820// :167:25: error: use of undefined value here causes illegal behavior
68276821// :167:25: note: when computing vector element at index '1'
68286822// :167:25: error: use of undefined value here causes illegal behavior
6829// :167:25: note: when computing vector element at index '0'
6823// :167:25: note: when computing vector element at index '1'
68306824// :167:25: error: use of undefined value here causes illegal behavior
6831// :167:25: note: when computing vector element at index '0'
6825// :167:25: note: when computing vector element at index '1'
68326826// :167:25: error: use of undefined value here causes illegal behavior
6833// :167:25: note: when computing vector element at index '0'
6827// :167:25: note: when computing vector element at index '1'
68346828// :167:25: error: use of undefined value here causes illegal behavior
6835// :167:25: note: when computing vector element at index '0'
6829// :167:25: note: when computing vector element at index '1'
68366830// :167:25: error: use of undefined value here causes illegal behavior
6831// :167:25: note: when computing vector element at index '1'
68376832// :167:25: error: use of undefined value here causes illegal behavior
6833// :167:25: note: when computing vector element at index '1'
68386834// :167:25: error: use of undefined value here causes illegal behavior
6835// :167:25: note: when computing vector element at index '1'
68396836// :167:25: error: use of undefined value here causes illegal behavior
6837// :167:25: note: when computing vector element at index '1'
68406838// :167:25: error: use of undefined value here causes illegal behavior
6839// :167:25: note: when computing vector element at index '1'
68416840// :167:25: error: use of undefined value here causes illegal behavior
6841// :167:25: note: when computing vector element at index '1'
68426842// :167:25: error: use of undefined value here causes illegal behavior
68436843// :167:25: note: when computing vector element at index '1'
68446844// :167:25: error: use of undefined value here causes illegal behavior
......@@ -6848,13 +6848,13 @@ const std = @import("std");
68486848// :167:25: error: use of undefined value here causes illegal behavior
68496849// :167:25: note: when computing vector element at index '1'
68506850// :167:25: error: use of undefined value here causes illegal behavior
6851// :167:25: note: when computing vector element at index '0'
6851// :167:25: note: when computing vector element at index '1'
68526852// :167:25: error: use of undefined value here causes illegal behavior
6853// :167:25: note: when computing vector element at index '0'
6853// :167:25: note: when computing vector element at index '1'
68546854// :167:25: error: use of undefined value here causes illegal behavior
6855// :167:25: note: when computing vector element at index '0'
6855// :167:25: note: when computing vector element at index '1'
68566856// :167:25: error: use of undefined value here causes illegal behavior
6857// :167:25: note: when computing vector element at index '0'
6857// :167:25: note: when computing vector element at index '1'
68586858// :171:25: error: use of undefined value here causes illegal behavior
68596859// :171:25: error: use of undefined value here causes illegal behavior
68606860// :171:25: error: use of undefined value here causes illegal behavior
......@@ -6862,21 +6862,13 @@ const std = @import("std");
68626862// :171:25: error: use of undefined value here causes illegal behavior
68636863// :171:25: error: use of undefined value here causes illegal behavior
68646864// :171:25: error: use of undefined value here causes illegal behavior
6865// :171:25: note: when computing vector element at index '1'
68666865// :171:25: error: use of undefined value here causes illegal behavior
6867// :171:25: note: when computing vector element at index '1'
68686866// :171:25: error: use of undefined value here causes illegal behavior
6869// :171:25: note: when computing vector element at index '1'
68706867// :171:25: error: use of undefined value here causes illegal behavior
6871// :171:25: note: when computing vector element at index '1'
68726868// :171:25: error: use of undefined value here causes illegal behavior
6873// :171:25: note: when computing vector element at index '0'
68746869// :171:25: error: use of undefined value here causes illegal behavior
6875// :171:25: note: when computing vector element at index '0'
68766870// :171:25: error: use of undefined value here causes illegal behavior
6877// :171:25: note: when computing vector element at index '0'
68786871// :171:25: error: use of undefined value here causes illegal behavior
6879// :171:25: note: when computing vector element at index '0'
68806872// :171:25: error: use of undefined value here causes illegal behavior
68816873// :171:25: error: use of undefined value here causes illegal behavior
68826874// :171:25: error: use of undefined value here causes illegal behavior
......@@ -6884,21 +6876,13 @@ const std = @import("std");
68846876// :171:25: error: use of undefined value here causes illegal behavior
68856877// :171:25: error: use of undefined value here causes illegal behavior
68866878// :171:25: error: use of undefined value here causes illegal behavior
6887// :171:25: note: when computing vector element at index '1'
68886879// :171:25: error: use of undefined value here causes illegal behavior
6889// :171:25: note: when computing vector element at index '1'
68906880// :171:25: error: use of undefined value here causes illegal behavior
6891// :171:25: note: when computing vector element at index '1'
68926881// :171:25: error: use of undefined value here causes illegal behavior
6893// :171:25: note: when computing vector element at index '1'
68946882// :171:25: error: use of undefined value here causes illegal behavior
6895// :171:25: note: when computing vector element at index '0'
68966883// :171:25: error: use of undefined value here causes illegal behavior
6897// :171:25: note: when computing vector element at index '0'
68986884// :171:25: error: use of undefined value here causes illegal behavior
6899// :171:25: note: when computing vector element at index '0'
69006885// :171:25: error: use of undefined value here causes illegal behavior
6901// :171:25: note: when computing vector element at index '0'
69026886// :171:25: error: use of undefined value here causes illegal behavior
69036887// :171:25: error: use of undefined value here causes illegal behavior
69046888// :171:25: error: use of undefined value here causes illegal behavior
......@@ -6906,21 +6890,13 @@ const std = @import("std");
69066890// :171:25: error: use of undefined value here causes illegal behavior
69076891// :171:25: error: use of undefined value here causes illegal behavior
69086892// :171:25: error: use of undefined value here causes illegal behavior
6909// :171:25: note: when computing vector element at index '1'
69106893// :171:25: error: use of undefined value here causes illegal behavior
6911// :171:25: note: when computing vector element at index '1'
69126894// :171:25: error: use of undefined value here causes illegal behavior
6913// :171:25: note: when computing vector element at index '1'
69146895// :171:25: error: use of undefined value here causes illegal behavior
6915// :171:25: note: when computing vector element at index '1'
69166896// :171:25: error: use of undefined value here causes illegal behavior
6917// :171:25: note: when computing vector element at index '0'
69186897// :171:25: error: use of undefined value here causes illegal behavior
6919// :171:25: note: when computing vector element at index '0'
69206898// :171:25: error: use of undefined value here causes illegal behavior
6921// :171:25: note: when computing vector element at index '0'
69226899// :171:25: error: use of undefined value here causes illegal behavior
6923// :171:25: note: when computing vector element at index '0'
69246900// :171:25: error: use of undefined value here causes illegal behavior
69256901// :171:25: error: use of undefined value here causes illegal behavior
69266902// :171:25: error: use of undefined value here causes illegal behavior
......@@ -6928,21 +6904,13 @@ const std = @import("std");
69286904// :171:25: error: use of undefined value here causes illegal behavior
69296905// :171:25: error: use of undefined value here causes illegal behavior
69306906// :171:25: error: use of undefined value here causes illegal behavior
6931// :171:25: note: when computing vector element at index '1'
69326907// :171:25: error: use of undefined value here causes illegal behavior
6933// :171:25: note: when computing vector element at index '1'
69346908// :171:25: error: use of undefined value here causes illegal behavior
6935// :171:25: note: when computing vector element at index '1'
69366909// :171:25: error: use of undefined value here causes illegal behavior
6937// :171:25: note: when computing vector element at index '1'
69386910// :171:25: error: use of undefined value here causes illegal behavior
6939// :171:25: note: when computing vector element at index '0'
69406911// :171:25: error: use of undefined value here causes illegal behavior
6941// :171:25: note: when computing vector element at index '0'
69426912// :171:25: error: use of undefined value here causes illegal behavior
6943// :171:25: note: when computing vector element at index '0'
69446913// :171:25: error: use of undefined value here causes illegal behavior
6945// :171:25: note: when computing vector element at index '0'
69466914// :171:25: error: use of undefined value here causes illegal behavior
69476915// :171:25: error: use of undefined value here causes illegal behavior
69486916// :171:25: error: use of undefined value here causes illegal behavior
......@@ -6950,13 +6918,9 @@ const std = @import("std");
69506918// :171:25: error: use of undefined value here causes illegal behavior
69516919// :171:25: error: use of undefined value here causes illegal behavior
69526920// :171:25: error: use of undefined value here causes illegal behavior
6953// :171:25: note: when computing vector element at index '1'
69546921// :171:25: error: use of undefined value here causes illegal behavior
6955// :171:25: note: when computing vector element at index '1'
69566922// :171:25: error: use of undefined value here causes illegal behavior
6957// :171:25: note: when computing vector element at index '1'
69586923// :171:25: error: use of undefined value here causes illegal behavior
6959// :171:25: note: when computing vector element at index '1'
69606924// :171:25: error: use of undefined value here causes illegal behavior
69616925// :171:25: note: when computing vector element at index '0'
69626926// :171:25: error: use of undefined value here causes illegal behavior
......@@ -6966,19 +6930,21 @@ const std = @import("std");
69666930// :171:25: error: use of undefined value here causes illegal behavior
69676931// :171:25: note: when computing vector element at index '0'
69686932// :171:25: error: use of undefined value here causes illegal behavior
6933// :171:25: note: when computing vector element at index '0'
69696934// :171:25: error: use of undefined value here causes illegal behavior
6935// :171:25: note: when computing vector element at index '0'
69706936// :171:25: error: use of undefined value here causes illegal behavior
6937// :171:25: note: when computing vector element at index '0'
69716938// :171:25: error: use of undefined value here causes illegal behavior
6939// :171:25: note: when computing vector element at index '0'
69726940// :171:25: error: use of undefined value here causes illegal behavior
6941// :171:25: note: when computing vector element at index '0'
69736942// :171:25: error: use of undefined value here causes illegal behavior
6943// :171:25: note: when computing vector element at index '0'
69746944// :171:25: error: use of undefined value here causes illegal behavior
6975// :171:25: note: when computing vector element at index '1'
6976// :171:25: error: use of undefined value here causes illegal behavior
6977// :171:25: note: when computing vector element at index '1'
6978// :171:25: error: use of undefined value here causes illegal behavior
6979// :171:25: note: when computing vector element at index '1'
6945// :171:25: note: when computing vector element at index '0'
69806946// :171:25: error: use of undefined value here causes illegal behavior
6981// :171:25: note: when computing vector element at index '1'
6947// :171:25: note: when computing vector element at index '0'
69826948// :171:25: error: use of undefined value here causes illegal behavior
69836949// :171:25: note: when computing vector element at index '0'
69846950// :171:25: error: use of undefined value here causes illegal behavior
......@@ -6988,19 +6954,25 @@ const std = @import("std");
69886954// :171:25: error: use of undefined value here causes illegal behavior
69896955// :171:25: note: when computing vector element at index '0'
69906956// :171:25: error: use of undefined value here causes illegal behavior
6957// :171:25: note: when computing vector element at index '0'
69916958// :171:25: error: use of undefined value here causes illegal behavior
6959// :171:25: note: when computing vector element at index '0'
69926960// :171:25: error: use of undefined value here causes illegal behavior
6961// :171:25: note: when computing vector element at index '0'
69936962// :171:25: error: use of undefined value here causes illegal behavior
6963// :171:25: note: when computing vector element at index '0'
69946964// :171:25: error: use of undefined value here causes illegal behavior
6965// :171:25: note: when computing vector element at index '0'
69956966// :171:25: error: use of undefined value here causes illegal behavior
6967// :171:25: note: when computing vector element at index '0'
69966968// :171:25: error: use of undefined value here causes illegal behavior
6997// :171:25: note: when computing vector element at index '1'
6969// :171:25: note: when computing vector element at index '0'
69986970// :171:25: error: use of undefined value here causes illegal behavior
6999// :171:25: note: when computing vector element at index '1'
6971// :171:25: note: when computing vector element at index '0'
70006972// :171:25: error: use of undefined value here causes illegal behavior
7001// :171:25: note: when computing vector element at index '1'
6973// :171:25: note: when computing vector element at index '0'
70026974// :171:25: error: use of undefined value here causes illegal behavior
7003// :171:25: note: when computing vector element at index '1'
6975// :171:25: note: when computing vector element at index '0'
70046976// :171:25: error: use of undefined value here causes illegal behavior
70056977// :171:25: note: when computing vector element at index '0'
70066978// :171:25: error: use of undefined value here causes illegal behavior
......@@ -7010,19 +6982,25 @@ const std = @import("std");
70106982// :171:25: error: use of undefined value here causes illegal behavior
70116983// :171:25: note: when computing vector element at index '0'
70126984// :171:25: error: use of undefined value here causes illegal behavior
6985// :171:25: note: when computing vector element at index '0'
70136986// :171:25: error: use of undefined value here causes illegal behavior
6987// :171:25: note: when computing vector element at index '0'
70146988// :171:25: error: use of undefined value here causes illegal behavior
6989// :171:25: note: when computing vector element at index '0'
70156990// :171:25: error: use of undefined value here causes illegal behavior
6991// :171:25: note: when computing vector element at index '0'
70166992// :171:25: error: use of undefined value here causes illegal behavior
6993// :171:25: note: when computing vector element at index '0'
70176994// :171:25: error: use of undefined value here causes illegal behavior
6995// :171:25: note: when computing vector element at index '0'
70186996// :171:25: error: use of undefined value here causes illegal behavior
7019// :171:25: note: when computing vector element at index '1'
6997// :171:25: note: when computing vector element at index '0'
70206998// :171:25: error: use of undefined value here causes illegal behavior
7021// :171:25: note: when computing vector element at index '1'
6999// :171:25: note: when computing vector element at index '0'
70227000// :171:25: error: use of undefined value here causes illegal behavior
7023// :171:25: note: when computing vector element at index '1'
7001// :171:25: note: when computing vector element at index '0'
70247002// :171:25: error: use of undefined value here causes illegal behavior
7025// :171:25: note: when computing vector element at index '1'
7003// :171:25: note: when computing vector element at index '0'
70267004// :171:25: error: use of undefined value here causes illegal behavior
70277005// :171:25: note: when computing vector element at index '0'
70287006// :171:25: error: use of undefined value here causes illegal behavior
......@@ -7032,11 +7010,17 @@ const std = @import("std");
70327010// :171:25: error: use of undefined value here causes illegal behavior
70337011// :171:25: note: when computing vector element at index '0'
70347012// :171:25: error: use of undefined value here causes illegal behavior
7013// :171:25: note: when computing vector element at index '1'
70357014// :171:25: error: use of undefined value here causes illegal behavior
7015// :171:25: note: when computing vector element at index '1'
70367016// :171:25: error: use of undefined value here causes illegal behavior
7017// :171:25: note: when computing vector element at index '1'
70377018// :171:25: error: use of undefined value here causes illegal behavior
7019// :171:25: note: when computing vector element at index '1'
70387020// :171:25: error: use of undefined value here causes illegal behavior
7021// :171:25: note: when computing vector element at index '1'
70397022// :171:25: error: use of undefined value here causes illegal behavior
7023// :171:25: note: when computing vector element at index '1'
70407024// :171:25: error: use of undefined value here causes illegal behavior
70417025// :171:25: note: when computing vector element at index '1'
70427026// :171:25: error: use of undefined value here causes illegal behavior
......@@ -7046,19 +7030,25 @@ const std = @import("std");
70467030// :171:25: error: use of undefined value here causes illegal behavior
70477031// :171:25: note: when computing vector element at index '1'
70487032// :171:25: error: use of undefined value here causes illegal behavior
7049// :171:25: note: when computing vector element at index '0'
7033// :171:25: note: when computing vector element at index '1'
70507034// :171:25: error: use of undefined value here causes illegal behavior
7051// :171:25: note: when computing vector element at index '0'
7035// :171:25: note: when computing vector element at index '1'
70527036// :171:25: error: use of undefined value here causes illegal behavior
7053// :171:25: note: when computing vector element at index '0'
7037// :171:25: note: when computing vector element at index '1'
70547038// :171:25: error: use of undefined value here causes illegal behavior
7055// :171:25: note: when computing vector element at index '0'
7039// :171:25: note: when computing vector element at index '1'
70567040// :171:25: error: use of undefined value here causes illegal behavior
7041// :171:25: note: when computing vector element at index '1'
70577042// :171:25: error: use of undefined value here causes illegal behavior
7043// :171:25: note: when computing vector element at index '1'
70587044// :171:25: error: use of undefined value here causes illegal behavior
7045// :171:25: note: when computing vector element at index '1'
70597046// :171:25: error: use of undefined value here causes illegal behavior
7047// :171:25: note: when computing vector element at index '1'
70607048// :171:25: error: use of undefined value here causes illegal behavior
7049// :171:25: note: when computing vector element at index '1'
70617050// :171:25: error: use of undefined value here causes illegal behavior
7051// :171:25: note: when computing vector element at index '1'
70627052// :171:25: error: use of undefined value here causes illegal behavior
70637053// :171:25: note: when computing vector element at index '1'
70647054// :171:25: error: use of undefined value here causes illegal behavior
......@@ -7068,19 +7058,25 @@ const std = @import("std");
70687058// :171:25: error: use of undefined value here causes illegal behavior
70697059// :171:25: note: when computing vector element at index '1'
70707060// :171:25: error: use of undefined value here causes illegal behavior
7071// :171:25: note: when computing vector element at index '0'
7061// :171:25: note: when computing vector element at index '1'
70727062// :171:25: error: use of undefined value here causes illegal behavior
7073// :171:25: note: when computing vector element at index '0'
7063// :171:25: note: when computing vector element at index '1'
70747064// :171:25: error: use of undefined value here causes illegal behavior
7075// :171:25: note: when computing vector element at index '0'
7065// :171:25: note: when computing vector element at index '1'
70767066// :171:25: error: use of undefined value here causes illegal behavior
7077// :171:25: note: when computing vector element at index '0'
7067// :171:25: note: when computing vector element at index '1'
70787068// :171:25: error: use of undefined value here causes illegal behavior
7069// :171:25: note: when computing vector element at index '1'
70797070// :171:25: error: use of undefined value here causes illegal behavior
7071// :171:25: note: when computing vector element at index '1'
70807072// :171:25: error: use of undefined value here causes illegal behavior
7073// :171:25: note: when computing vector element at index '1'
70817074// :171:25: error: use of undefined value here causes illegal behavior
7075// :171:25: note: when computing vector element at index '1'
70827076// :171:25: error: use of undefined value here causes illegal behavior
7077// :171:25: note: when computing vector element at index '1'
70837078// :171:25: error: use of undefined value here causes illegal behavior
7079// :171:25: note: when computing vector element at index '1'
70847080// :171:25: error: use of undefined value here causes illegal behavior
70857081// :171:25: note: when computing vector element at index '1'
70867082// :171:25: error: use of undefined value here causes illegal behavior
......@@ -7090,37 +7086,33 @@ const std = @import("std");
70907086// :171:25: error: use of undefined value here causes illegal behavior
70917087// :171:25: note: when computing vector element at index '1'
70927088// :171:25: error: use of undefined value here causes illegal behavior
7093// :171:25: note: when computing vector element at index '0'
7089// :171:25: note: when computing vector element at index '1'
70947090// :171:25: error: use of undefined value here causes illegal behavior
7095// :171:25: note: when computing vector element at index '0'
7091// :171:25: note: when computing vector element at index '1'
70967092// :171:25: error: use of undefined value here causes illegal behavior
7097// :171:25: note: when computing vector element at index '0'
7093// :171:25: note: when computing vector element at index '1'
70987094// :171:25: error: use of undefined value here causes illegal behavior
7099// :171:25: note: when computing vector element at index '0'
7095// :171:25: note: when computing vector element at index '1'
7096// :171:25: error: use of undefined value here causes illegal behavior
7097// :171:25: note: when computing vector element at index '1'
7098// :171:25: error: use of undefined value here causes illegal behavior
7099// :171:25: note: when computing vector element at index '1'
71007100// :177:17: error: use of undefined value here causes illegal behavior
71017101// :177:17: error: use of undefined value here causes illegal behavior
71027102// :177:17: error: use of undefined value here causes illegal behavior
7103// :177:17: note: when computing vector element at index '0'
71047103// :177:17: error: use of undefined value here causes illegal behavior
7105// :177:17: note: when computing vector element at index '0'
71067104// :177:17: error: use of undefined value here causes illegal behavior
7107// :177:17: note: when computing vector element at index '0'
71087105// :177:17: error: use of undefined value here causes illegal behavior
7109// :177:17: note: when computing vector element at index '0'
71107106// :177:17: error: use of undefined value here causes illegal behavior
7111// :177:17: note: when computing vector element at index '1'
71127107// :177:17: error: use of undefined value here causes illegal behavior
7113// :177:17: note: when computing vector element at index '1'
71147108// :177:17: error: use of undefined value here causes illegal behavior
7115// :177:17: note: when computing vector element at index '0'
71167109// :177:17: error: use of undefined value here causes illegal behavior
7117// :177:17: note: when computing vector element at index '0'
71187110// :177:17: error: use of undefined value here causes illegal behavior
7119// :177:17: note: when computing vector element at index '0'
71207111// :177:17: error: use of undefined value here causes illegal behavior
7121// :177:17: note: when computing vector element at index '0'
71227112// :177:17: error: use of undefined value here causes illegal behavior
7113// :177:17: note: when computing vector element at index '0'
71237114// :177:17: error: use of undefined value here causes illegal behavior
7115// :177:17: note: when computing vector element at index '0'
71247116// :177:17: error: use of undefined value here causes illegal behavior
71257117// :177:17: note: when computing vector element at index '0'
71267118// :177:17: error: use of undefined value here causes illegal behavior
......@@ -7130,9 +7122,9 @@ const std = @import("std");
71307122// :177:17: error: use of undefined value here causes illegal behavior
71317123// :177:17: note: when computing vector element at index '0'
71327124// :177:17: error: use of undefined value here causes illegal behavior
7133// :177:17: note: when computing vector element at index '1'
7125// :177:17: note: when computing vector element at index '0'
71347126// :177:17: error: use of undefined value here causes illegal behavior
7135// :177:17: note: when computing vector element at index '1'
7127// :177:17: note: when computing vector element at index '0'
71367128// :177:17: error: use of undefined value here causes illegal behavior
71377129// :177:17: note: when computing vector element at index '0'
71387130// :177:17: error: use of undefined value here causes illegal behavior
......@@ -7142,7 +7134,9 @@ const std = @import("std");
71427134// :177:17: error: use of undefined value here causes illegal behavior
71437135// :177:17: note: when computing vector element at index '0'
71447136// :177:17: error: use of undefined value here causes illegal behavior
7137// :177:17: note: when computing vector element at index '0'
71457138// :177:17: error: use of undefined value here causes illegal behavior
7139// :177:17: note: when computing vector element at index '0'
71467140// :177:17: error: use of undefined value here causes illegal behavior
71477141// :177:17: note: when computing vector element at index '0'
71487142// :177:17: error: use of undefined value here causes illegal behavior
......@@ -7152,9 +7146,9 @@ const std = @import("std");
71527146// :177:17: error: use of undefined value here causes illegal behavior
71537147// :177:17: note: when computing vector element at index '0'
71547148// :177:17: error: use of undefined value here causes illegal behavior
7155// :177:17: note: when computing vector element at index '1'
7149// :177:17: note: when computing vector element at index '0'
71567150// :177:17: error: use of undefined value here causes illegal behavior
7157// :177:17: note: when computing vector element at index '1'
7151// :177:17: note: when computing vector element at index '0'
71587152// :177:17: error: use of undefined value here causes illegal behavior
71597153// :177:17: note: when computing vector element at index '0'
71607154// :177:17: error: use of undefined value here causes illegal behavior
......@@ -7164,7 +7158,9 @@ const std = @import("std");
71647158// :177:17: error: use of undefined value here causes illegal behavior
71657159// :177:17: note: when computing vector element at index '0'
71667160// :177:17: error: use of undefined value here causes illegal behavior
7161// :177:17: note: when computing vector element at index '0'
71677162// :177:17: error: use of undefined value here causes illegal behavior
7163// :177:17: note: when computing vector element at index '0'
71687164// :177:17: error: use of undefined value here causes illegal behavior
71697165// :177:17: note: when computing vector element at index '0'
71707166// :177:17: error: use of undefined value here causes illegal behavior
......@@ -7174,9 +7170,9 @@ const std = @import("std");
71747170// :177:17: error: use of undefined value here causes illegal behavior
71757171// :177:17: note: when computing vector element at index '0'
71767172// :177:17: error: use of undefined value here causes illegal behavior
7177// :177:17: note: when computing vector element at index '1'
7173// :177:17: note: when computing vector element at index '0'
71787174// :177:17: error: use of undefined value here causes illegal behavior
7179// :177:17: note: when computing vector element at index '1'
7175// :177:17: note: when computing vector element at index '0'
71807176// :177:17: error: use of undefined value here causes illegal behavior
71817177// :177:17: note: when computing vector element at index '0'
71827178// :177:17: error: use of undefined value here causes illegal behavior
......@@ -7186,7 +7182,9 @@ const std = @import("std");
71867182// :177:17: error: use of undefined value here causes illegal behavior
71877183// :177:17: note: when computing vector element at index '0'
71887184// :177:17: error: use of undefined value here causes illegal behavior
7185// :177:17: note: when computing vector element at index '0'
71897186// :177:17: error: use of undefined value here causes illegal behavior
7187// :177:17: note: when computing vector element at index '0'
71907188// :177:17: error: use of undefined value here causes illegal behavior
71917189// :177:17: note: when computing vector element at index '0'
71927190// :177:17: error: use of undefined value here causes illegal behavior
......@@ -7196,9 +7194,9 @@ const std = @import("std");
71967194// :177:17: error: use of undefined value here causes illegal behavior
71977195// :177:17: note: when computing vector element at index '0'
71987196// :177:17: error: use of undefined value here causes illegal behavior
7199// :177:17: note: when computing vector element at index '1'
7197// :177:17: note: when computing vector element at index '0'
72007198// :177:17: error: use of undefined value here causes illegal behavior
7201// :177:17: note: when computing vector element at index '1'
7199// :177:17: note: when computing vector element at index '0'
72027200// :177:17: error: use of undefined value here causes illegal behavior
72037201// :177:17: note: when computing vector element at index '0'
72047202// :177:17: error: use of undefined value here causes illegal behavior
......@@ -7208,27 +7206,29 @@ const std = @import("std");
72087206// :177:17: error: use of undefined value here causes illegal behavior
72097207// :177:17: note: when computing vector element at index '0'
72107208// :177:17: error: use of undefined value here causes illegal behavior
7209// :177:17: note: when computing vector element at index '1'
72117210// :177:17: error: use of undefined value here causes illegal behavior
7211// :177:17: note: when computing vector element at index '1'
72127212// :177:17: error: use of undefined value here causes illegal behavior
7213// :177:17: note: when computing vector element at index '0'
7213// :177:17: note: when computing vector element at index '1'
72147214// :177:17: error: use of undefined value here causes illegal behavior
7215// :177:17: note: when computing vector element at index '0'
7215// :177:17: note: when computing vector element at index '1'
72167216// :177:17: error: use of undefined value here causes illegal behavior
7217// :177:17: note: when computing vector element at index '0'
7217// :177:17: note: when computing vector element at index '1'
72187218// :177:17: error: use of undefined value here causes illegal behavior
7219// :177:17: note: when computing vector element at index '0'
7219// :177:17: note: when computing vector element at index '1'
72207220// :177:17: error: use of undefined value here causes illegal behavior
72217221// :177:17: note: when computing vector element at index '1'
72227222// :177:17: error: use of undefined value here causes illegal behavior
72237223// :177:17: note: when computing vector element at index '1'
72247224// :177:17: error: use of undefined value here causes illegal behavior
7225// :177:17: note: when computing vector element at index '0'
7225// :177:17: note: when computing vector element at index '1'
72267226// :177:17: error: use of undefined value here causes illegal behavior
7227// :177:17: note: when computing vector element at index '0'
7227// :177:17: note: when computing vector element at index '1'
72287228// :177:17: error: use of undefined value here causes illegal behavior
7229// :177:17: note: when computing vector element at index '0'
7229// :177:17: note: when computing vector element at index '1'
72307230// :177:17: error: use of undefined value here causes illegal behavior
7231// :177:17: note: when computing vector element at index '0'
7231// :177:17: note: when computing vector element at index '1'
72327232// :177:21: error: use of undefined value here causes illegal behavior
72337233// :177:21: note: when computing vector element at index '0'
72347234// :177:21: error: use of undefined value here causes illegal behavior
......@@ -7256,27 +7256,19 @@ const std = @import("std");
72567256// :180:17: error: use of undefined value here causes illegal behavior
72577257// :180:17: error: use of undefined value here causes illegal behavior
72587258// :180:17: error: use of undefined value here causes illegal behavior
7259// :180:17: note: when computing vector element at index '0'
72607259// :180:17: error: use of undefined value here causes illegal behavior
7261// :180:17: note: when computing vector element at index '0'
72627260// :180:17: error: use of undefined value here causes illegal behavior
7263// :180:17: note: when computing vector element at index '0'
72647261// :180:17: error: use of undefined value here causes illegal behavior
7265// :180:17: note: when computing vector element at index '0'
72667262// :180:17: error: use of undefined value here causes illegal behavior
7267// :180:17: note: when computing vector element at index '1'
72687263// :180:17: error: use of undefined value here causes illegal behavior
7269// :180:17: note: when computing vector element at index '1'
72707264// :180:17: error: use of undefined value here causes illegal behavior
7271// :180:17: note: when computing vector element at index '0'
72727265// :180:17: error: use of undefined value here causes illegal behavior
7273// :180:17: note: when computing vector element at index '0'
72747266// :180:17: error: use of undefined value here causes illegal behavior
7275// :180:17: note: when computing vector element at index '0'
72767267// :180:17: error: use of undefined value here causes illegal behavior
7277// :180:17: note: when computing vector element at index '0'
72787268// :180:17: error: use of undefined value here causes illegal behavior
7269// :180:17: note: when computing vector element at index '0'
72797270// :180:17: error: use of undefined value here causes illegal behavior
7271// :180:17: note: when computing vector element at index '0'
72807272// :180:17: error: use of undefined value here causes illegal behavior
72817273// :180:17: note: when computing vector element at index '0'
72827274// :180:17: error: use of undefined value here causes illegal behavior
......@@ -7286,9 +7278,9 @@ const std = @import("std");
72867278// :180:17: error: use of undefined value here causes illegal behavior
72877279// :180:17: note: when computing vector element at index '0'
72887280// :180:17: error: use of undefined value here causes illegal behavior
7289// :180:17: note: when computing vector element at index '1'
7281// :180:17: note: when computing vector element at index '0'
72907282// :180:17: error: use of undefined value here causes illegal behavior
7291// :180:17: note: when computing vector element at index '1'
7283// :180:17: note: when computing vector element at index '0'
72927284// :180:17: error: use of undefined value here causes illegal behavior
72937285// :180:17: note: when computing vector element at index '0'
72947286// :180:17: error: use of undefined value here causes illegal behavior
......@@ -7298,7 +7290,9 @@ const std = @import("std");
72987290// :180:17: error: use of undefined value here causes illegal behavior
72997291// :180:17: note: when computing vector element at index '0'
73007292// :180:17: error: use of undefined value here causes illegal behavior
7293// :180:17: note: when computing vector element at index '0'
73017294// :180:17: error: use of undefined value here causes illegal behavior
7295// :180:17: note: when computing vector element at index '0'
73027296// :180:17: error: use of undefined value here causes illegal behavior
73037297// :180:17: note: when computing vector element at index '0'
73047298// :180:17: error: use of undefined value here causes illegal behavior
......@@ -7308,9 +7302,9 @@ const std = @import("std");
73087302// :180:17: error: use of undefined value here causes illegal behavior
73097303// :180:17: note: when computing vector element at index '0'
73107304// :180:17: error: use of undefined value here causes illegal behavior
7311// :180:17: note: when computing vector element at index '1'
7305// :180:17: note: when computing vector element at index '0'
73127306// :180:17: error: use of undefined value here causes illegal behavior
7313// :180:17: note: when computing vector element at index '1'
7307// :180:17: note: when computing vector element at index '0'
73147308// :180:17: error: use of undefined value here causes illegal behavior
73157309// :180:17: note: when computing vector element at index '0'
73167310// :180:17: error: use of undefined value here causes illegal behavior
......@@ -7320,7 +7314,9 @@ const std = @import("std");
73207314// :180:17: error: use of undefined value here causes illegal behavior
73217315// :180:17: note: when computing vector element at index '0'
73227316// :180:17: error: use of undefined value here causes illegal behavior
7317// :180:17: note: when computing vector element at index '0'
73237318// :180:17: error: use of undefined value here causes illegal behavior
7319// :180:17: note: when computing vector element at index '0'
73247320// :180:17: error: use of undefined value here causes illegal behavior
73257321// :180:17: note: when computing vector element at index '0'
73267322// :180:17: error: use of undefined value here causes illegal behavior
......@@ -7330,9 +7326,9 @@ const std = @import("std");
73307326// :180:17: error: use of undefined value here causes illegal behavior
73317327// :180:17: note: when computing vector element at index '0'
73327328// :180:17: error: use of undefined value here causes illegal behavior
7333// :180:17: note: when computing vector element at index '1'
7329// :180:17: note: when computing vector element at index '0'
73347330// :180:17: error: use of undefined value here causes illegal behavior
7335// :180:17: note: when computing vector element at index '1'
7331// :180:17: note: when computing vector element at index '0'
73367332// :180:17: error: use of undefined value here causes illegal behavior
73377333// :180:17: note: when computing vector element at index '0'
73387334// :180:17: error: use of undefined value here causes illegal behavior
......@@ -7342,7 +7338,9 @@ const std = @import("std");
73427338// :180:17: error: use of undefined value here causes illegal behavior
73437339// :180:17: note: when computing vector element at index '0'
73447340// :180:17: error: use of undefined value here causes illegal behavior
7341// :180:17: note: when computing vector element at index '0'
73457342// :180:17: error: use of undefined value here causes illegal behavior
7343// :180:17: note: when computing vector element at index '0'
73467344// :180:17: error: use of undefined value here causes illegal behavior
73477345// :180:17: note: when computing vector element at index '0'
73487346// :180:17: error: use of undefined value here causes illegal behavior
......@@ -7352,9 +7350,9 @@ const std = @import("std");
73527350// :180:17: error: use of undefined value here causes illegal behavior
73537351// :180:17: note: when computing vector element at index '0'
73547352// :180:17: error: use of undefined value here causes illegal behavior
7355// :180:17: note: when computing vector element at index '1'
7353// :180:17: note: when computing vector element at index '0'
73567354// :180:17: error: use of undefined value here causes illegal behavior
7357// :180:17: note: when computing vector element at index '1'
7355// :180:17: note: when computing vector element at index '0'
73587356// :180:17: error: use of undefined value here causes illegal behavior
73597357// :180:17: note: when computing vector element at index '0'
73607358// :180:17: error: use of undefined value here causes illegal behavior
......@@ -7364,27 +7362,29 @@ const std = @import("std");
73647362// :180:17: error: use of undefined value here causes illegal behavior
73657363// :180:17: note: when computing vector element at index '0'
73667364// :180:17: error: use of undefined value here causes illegal behavior
7365// :180:17: note: when computing vector element at index '1'
73677366// :180:17: error: use of undefined value here causes illegal behavior
7367// :180:17: note: when computing vector element at index '1'
73687368// :180:17: error: use of undefined value here causes illegal behavior
7369// :180:17: note: when computing vector element at index '0'
7369// :180:17: note: when computing vector element at index '1'
73707370// :180:17: error: use of undefined value here causes illegal behavior
7371// :180:17: note: when computing vector element at index '0'
7371// :180:17: note: when computing vector element at index '1'
73727372// :180:17: error: use of undefined value here causes illegal behavior
7373// :180:17: note: when computing vector element at index '0'
7373// :180:17: note: when computing vector element at index '1'
73747374// :180:17: error: use of undefined value here causes illegal behavior
7375// :180:17: note: when computing vector element at index '0'
7375// :180:17: note: when computing vector element at index '1'
73767376// :180:17: error: use of undefined value here causes illegal behavior
73777377// :180:17: note: when computing vector element at index '1'
73787378// :180:17: error: use of undefined value here causes illegal behavior
73797379// :180:17: note: when computing vector element at index '1'
73807380// :180:17: error: use of undefined value here causes illegal behavior
7381// :180:17: note: when computing vector element at index '0'
7381// :180:17: note: when computing vector element at index '1'
73827382// :180:17: error: use of undefined value here causes illegal behavior
7383// :180:17: note: when computing vector element at index '0'
7383// :180:17: note: when computing vector element at index '1'
73847384// :180:17: error: use of undefined value here causes illegal behavior
7385// :180:17: note: when computing vector element at index '0'
7385// :180:17: note: when computing vector element at index '1'
73867386// :180:17: error: use of undefined value here causes illegal behavior
7387// :180:17: note: when computing vector element at index '0'
7387// :180:17: note: when computing vector element at index '1'
73887388// :180:21: error: use of undefined value here causes illegal behavior
73897389// :180:21: note: when computing vector element at index '0'
73907390// :180:21: error: use of undefined value here causes illegal behavior
......@@ -7412,27 +7412,19 @@ const std = @import("std");
74127412// :183:17: error: use of undefined value here causes illegal behavior
74137413// :183:17: error: use of undefined value here causes illegal behavior
74147414// :183:17: error: use of undefined value here causes illegal behavior
7415// :183:17: note: when computing vector element at index '0'
74167415// :183:17: error: use of undefined value here causes illegal behavior
7417// :183:17: note: when computing vector element at index '0'
74187416// :183:17: error: use of undefined value here causes illegal behavior
7419// :183:17: note: when computing vector element at index '0'
74207417// :183:17: error: use of undefined value here causes illegal behavior
7421// :183:17: note: when computing vector element at index '0'
74227418// :183:17: error: use of undefined value here causes illegal behavior
7423// :183:17: note: when computing vector element at index '1'
74247419// :183:17: error: use of undefined value here causes illegal behavior
7425// :183:17: note: when computing vector element at index '1'
74267420// :183:17: error: use of undefined value here causes illegal behavior
7427// :183:17: note: when computing vector element at index '0'
74287421// :183:17: error: use of undefined value here causes illegal behavior
7429// :183:17: note: when computing vector element at index '0'
74307422// :183:17: error: use of undefined value here causes illegal behavior
7431// :183:17: note: when computing vector element at index '0'
74327423// :183:17: error: use of undefined value here causes illegal behavior
7433// :183:17: note: when computing vector element at index '0'
74347424// :183:17: error: use of undefined value here causes illegal behavior
7425// :183:17: note: when computing vector element at index '0'
74357426// :183:17: error: use of undefined value here causes illegal behavior
7427// :183:17: note: when computing vector element at index '0'
74367428// :183:17: error: use of undefined value here causes illegal behavior
74377429// :183:17: note: when computing vector element at index '0'
74387430// :183:17: error: use of undefined value here causes illegal behavior
......@@ -7442,9 +7434,9 @@ const std = @import("std");
74427434// :183:17: error: use of undefined value here causes illegal behavior
74437435// :183:17: note: when computing vector element at index '0'
74447436// :183:17: error: use of undefined value here causes illegal behavior
7445// :183:17: note: when computing vector element at index '1'
7437// :183:17: note: when computing vector element at index '0'
74467438// :183:17: error: use of undefined value here causes illegal behavior
7447// :183:17: note: when computing vector element at index '1'
7439// :183:17: note: when computing vector element at index '0'
74487440// :183:17: error: use of undefined value here causes illegal behavior
74497441// :183:17: note: when computing vector element at index '0'
74507442// :183:17: error: use of undefined value here causes illegal behavior
......@@ -7454,7 +7446,9 @@ const std = @import("std");
74547446// :183:17: error: use of undefined value here causes illegal behavior
74557447// :183:17: note: when computing vector element at index '0'
74567448// :183:17: error: use of undefined value here causes illegal behavior
7449// :183:17: note: when computing vector element at index '0'
74577450// :183:17: error: use of undefined value here causes illegal behavior
7451// :183:17: note: when computing vector element at index '0'
74587452// :183:17: error: use of undefined value here causes illegal behavior
74597453// :183:17: note: when computing vector element at index '0'
74607454// :183:17: error: use of undefined value here causes illegal behavior
......@@ -7464,9 +7458,9 @@ const std = @import("std");
74647458// :183:17: error: use of undefined value here causes illegal behavior
74657459// :183:17: note: when computing vector element at index '0'
74667460// :183:17: error: use of undefined value here causes illegal behavior
7467// :183:17: note: when computing vector element at index '1'
7461// :183:17: note: when computing vector element at index '0'
74687462// :183:17: error: use of undefined value here causes illegal behavior
7469// :183:17: note: when computing vector element at index '1'
7463// :183:17: note: when computing vector element at index '0'
74707464// :183:17: error: use of undefined value here causes illegal behavior
74717465// :183:17: note: when computing vector element at index '0'
74727466// :183:17: error: use of undefined value here causes illegal behavior
......@@ -7476,7 +7470,9 @@ const std = @import("std");
74767470// :183:17: error: use of undefined value here causes illegal behavior
74777471// :183:17: note: when computing vector element at index '0'
74787472// :183:17: error: use of undefined value here causes illegal behavior
7473// :183:17: note: when computing vector element at index '0'
74797474// :183:17: error: use of undefined value here causes illegal behavior
7475// :183:17: note: when computing vector element at index '0'
74807476// :183:17: error: use of undefined value here causes illegal behavior
74817477// :183:17: note: when computing vector element at index '0'
74827478// :183:17: error: use of undefined value here causes illegal behavior
......@@ -7486,9 +7482,9 @@ const std = @import("std");
74867482// :183:17: error: use of undefined value here causes illegal behavior
74877483// :183:17: note: when computing vector element at index '0'
74887484// :183:17: error: use of undefined value here causes illegal behavior
7489// :183:17: note: when computing vector element at index '1'
7485// :183:17: note: when computing vector element at index '0'
74907486// :183:17: error: use of undefined value here causes illegal behavior
7491// :183:17: note: when computing vector element at index '1'
7487// :183:17: note: when computing vector element at index '0'
74927488// :183:17: error: use of undefined value here causes illegal behavior
74937489// :183:17: note: when computing vector element at index '0'
74947490// :183:17: error: use of undefined value here causes illegal behavior
......@@ -7498,7 +7494,9 @@ const std = @import("std");
74987494// :183:17: error: use of undefined value here causes illegal behavior
74997495// :183:17: note: when computing vector element at index '0'
75007496// :183:17: error: use of undefined value here causes illegal behavior
7497// :183:17: note: when computing vector element at index '0'
75017498// :183:17: error: use of undefined value here causes illegal behavior
7499// :183:17: note: when computing vector element at index '0'
75027500// :183:17: error: use of undefined value here causes illegal behavior
75037501// :183:17: note: when computing vector element at index '0'
75047502// :183:17: error: use of undefined value here causes illegal behavior
......@@ -7508,9 +7506,9 @@ const std = @import("std");
75087506// :183:17: error: use of undefined value here causes illegal behavior
75097507// :183:17: note: when computing vector element at index '0'
75107508// :183:17: error: use of undefined value here causes illegal behavior
7511// :183:17: note: when computing vector element at index '1'
7509// :183:17: note: when computing vector element at index '0'
75127510// :183:17: error: use of undefined value here causes illegal behavior
7513// :183:17: note: when computing vector element at index '1'
7511// :183:17: note: when computing vector element at index '0'
75147512// :183:17: error: use of undefined value here causes illegal behavior
75157513// :183:17: note: when computing vector element at index '0'
75167514// :183:17: error: use of undefined value here causes illegal behavior
......@@ -7520,27 +7518,29 @@ const std = @import("std");
75207518// :183:17: error: use of undefined value here causes illegal behavior
75217519// :183:17: note: when computing vector element at index '0'
75227520// :183:17: error: use of undefined value here causes illegal behavior
7521// :183:17: note: when computing vector element at index '1'
75237522// :183:17: error: use of undefined value here causes illegal behavior
7523// :183:17: note: when computing vector element at index '1'
75247524// :183:17: error: use of undefined value here causes illegal behavior
7525// :183:17: note: when computing vector element at index '0'
7525// :183:17: note: when computing vector element at index '1'
75267526// :183:17: error: use of undefined value here causes illegal behavior
7527// :183:17: note: when computing vector element at index '0'
7527// :183:17: note: when computing vector element at index '1'
75287528// :183:17: error: use of undefined value here causes illegal behavior
7529// :183:17: note: when computing vector element at index '0'
7529// :183:17: note: when computing vector element at index '1'
75307530// :183:17: error: use of undefined value here causes illegal behavior
7531// :183:17: note: when computing vector element at index '0'
7531// :183:17: note: when computing vector element at index '1'
75327532// :183:17: error: use of undefined value here causes illegal behavior
75337533// :183:17: note: when computing vector element at index '1'
75347534// :183:17: error: use of undefined value here causes illegal behavior
75357535// :183:17: note: when computing vector element at index '1'
75367536// :183:17: error: use of undefined value here causes illegal behavior
7537// :183:17: note: when computing vector element at index '0'
7537// :183:17: note: when computing vector element at index '1'
75387538// :183:17: error: use of undefined value here causes illegal behavior
7539// :183:17: note: when computing vector element at index '0'
7539// :183:17: note: when computing vector element at index '1'
75407540// :183:17: error: use of undefined value here causes illegal behavior
7541// :183:17: note: when computing vector element at index '0'
7541// :183:17: note: when computing vector element at index '1'
75427542// :183:17: error: use of undefined value here causes illegal behavior
7543// :183:17: note: when computing vector element at index '0'
7543// :183:17: note: when computing vector element at index '1'
75447544// :183:21: error: use of undefined value here causes illegal behavior
75457545// :183:21: note: when computing vector element at index '0'
75467546// :183:21: error: use of undefined value here causes illegal behavior
test/cases/compile_errors/undef_arith_returns_undef.zig+1794-1794
......@@ -681,1800 +681,1360 @@ inline fn testFloatWithValue(comptime Float: type, x: Float) void {
681681// @as(@Vector(2, u8), undefined)
682682// @as(@Vector(2, u8), [runtime value])
683683// @as(@Vector(2, u8), [runtime value])
684// @as(i8, undefined)
685// @as(i8, undefined)
686// @as(@Vector(2, i8), .{ 6, undefined })
687// @as(@Vector(2, i8), .{ undefined, 6 })
688// @as(@Vector(2, i8), undefined)
689// @as(@Vector(2, i8), .{ 6, undefined })
690// @as(@Vector(2, i8), .{ 6, undefined })
691// @as(@Vector(2, i8), undefined)
692// @as(@Vector(2, i8), undefined)
693// @as(@Vector(2, i8), .{ undefined, 6 })
694// @as(@Vector(2, i8), undefined)
695// @as(@Vector(2, i8), .{ undefined, 6 })
696// @as(@Vector(2, i8), undefined)
697// @as(@Vector(2, i8), undefined)
698// @as(@Vector(2, i8), undefined)
699// @as(@Vector(2, i8), undefined)
700// @as(@Vector(2, i8), undefined)
701// @as(i8, undefined)
702// @as(i8, undefined)
703// @as(@Vector(2, i8), .{ 6, undefined })
704// @as(@Vector(2, i8), .{ undefined, 6 })
705// @as(@Vector(2, i8), undefined)
706// @as(@Vector(2, i8), .{ 6, undefined })
707// @as(@Vector(2, i8), .{ 6, undefined })
708// @as(@Vector(2, i8), undefined)
709// @as(@Vector(2, i8), undefined)
710// @as(@Vector(2, i8), .{ undefined, 6 })
711// @as(@Vector(2, i8), undefined)
712// @as(@Vector(2, i8), .{ undefined, 6 })
713// @as(@Vector(2, i8), undefined)
714// @as(@Vector(2, i8), undefined)
715// @as(@Vector(2, i8), undefined)
716// @as(@Vector(2, i8), undefined)
717// @as(@Vector(2, i8), undefined)
718// @as(i8, undefined)
719// @as(i8, undefined)
720// @as(@Vector(2, i8), .{ 0, undefined })
721// @as(@Vector(2, i8), .{ undefined, 0 })
722// @as(@Vector(2, i8), undefined)
723// @as(@Vector(2, i8), .{ 0, undefined })
724// @as(@Vector(2, i8), .{ 0, undefined })
725// @as(@Vector(2, i8), undefined)
726// @as(@Vector(2, i8), undefined)
727// @as(@Vector(2, i8), .{ undefined, 0 })
728// @as(@Vector(2, i8), undefined)
729// @as(@Vector(2, i8), .{ undefined, 0 })
730// @as(@Vector(2, i8), undefined)
731// @as(@Vector(2, i8), undefined)
732// @as(@Vector(2, i8), undefined)
733// @as(@Vector(2, i8), undefined)
734// @as(@Vector(2, i8), undefined)
735// @as(i8, undefined)
736// @as(i8, undefined)
737// @as(@Vector(2, i8), .{ 0, undefined })
738// @as(@Vector(2, i8), .{ undefined, 0 })
739// @as(@Vector(2, i8), undefined)
740// @as(@Vector(2, i8), .{ 0, undefined })
741// @as(@Vector(2, i8), .{ 0, undefined })
742// @as(@Vector(2, i8), undefined)
743// @as(@Vector(2, i8), undefined)
744// @as(@Vector(2, i8), .{ undefined, 0 })
745// @as(@Vector(2, i8), undefined)
746// @as(@Vector(2, i8), .{ undefined, 0 })
747// @as(@Vector(2, i8), undefined)
748// @as(@Vector(2, i8), undefined)
749// @as(@Vector(2, i8), undefined)
750// @as(@Vector(2, i8), undefined)
751// @as(@Vector(2, i8), undefined)
752// @as(i8, undefined)
753// @as(i8, undefined)
754// @as(@Vector(2, i8), .{ 9, undefined })
755// @as(@Vector(2, i8), .{ undefined, 9 })
756// @as(@Vector(2, i8), undefined)
757// @as(@Vector(2, i8), .{ 9, undefined })
758// @as(@Vector(2, i8), .{ 9, undefined })
759// @as(@Vector(2, i8), undefined)
760// @as(@Vector(2, i8), undefined)
761// @as(@Vector(2, i8), .{ undefined, 9 })
762// @as(@Vector(2, i8), undefined)
763// @as(@Vector(2, i8), .{ undefined, 9 })
764// @as(@Vector(2, i8), undefined)
765// @as(@Vector(2, i8), undefined)
766// @as(@Vector(2, i8), undefined)
767// @as(@Vector(2, i8), undefined)
768// @as(@Vector(2, i8), undefined)
769// @as(i8, undefined)
770// @as(i8, undefined)
771// @as(@Vector(2, i8), .{ 9, undefined })
772// @as(@Vector(2, i8), .{ undefined, 9 })
773// @as(@Vector(2, i8), undefined)
774// @as(@Vector(2, i8), .{ 9, undefined })
775// @as(@Vector(2, i8), .{ 9, undefined })
776// @as(@Vector(2, i8), undefined)
777// @as(@Vector(2, i8), undefined)
778// @as(@Vector(2, i8), .{ undefined, 9 })
779// @as(@Vector(2, i8), undefined)
780// @as(@Vector(2, i8), .{ undefined, 9 })
781// @as(@Vector(2, i8), undefined)
782// @as(@Vector(2, i8), undefined)
783// @as(@Vector(2, i8), undefined)
784// @as(@Vector(2, i8), undefined)
785// @as(@Vector(2, i8), undefined)
786// @as(i8, undefined)
787// @as(i8, undefined)
788// @as(@Vector(2, i8), .{ 0, undefined })
789// @as(@Vector(2, i8), .{ undefined, 0 })
790// @as(@Vector(2, i8), undefined)
791// @as(@Vector(2, i8), .{ 0, undefined })
792// @as(@Vector(2, i8), .{ 0, undefined })
793// @as(@Vector(2, i8), undefined)
794// @as(@Vector(2, i8), undefined)
795// @as(@Vector(2, i8), .{ undefined, 0 })
796// @as(@Vector(2, i8), undefined)
797// @as(@Vector(2, i8), .{ undefined, 0 })
798// @as(@Vector(2, i8), undefined)
799// @as(@Vector(2, i8), undefined)
800// @as(@Vector(2, i8), undefined)
801// @as(@Vector(2, i8), undefined)
802// @as(@Vector(2, i8), undefined)
803// @as(i8, undefined)
804// @as(@Vector(2, i8), undefined)
805// @as(i8, undefined)
806// @as(i8, undefined)
807// @as(@Vector(2, i8), undefined)
808// @as(@Vector(2, i8), undefined)
809// @as(i8, undefined)
810// @as(@Vector(2, i8), undefined)
811// @as(i8, undefined)
812// @as(i8, undefined)
813// @as(@Vector(2, i8), [runtime value])
814// @as(@Vector(2, i8), [runtime value])
815// @as(@Vector(2, i8), undefined)
816// @as(@Vector(2, i8), [runtime value])
817// @as(@Vector(2, i8), [runtime value])
818// @as(@Vector(2, i8), [runtime value])
819// @as(@Vector(2, i8), undefined)
820// @as(@Vector(2, i8), [runtime value])
821// @as(@Vector(2, i8), [runtime value])
822// @as(@Vector(2, i8), [runtime value])
823// @as(@Vector(2, i8), undefined)
824// @as(@Vector(2, i8), undefined)
825// @as(@Vector(2, i8), undefined)
826// @as(@Vector(2, i8), undefined)
827// @as(@Vector(2, i8), undefined)
828// @as(i8, undefined)
829// @as(i8, undefined)
830// @as(@Vector(2, i8), [runtime value])
831// @as(@Vector(2, i8), [runtime value])
832// @as(@Vector(2, i8), undefined)
833// @as(@Vector(2, i8), [runtime value])
834// @as(@Vector(2, i8), [runtime value])
835// @as(@Vector(2, i8), [runtime value])
836// @as(@Vector(2, i8), undefined)
837// @as(@Vector(2, i8), [runtime value])
838// @as(@Vector(2, i8), [runtime value])
839// @as(@Vector(2, i8), [runtime value])
840// @as(@Vector(2, i8), undefined)
841// @as(@Vector(2, i8), undefined)
842// @as(@Vector(2, i8), undefined)
843// @as(@Vector(2, i8), undefined)
844// @as(@Vector(2, i8), undefined)
845// @as(i8, undefined)
846// @as(i8, undefined)
847// @as(@Vector(2, i8), [runtime value])
848// @as(@Vector(2, i8), [runtime value])
849// @as(@Vector(2, i8), undefined)
850// @as(@Vector(2, i8), [runtime value])
851// @as(@Vector(2, i8), [runtime value])
852// @as(@Vector(2, i8), [runtime value])
853// @as(@Vector(2, i8), undefined)
854// @as(@Vector(2, i8), [runtime value])
855// @as(@Vector(2, i8), [runtime value])
856// @as(@Vector(2, i8), [runtime value])
857// @as(@Vector(2, i8), undefined)
858// @as(@Vector(2, i8), undefined)
859// @as(@Vector(2, i8), undefined)
860// @as(@Vector(2, i8), undefined)
861// @as(@Vector(2, i8), undefined)
862// @as(i8, undefined)
863// @as(i8, undefined)
864// @as(@Vector(2, i8), [runtime value])
865// @as(@Vector(2, i8), [runtime value])
866// @as(@Vector(2, i8), undefined)
867// @as(@Vector(2, i8), [runtime value])
868// @as(@Vector(2, i8), [runtime value])
869// @as(@Vector(2, i8), [runtime value])
870// @as(@Vector(2, i8), undefined)
871// @as(@Vector(2, i8), [runtime value])
872// @as(@Vector(2, i8), [runtime value])
873// @as(@Vector(2, i8), [runtime value])
874// @as(@Vector(2, i8), undefined)
875// @as(@Vector(2, i8), undefined)
876// @as(@Vector(2, i8), undefined)
877// @as(@Vector(2, i8), undefined)
878// @as(@Vector(2, i8), undefined)
879// @as(i8, undefined)
880// @as(i8, undefined)
881// @as(@Vector(2, i8), [runtime value])
882// @as(@Vector(2, i8), [runtime value])
883// @as(@Vector(2, i8), undefined)
884// @as(@Vector(2, i8), [runtime value])
885// @as(@Vector(2, i8), [runtime value])
886// @as(@Vector(2, i8), [runtime value])
887// @as(@Vector(2, i8), undefined)
888// @as(@Vector(2, i8), [runtime value])
889// @as(@Vector(2, i8), [runtime value])
890// @as(@Vector(2, i8), [runtime value])
891// @as(@Vector(2, i8), undefined)
892// @as(@Vector(2, i8), undefined)
893// @as(@Vector(2, i8), undefined)
894// @as(@Vector(2, i8), undefined)
895// @as(@Vector(2, i8), undefined)
896// @as(i8, undefined)
897// @as(i8, undefined)
898// @as(@Vector(2, i8), [runtime value])
899// @as(@Vector(2, i8), [runtime value])
900// @as(@Vector(2, i8), undefined)
901// @as(@Vector(2, i8), [runtime value])
902// @as(@Vector(2, i8), [runtime value])
903// @as(@Vector(2, i8), [runtime value])
904// @as(@Vector(2, i8), undefined)
905// @as(@Vector(2, i8), [runtime value])
906// @as(@Vector(2, i8), [runtime value])
907// @as(@Vector(2, i8), [runtime value])
908// @as(@Vector(2, i8), undefined)
909// @as(@Vector(2, i8), undefined)
910// @as(@Vector(2, i8), undefined)
911// @as(@Vector(2, i8), undefined)
912// @as(@Vector(2, i8), undefined)
913// @as(i8, [runtime value])
914// @as(i8, [runtime value])
915// @as(@Vector(2, i8), [runtime value])
916// @as(@Vector(2, i8), [runtime value])
917// @as(@Vector(2, i8), [runtime value])
918// @as(@Vector(2, i8), [runtime value])
919// @as(@Vector(2, i8), [runtime value])
920// @as(@Vector(2, i8), [runtime value])
921// @as(@Vector(2, i8), [runtime value])
922// @as(@Vector(2, i8), [runtime value])
923// @as(@Vector(2, i8), [runtime value])
924// @as(@Vector(2, i8), [runtime value])
925// @as(@Vector(2, i8), [runtime value])
926// @as(@Vector(2, i8), [runtime value])
927// @as(@Vector(2, i8), [runtime value])
928// @as(@Vector(2, i8), [runtime value])
929// @as(@Vector(2, i8), undefined)
930// @as(i8, undefined)
931// @as(@Vector(2, i8), undefined)
932// @as(i8, undefined)
933// @as(i8, undefined)
934// @as(@Vector(2, i8), undefined)
935// @as(@Vector(2, i8), undefined)
936// @as(i8, undefined)
937// @as(@Vector(2, i8), undefined)
938// @as(u32, undefined)
939// @as(u32, undefined)
940// @as(@Vector(2, u32), .{ 6, undefined })
941// @as(@Vector(2, u32), .{ undefined, 6 })
942// @as(@Vector(2, u32), undefined)
943// @as(@Vector(2, u32), .{ 6, undefined })
944// @as(@Vector(2, u32), .{ 6, undefined })
945// @as(@Vector(2, u32), undefined)
946// @as(@Vector(2, u32), undefined)
947// @as(@Vector(2, u32), .{ undefined, 6 })
948// @as(@Vector(2, u32), undefined)
949// @as(@Vector(2, u32), .{ undefined, 6 })
950// @as(@Vector(2, u32), undefined)
951// @as(@Vector(2, u32), undefined)
952// @as(@Vector(2, u32), undefined)
953// @as(@Vector(2, u32), undefined)
954// @as(@Vector(2, u32), undefined)
955// @as(u32, undefined)
956// @as(u32, undefined)
957// @as(@Vector(2, u32), .{ 6, undefined })
958// @as(@Vector(2, u32), .{ undefined, 6 })
959// @as(@Vector(2, u32), undefined)
960// @as(@Vector(2, u32), .{ 6, undefined })
961// @as(@Vector(2, u32), .{ 6, undefined })
962// @as(@Vector(2, u32), undefined)
963// @as(@Vector(2, u32), undefined)
964// @as(@Vector(2, u32), .{ undefined, 6 })
965// @as(@Vector(2, u32), undefined)
966// @as(@Vector(2, u32), .{ undefined, 6 })
967// @as(@Vector(2, u32), undefined)
968// @as(@Vector(2, u32), undefined)
969// @as(@Vector(2, u32), undefined)
970// @as(@Vector(2, u32), undefined)
971// @as(@Vector(2, u32), undefined)
972// @as(u32, undefined)
973// @as(u32, undefined)
974// @as(@Vector(2, u32), .{ 0, undefined })
975// @as(@Vector(2, u32), .{ undefined, 0 })
976// @as(@Vector(2, u32), undefined)
977// @as(@Vector(2, u32), .{ 0, undefined })
978// @as(@Vector(2, u32), .{ 0, undefined })
979// @as(@Vector(2, u32), undefined)
980// @as(@Vector(2, u32), undefined)
981// @as(@Vector(2, u32), .{ undefined, 0 })
982// @as(@Vector(2, u32), undefined)
983// @as(@Vector(2, u32), .{ undefined, 0 })
984// @as(@Vector(2, u32), undefined)
985// @as(@Vector(2, u32), undefined)
986// @as(@Vector(2, u32), undefined)
987// @as(@Vector(2, u32), undefined)
988// @as(@Vector(2, u32), undefined)
989// @as(u32, undefined)
990// @as(u32, undefined)
991// @as(@Vector(2, u32), .{ 0, undefined })
992// @as(@Vector(2, u32), .{ undefined, 0 })
993// @as(@Vector(2, u32), undefined)
994// @as(@Vector(2, u32), .{ 0, undefined })
995// @as(@Vector(2, u32), .{ 0, undefined })
996// @as(@Vector(2, u32), undefined)
997// @as(@Vector(2, u32), undefined)
998// @as(@Vector(2, u32), .{ undefined, 0 })
999// @as(@Vector(2, u32), undefined)
1000// @as(@Vector(2, u32), .{ undefined, 0 })
1001// @as(@Vector(2, u32), undefined)
1002// @as(@Vector(2, u32), undefined)
1003// @as(@Vector(2, u32), undefined)
1004// @as(@Vector(2, u32), undefined)
1005// @as(@Vector(2, u32), undefined)
1006// @as(u32, undefined)
1007// @as(u32, undefined)
1008// @as(@Vector(2, u32), .{ 9, undefined })
1009// @as(@Vector(2, u32), .{ undefined, 9 })
1010// @as(@Vector(2, u32), undefined)
1011// @as(@Vector(2, u32), .{ 9, undefined })
1012// @as(@Vector(2, u32), .{ 9, undefined })
1013// @as(@Vector(2, u32), undefined)
1014// @as(@Vector(2, u32), undefined)
1015// @as(@Vector(2, u32), .{ undefined, 9 })
1016// @as(@Vector(2, u32), undefined)
1017// @as(@Vector(2, u32), .{ undefined, 9 })
1018// @as(@Vector(2, u32), undefined)
1019// @as(@Vector(2, u32), undefined)
1020// @as(@Vector(2, u32), undefined)
1021// @as(@Vector(2, u32), undefined)
1022// @as(@Vector(2, u32), undefined)
1023// @as(u32, undefined)
1024// @as(u32, undefined)
1025// @as(@Vector(2, u32), .{ 9, undefined })
1026// @as(@Vector(2, u32), .{ undefined, 9 })
1027// @as(@Vector(2, u32), undefined)
1028// @as(@Vector(2, u32), .{ 9, undefined })
1029// @as(@Vector(2, u32), .{ 9, undefined })
1030// @as(@Vector(2, u32), undefined)
1031// @as(@Vector(2, u32), undefined)
1032// @as(@Vector(2, u32), .{ undefined, 9 })
1033// @as(@Vector(2, u32), undefined)
1034// @as(@Vector(2, u32), .{ undefined, 9 })
1035// @as(@Vector(2, u32), undefined)
1036// @as(@Vector(2, u32), undefined)
1037// @as(@Vector(2, u32), undefined)
1038// @as(@Vector(2, u32), undefined)
1039// @as(@Vector(2, u32), undefined)
1040// @as(u32, undefined)
1041// @as(u32, undefined)
1042// @as(@Vector(2, u32), .{ 24, undefined })
1043// @as(@Vector(2, u32), .{ undefined, 24 })
1044// @as(@Vector(2, u32), undefined)
1045// @as(@Vector(2, u32), .{ 24, undefined })
1046// @as(@Vector(2, u32), .{ 24, undefined })
1047// @as(@Vector(2, u32), undefined)
1048// @as(@Vector(2, u32), undefined)
1049// @as(@Vector(2, u32), .{ undefined, 24 })
1050// @as(@Vector(2, u32), undefined)
1051// @as(@Vector(2, u32), .{ undefined, 24 })
1052// @as(@Vector(2, u32), undefined)
1053// @as(@Vector(2, u32), undefined)
1054// @as(@Vector(2, u32), undefined)
1055// @as(@Vector(2, u32), undefined)
1056// @as(@Vector(2, u32), undefined)
1057// @as(u32, undefined)
1058// @as(u32, undefined)
1059// @as(@Vector(2, u32), .{ 0, undefined })
1060// @as(@Vector(2, u32), .{ undefined, 0 })
1061// @as(@Vector(2, u32), undefined)
1062// @as(@Vector(2, u32), .{ 0, undefined })
1063// @as(@Vector(2, u32), .{ 0, undefined })
1064// @as(@Vector(2, u32), undefined)
1065// @as(@Vector(2, u32), undefined)
1066// @as(@Vector(2, u32), .{ undefined, 0 })
1067// @as(@Vector(2, u32), undefined)
1068// @as(@Vector(2, u32), .{ undefined, 0 })
1069// @as(@Vector(2, u32), undefined)
1070// @as(@Vector(2, u32), undefined)
1071// @as(@Vector(2, u32), undefined)
1072// @as(@Vector(2, u32), undefined)
1073// @as(@Vector(2, u32), undefined)
1074// @as(u32, undefined)
1075// @as(@Vector(2, u32), undefined)
1076// @as(u32, undefined)
1077// @as(u32, undefined)
1078// @as(@Vector(2, u32), undefined)
1079// @as(@Vector(2, u32), undefined)
1080// @as(u1, undefined)
1081// @as(@Vector(2, u1), .{ 1, undefined })
1082// @as(@Vector(2, u1), .{ undefined, 1 })
1083// @as(@Vector(2, u1), undefined)
1084// @as(u32, undefined)
1085// @as(@Vector(2, u32), undefined)
1086// @as(u32, undefined)
1087// @as(u32, undefined)
1088// @as(@Vector(2, u32), [runtime value])
1089// @as(@Vector(2, u32), [runtime value])
1090// @as(@Vector(2, u32), undefined)
1091// @as(@Vector(2, u32), [runtime value])
1092// @as(@Vector(2, u32), [runtime value])
1093// @as(@Vector(2, u32), [runtime value])
1094// @as(@Vector(2, u32), undefined)
1095// @as(@Vector(2, u32), [runtime value])
1096// @as(@Vector(2, u32), [runtime value])
1097// @as(@Vector(2, u32), [runtime value])
1098// @as(@Vector(2, u32), undefined)
1099// @as(@Vector(2, u32), undefined)
1100// @as(@Vector(2, u32), undefined)
1101// @as(@Vector(2, u32), undefined)
1102// @as(@Vector(2, u32), undefined)
1103// @as(u32, undefined)
1104// @as(u32, undefined)
1105// @as(@Vector(2, u32), [runtime value])
1106// @as(@Vector(2, u32), [runtime value])
1107// @as(@Vector(2, u32), undefined)
1108// @as(@Vector(2, u32), [runtime value])
1109// @as(@Vector(2, u32), [runtime value])
1110// @as(@Vector(2, u32), [runtime value])
1111// @as(@Vector(2, u32), undefined)
1112// @as(@Vector(2, u32), [runtime value])
1113// @as(@Vector(2, u32), [runtime value])
1114// @as(@Vector(2, u32), [runtime value])
1115// @as(@Vector(2, u32), undefined)
1116// @as(@Vector(2, u32), undefined)
1117// @as(@Vector(2, u32), undefined)
1118// @as(@Vector(2, u32), undefined)
1119// @as(@Vector(2, u32), undefined)
1120// @as(u32, undefined)
1121// @as(u32, undefined)
1122// @as(@Vector(2, u32), [runtime value])
1123// @as(@Vector(2, u32), [runtime value])
1124// @as(@Vector(2, u32), undefined)
1125// @as(@Vector(2, u32), [runtime value])
1126// @as(@Vector(2, u32), [runtime value])
1127// @as(@Vector(2, u32), [runtime value])
1128// @as(@Vector(2, u32), undefined)
1129// @as(@Vector(2, u32), [runtime value])
1130// @as(@Vector(2, u32), [runtime value])
1131// @as(@Vector(2, u32), [runtime value])
1132// @as(@Vector(2, u32), undefined)
1133// @as(@Vector(2, u32), undefined)
1134// @as(@Vector(2, u32), undefined)
1135// @as(@Vector(2, u32), undefined)
1136// @as(@Vector(2, u32), undefined)
1137// @as(u32, undefined)
1138// @as(u32, undefined)
1139// @as(@Vector(2, u32), [runtime value])
1140// @as(@Vector(2, u32), [runtime value])
1141// @as(@Vector(2, u32), undefined)
1142// @as(@Vector(2, u32), [runtime value])
1143// @as(@Vector(2, u32), [runtime value])
1144// @as(@Vector(2, u32), [runtime value])
1145// @as(@Vector(2, u32), undefined)
1146// @as(@Vector(2, u32), [runtime value])
1147// @as(@Vector(2, u32), [runtime value])
1148// @as(@Vector(2, u32), [runtime value])
1149// @as(@Vector(2, u32), undefined)
1150// @as(@Vector(2, u32), undefined)
1151// @as(@Vector(2, u32), undefined)
1152// @as(@Vector(2, u32), undefined)
1153// @as(@Vector(2, u32), undefined)
1154// @as(u32, undefined)
1155// @as(u32, undefined)
1156// @as(@Vector(2, u32), [runtime value])
1157// @as(@Vector(2, u32), [runtime value])
1158// @as(@Vector(2, u32), undefined)
1159// @as(@Vector(2, u32), [runtime value])
1160// @as(@Vector(2, u32), [runtime value])
1161// @as(@Vector(2, u32), [runtime value])
1162// @as(@Vector(2, u32), undefined)
1163// @as(@Vector(2, u32), [runtime value])
1164// @as(@Vector(2, u32), [runtime value])
1165// @as(@Vector(2, u32), [runtime value])
1166// @as(@Vector(2, u32), undefined)
1167// @as(@Vector(2, u32), undefined)
1168// @as(@Vector(2, u32), undefined)
1169// @as(@Vector(2, u32), undefined)
1170// @as(@Vector(2, u32), undefined)
1171// @as(u32, undefined)
1172// @as(u32, undefined)
1173// @as(@Vector(2, u32), [runtime value])
1174// @as(@Vector(2, u32), [runtime value])
1175// @as(@Vector(2, u32), undefined)
1176// @as(@Vector(2, u32), [runtime value])
1177// @as(@Vector(2, u32), [runtime value])
1178// @as(@Vector(2, u32), [runtime value])
1179// @as(@Vector(2, u32), undefined)
1180// @as(@Vector(2, u32), [runtime value])
1181// @as(@Vector(2, u32), [runtime value])
1182// @as(@Vector(2, u32), [runtime value])
1183// @as(@Vector(2, u32), undefined)
1184// @as(@Vector(2, u32), undefined)
1185// @as(@Vector(2, u32), undefined)
1186// @as(@Vector(2, u32), undefined)
1187// @as(@Vector(2, u32), undefined)
1188// @as(u32, undefined)
1189// @as(u32, undefined)
1190// @as(@Vector(2, u32), [runtime value])
1191// @as(@Vector(2, u32), [runtime value])
1192// @as(@Vector(2, u32), undefined)
1193// @as(@Vector(2, u32), [runtime value])
1194// @as(@Vector(2, u32), [runtime value])
1195// @as(@Vector(2, u32), [runtime value])
1196// @as(@Vector(2, u32), undefined)
1197// @as(@Vector(2, u32), [runtime value])
1198// @as(@Vector(2, u32), [runtime value])
1199// @as(@Vector(2, u32), [runtime value])
1200// @as(@Vector(2, u32), undefined)
1201// @as(@Vector(2, u32), undefined)
1202// @as(@Vector(2, u32), undefined)
1203// @as(@Vector(2, u32), undefined)
1204// @as(@Vector(2, u32), undefined)
1205// @as(u32, [runtime value])
1206// @as(u32, [runtime value])
1207// @as(@Vector(2, u32), [runtime value])
1208// @as(@Vector(2, u32), [runtime value])
1209// @as(@Vector(2, u32), [runtime value])
1210// @as(@Vector(2, u32), [runtime value])
1211// @as(@Vector(2, u32), [runtime value])
1212// @as(@Vector(2, u32), [runtime value])
1213// @as(@Vector(2, u32), [runtime value])
1214// @as(@Vector(2, u32), [runtime value])
1215// @as(@Vector(2, u32), [runtime value])
1216// @as(@Vector(2, u32), [runtime value])
1217// @as(@Vector(2, u32), [runtime value])
1218// @as(@Vector(2, u32), [runtime value])
1219// @as(@Vector(2, u32), [runtime value])
1220// @as(@Vector(2, u32), [runtime value])
1221// @as(@Vector(2, u32), undefined)
1222// @as(u32, undefined)
1223// @as(@Vector(2, u32), undefined)
1224// @as(u32, undefined)
1225// @as(u32, undefined)
1226// @as(@Vector(2, u32), undefined)
1227// @as(@Vector(2, u32), undefined)
1228// @as(u1, undefined)
1229// @as(@Vector(2, u1), [runtime value])
1230// @as(@Vector(2, u1), [runtime value])
1231// @as(@Vector(2, u1), undefined)
1232// @as(u32, undefined)
1233// @as(@Vector(2, u32), undefined)
1234// @as(i32, undefined)
1235// @as(i32, undefined)
1236// @as(@Vector(2, i32), .{ 6, undefined })
1237// @as(@Vector(2, i32), .{ undefined, 6 })
1238// @as(@Vector(2, i32), undefined)
1239// @as(@Vector(2, i32), .{ 6, undefined })
1240// @as(@Vector(2, i32), .{ 6, undefined })
1241// @as(@Vector(2, i32), undefined)
1242// @as(@Vector(2, i32), undefined)
1243// @as(@Vector(2, i32), .{ undefined, 6 })
1244// @as(@Vector(2, i32), undefined)
1245// @as(@Vector(2, i32), .{ undefined, 6 })
1246// @as(@Vector(2, i32), undefined)
1247// @as(@Vector(2, i32), undefined)
1248// @as(@Vector(2, i32), undefined)
1249// @as(@Vector(2, i32), undefined)
1250// @as(@Vector(2, i32), undefined)
1251// @as(i32, undefined)
1252// @as(i32, undefined)
1253// @as(@Vector(2, i32), .{ 6, undefined })
1254// @as(@Vector(2, i32), .{ undefined, 6 })
1255// @as(@Vector(2, i32), undefined)
1256// @as(@Vector(2, i32), .{ 6, undefined })
1257// @as(@Vector(2, i32), .{ 6, undefined })
1258// @as(@Vector(2, i32), undefined)
1259// @as(@Vector(2, i32), undefined)
1260// @as(@Vector(2, i32), .{ undefined, 6 })
1261// @as(@Vector(2, i32), undefined)
1262// @as(@Vector(2, i32), .{ undefined, 6 })
1263// @as(@Vector(2, i32), undefined)
1264// @as(@Vector(2, i32), undefined)
1265// @as(@Vector(2, i32), undefined)
1266// @as(@Vector(2, i32), undefined)
1267// @as(@Vector(2, i32), undefined)
1268// @as(i32, undefined)
1269// @as(i32, undefined)
1270// @as(@Vector(2, i32), .{ 0, undefined })
1271// @as(@Vector(2, i32), .{ undefined, 0 })
1272// @as(@Vector(2, i32), undefined)
1273// @as(@Vector(2, i32), .{ 0, undefined })
1274// @as(@Vector(2, i32), .{ 0, undefined })
1275// @as(@Vector(2, i32), undefined)
1276// @as(@Vector(2, i32), undefined)
1277// @as(@Vector(2, i32), .{ undefined, 0 })
1278// @as(@Vector(2, i32), undefined)
1279// @as(@Vector(2, i32), .{ undefined, 0 })
1280// @as(@Vector(2, i32), undefined)
1281// @as(@Vector(2, i32), undefined)
1282// @as(@Vector(2, i32), undefined)
1283// @as(@Vector(2, i32), undefined)
1284// @as(@Vector(2, i32), undefined)
1285// @as(i32, undefined)
1286// @as(i32, undefined)
1287// @as(@Vector(2, i32), .{ 0, undefined })
1288// @as(@Vector(2, i32), .{ undefined, 0 })
1289// @as(@Vector(2, i32), undefined)
1290// @as(@Vector(2, i32), .{ 0, undefined })
1291// @as(@Vector(2, i32), .{ 0, undefined })
1292// @as(@Vector(2, i32), undefined)
1293// @as(@Vector(2, i32), undefined)
1294// @as(@Vector(2, i32), .{ undefined, 0 })
1295// @as(@Vector(2, i32), undefined)
1296// @as(@Vector(2, i32), .{ undefined, 0 })
1297// @as(@Vector(2, i32), undefined)
1298// @as(@Vector(2, i32), undefined)
1299// @as(@Vector(2, i32), undefined)
1300// @as(@Vector(2, i32), undefined)
1301// @as(@Vector(2, i32), undefined)
1302// @as(i32, undefined)
1303// @as(i32, undefined)
1304// @as(@Vector(2, i32), .{ 9, undefined })
1305// @as(@Vector(2, i32), .{ undefined, 9 })
1306// @as(@Vector(2, i32), undefined)
1307// @as(@Vector(2, i32), .{ 9, undefined })
1308// @as(@Vector(2, i32), .{ 9, undefined })
1309// @as(@Vector(2, i32), undefined)
1310// @as(@Vector(2, i32), undefined)
1311// @as(@Vector(2, i32), .{ undefined, 9 })
1312// @as(@Vector(2, i32), undefined)
1313// @as(@Vector(2, i32), .{ undefined, 9 })
1314// @as(@Vector(2, i32), undefined)
1315// @as(@Vector(2, i32), undefined)
1316// @as(@Vector(2, i32), undefined)
1317// @as(@Vector(2, i32), undefined)
1318// @as(@Vector(2, i32), undefined)
1319// @as(i32, undefined)
1320// @as(i32, undefined)
1321// @as(@Vector(2, i32), .{ 9, undefined })
1322// @as(@Vector(2, i32), .{ undefined, 9 })
1323// @as(@Vector(2, i32), undefined)
1324// @as(@Vector(2, i32), .{ 9, undefined })
1325// @as(@Vector(2, i32), .{ 9, undefined })
1326// @as(@Vector(2, i32), undefined)
1327// @as(@Vector(2, i32), undefined)
1328// @as(@Vector(2, i32), .{ undefined, 9 })
1329// @as(@Vector(2, i32), undefined)
1330// @as(@Vector(2, i32), .{ undefined, 9 })
1331// @as(@Vector(2, i32), undefined)
1332// @as(@Vector(2, i32), undefined)
1333// @as(@Vector(2, i32), undefined)
1334// @as(@Vector(2, i32), undefined)
1335// @as(@Vector(2, i32), undefined)
1336// @as(i32, undefined)
1337// @as(i32, undefined)
1338// @as(@Vector(2, i32), .{ 0, undefined })
1339// @as(@Vector(2, i32), .{ undefined, 0 })
1340// @as(@Vector(2, i32), undefined)
1341// @as(@Vector(2, i32), .{ 0, undefined })
1342// @as(@Vector(2, i32), .{ 0, undefined })
1343// @as(@Vector(2, i32), undefined)
1344// @as(@Vector(2, i32), undefined)
1345// @as(@Vector(2, i32), .{ undefined, 0 })
1346// @as(@Vector(2, i32), undefined)
1347// @as(@Vector(2, i32), .{ undefined, 0 })
1348// @as(@Vector(2, i32), undefined)
1349// @as(@Vector(2, i32), undefined)
1350// @as(@Vector(2, i32), undefined)
1351// @as(@Vector(2, i32), undefined)
1352// @as(@Vector(2, i32), undefined)
1353// @as(i32, undefined)
1354// @as(@Vector(2, i32), undefined)
1355// @as(i32, undefined)
1356// @as(i32, undefined)
1357// @as(@Vector(2, i32), undefined)
1358// @as(@Vector(2, i32), undefined)
1359// @as(i32, undefined)
1360// @as(@Vector(2, i32), undefined)
1361// @as(i32, undefined)
1362// @as(i32, undefined)
1363// @as(@Vector(2, i32), [runtime value])
1364// @as(@Vector(2, i32), [runtime value])
1365// @as(@Vector(2, i32), undefined)
1366// @as(@Vector(2, i32), [runtime value])
1367// @as(@Vector(2, i32), [runtime value])
1368// @as(@Vector(2, i32), [runtime value])
1369// @as(@Vector(2, i32), undefined)
1370// @as(@Vector(2, i32), [runtime value])
1371// @as(@Vector(2, i32), [runtime value])
1372// @as(@Vector(2, i32), [runtime value])
1373// @as(@Vector(2, i32), undefined)
1374// @as(@Vector(2, i32), undefined)
1375// @as(@Vector(2, i32), undefined)
1376// @as(@Vector(2, i32), undefined)
1377// @as(@Vector(2, i32), undefined)
1378// @as(i32, undefined)
1379// @as(i32, undefined)
1380// @as(@Vector(2, i32), [runtime value])
1381// @as(@Vector(2, i32), [runtime value])
1382// @as(@Vector(2, i32), undefined)
1383// @as(@Vector(2, i32), [runtime value])
1384// @as(@Vector(2, i32), [runtime value])
1385// @as(@Vector(2, i32), [runtime value])
1386// @as(@Vector(2, i32), undefined)
1387// @as(@Vector(2, i32), [runtime value])
1388// @as(@Vector(2, i32), [runtime value])
1389// @as(@Vector(2, i32), [runtime value])
1390// @as(@Vector(2, i32), undefined)
1391// @as(@Vector(2, i32), undefined)
1392// @as(@Vector(2, i32), undefined)
1393// @as(@Vector(2, i32), undefined)
1394// @as(@Vector(2, i32), undefined)
1395// @as(i32, undefined)
1396// @as(i32, undefined)
1397// @as(@Vector(2, i32), [runtime value])
1398// @as(@Vector(2, i32), [runtime value])
1399// @as(@Vector(2, i32), undefined)
1400// @as(@Vector(2, i32), [runtime value])
1401// @as(@Vector(2, i32), [runtime value])
1402// @as(@Vector(2, i32), [runtime value])
1403// @as(@Vector(2, i32), undefined)
1404// @as(@Vector(2, i32), [runtime value])
1405// @as(@Vector(2, i32), [runtime value])
1406// @as(@Vector(2, i32), [runtime value])
1407// @as(@Vector(2, i32), undefined)
1408// @as(@Vector(2, i32), undefined)
1409// @as(@Vector(2, i32), undefined)
1410// @as(@Vector(2, i32), undefined)
1411// @as(@Vector(2, i32), undefined)
1412// @as(i32, undefined)
1413// @as(i32, undefined)
1414// @as(@Vector(2, i32), [runtime value])
1415// @as(@Vector(2, i32), [runtime value])
1416// @as(@Vector(2, i32), undefined)
1417// @as(@Vector(2, i32), [runtime value])
1418// @as(@Vector(2, i32), [runtime value])
1419// @as(@Vector(2, i32), [runtime value])
1420// @as(@Vector(2, i32), undefined)
1421// @as(@Vector(2, i32), [runtime value])
1422// @as(@Vector(2, i32), [runtime value])
1423// @as(@Vector(2, i32), [runtime value])
1424// @as(@Vector(2, i32), undefined)
1425// @as(@Vector(2, i32), undefined)
1426// @as(@Vector(2, i32), undefined)
1427// @as(@Vector(2, i32), undefined)
1428// @as(@Vector(2, i32), undefined)
1429// @as(i32, undefined)
1430// @as(i32, undefined)
1431// @as(@Vector(2, i32), [runtime value])
1432// @as(@Vector(2, i32), [runtime value])
1433// @as(@Vector(2, i32), undefined)
1434// @as(@Vector(2, i32), [runtime value])
1435// @as(@Vector(2, i32), [runtime value])
1436// @as(@Vector(2, i32), [runtime value])
1437// @as(@Vector(2, i32), undefined)
1438// @as(@Vector(2, i32), [runtime value])
1439// @as(@Vector(2, i32), [runtime value])
1440// @as(@Vector(2, i32), [runtime value])
1441// @as(@Vector(2, i32), undefined)
1442// @as(@Vector(2, i32), undefined)
1443// @as(@Vector(2, i32), undefined)
1444// @as(@Vector(2, i32), undefined)
1445// @as(@Vector(2, i32), undefined)
1446// @as(i32, undefined)
1447// @as(i32, undefined)
1448// @as(@Vector(2, i32), [runtime value])
1449// @as(@Vector(2, i32), [runtime value])
1450// @as(@Vector(2, i32), undefined)
1451// @as(@Vector(2, i32), [runtime value])
1452// @as(@Vector(2, i32), [runtime value])
1453// @as(@Vector(2, i32), [runtime value])
1454// @as(@Vector(2, i32), undefined)
1455// @as(@Vector(2, i32), [runtime value])
1456// @as(@Vector(2, i32), [runtime value])
1457// @as(@Vector(2, i32), [runtime value])
1458// @as(@Vector(2, i32), undefined)
1459// @as(@Vector(2, i32), undefined)
1460// @as(@Vector(2, i32), undefined)
1461// @as(@Vector(2, i32), undefined)
1462// @as(@Vector(2, i32), undefined)
1463// @as(i32, [runtime value])
1464// @as(i32, [runtime value])
1465// @as(@Vector(2, i32), [runtime value])
1466// @as(@Vector(2, i32), [runtime value])
1467// @as(@Vector(2, i32), [runtime value])
1468// @as(@Vector(2, i32), [runtime value])
1469// @as(@Vector(2, i32), [runtime value])
1470// @as(@Vector(2, i32), [runtime value])
1471// @as(@Vector(2, i32), [runtime value])
1472// @as(@Vector(2, i32), [runtime value])
1473// @as(@Vector(2, i32), [runtime value])
1474// @as(@Vector(2, i32), [runtime value])
1475// @as(@Vector(2, i32), [runtime value])
1476// @as(@Vector(2, i32), [runtime value])
1477// @as(@Vector(2, i32), [runtime value])
1478// @as(@Vector(2, i32), [runtime value])
1479// @as(@Vector(2, i32), undefined)
1480// @as(i32, undefined)
1481// @as(@Vector(2, i32), undefined)
1482// @as(i32, undefined)
1483// @as(i32, undefined)
1484// @as(@Vector(2, i32), undefined)
1485// @as(@Vector(2, i32), undefined)
1486// @as(i32, undefined)
1487// @as(@Vector(2, i32), undefined)
1488// @as(u500, undefined)
1489// @as(u500, undefined)
1490// @as(@Vector(2, u500), .{ 6, undefined })
1491// @as(@Vector(2, u500), .{ undefined, 6 })
1492// @as(@Vector(2, u500), undefined)
1493// @as(@Vector(2, u500), .{ 6, undefined })
1494// @as(@Vector(2, u500), .{ 6, undefined })
1495// @as(@Vector(2, u500), undefined)
1496// @as(@Vector(2, u500), undefined)
1497// @as(@Vector(2, u500), .{ undefined, 6 })
1498// @as(@Vector(2, u500), undefined)
1499// @as(@Vector(2, u500), .{ undefined, 6 })
1500// @as(@Vector(2, u500), undefined)
1501// @as(@Vector(2, u500), undefined)
1502// @as(@Vector(2, u500), undefined)
1503// @as(@Vector(2, u500), undefined)
1504// @as(@Vector(2, u500), undefined)
1505// @as(u500, undefined)
1506// @as(u500, undefined)
1507// @as(@Vector(2, u500), .{ 6, undefined })
1508// @as(@Vector(2, u500), .{ undefined, 6 })
1509// @as(@Vector(2, u500), undefined)
1510// @as(@Vector(2, u500), .{ 6, undefined })
1511// @as(@Vector(2, u500), .{ 6, undefined })
1512// @as(@Vector(2, u500), undefined)
1513// @as(@Vector(2, u500), undefined)
1514// @as(@Vector(2, u500), .{ undefined, 6 })
1515// @as(@Vector(2, u500), undefined)
1516// @as(@Vector(2, u500), .{ undefined, 6 })
1517// @as(@Vector(2, u500), undefined)
1518// @as(@Vector(2, u500), undefined)
1519// @as(@Vector(2, u500), undefined)
1520// @as(@Vector(2, u500), undefined)
1521// @as(@Vector(2, u500), undefined)
1522// @as(u500, undefined)
1523// @as(u500, undefined)
1524// @as(@Vector(2, u500), .{ 0, undefined })
1525// @as(@Vector(2, u500), .{ undefined, 0 })
1526// @as(@Vector(2, u500), undefined)
1527// @as(@Vector(2, u500), .{ 0, undefined })
1528// @as(@Vector(2, u500), .{ 0, undefined })
1529// @as(@Vector(2, u500), undefined)
1530// @as(@Vector(2, u500), undefined)
1531// @as(@Vector(2, u500), .{ undefined, 0 })
1532// @as(@Vector(2, u500), undefined)
1533// @as(@Vector(2, u500), .{ undefined, 0 })
1534// @as(@Vector(2, u500), undefined)
1535// @as(@Vector(2, u500), undefined)
1536// @as(@Vector(2, u500), undefined)
1537// @as(@Vector(2, u500), undefined)
1538// @as(@Vector(2, u500), undefined)
1539// @as(u500, undefined)
1540// @as(u500, undefined)
1541// @as(@Vector(2, u500), .{ 0, undefined })
1542// @as(@Vector(2, u500), .{ undefined, 0 })
1543// @as(@Vector(2, u500), undefined)
1544// @as(@Vector(2, u500), .{ 0, undefined })
1545// @as(@Vector(2, u500), .{ 0, undefined })
1546// @as(@Vector(2, u500), undefined)
1547// @as(@Vector(2, u500), undefined)
1548// @as(@Vector(2, u500), .{ undefined, 0 })
1549// @as(@Vector(2, u500), undefined)
1550// @as(@Vector(2, u500), .{ undefined, 0 })
1551// @as(@Vector(2, u500), undefined)
1552// @as(@Vector(2, u500), undefined)
1553// @as(@Vector(2, u500), undefined)
1554// @as(@Vector(2, u500), undefined)
1555// @as(@Vector(2, u500), undefined)
1556// @as(u500, undefined)
1557// @as(u500, undefined)
1558// @as(@Vector(2, u500), .{ 9, undefined })
1559// @as(@Vector(2, u500), .{ undefined, 9 })
1560// @as(@Vector(2, u500), undefined)
1561// @as(@Vector(2, u500), .{ 9, undefined })
1562// @as(@Vector(2, u500), .{ 9, undefined })
1563// @as(@Vector(2, u500), undefined)
1564// @as(@Vector(2, u500), undefined)
1565// @as(@Vector(2, u500), .{ undefined, 9 })
1566// @as(@Vector(2, u500), undefined)
1567// @as(@Vector(2, u500), .{ undefined, 9 })
1568// @as(@Vector(2, u500), undefined)
1569// @as(@Vector(2, u500), undefined)
1570// @as(@Vector(2, u500), undefined)
1571// @as(@Vector(2, u500), undefined)
1572// @as(@Vector(2, u500), undefined)
1573// @as(u500, undefined)
1574// @as(u500, undefined)
1575// @as(@Vector(2, u500), .{ 9, undefined })
1576// @as(@Vector(2, u500), .{ undefined, 9 })
1577// @as(@Vector(2, u500), undefined)
1578// @as(@Vector(2, u500), .{ 9, undefined })
1579// @as(@Vector(2, u500), .{ 9, undefined })
1580// @as(@Vector(2, u500), undefined)
1581// @as(@Vector(2, u500), undefined)
1582// @as(@Vector(2, u500), .{ undefined, 9 })
1583// @as(@Vector(2, u500), undefined)
1584// @as(@Vector(2, u500), .{ undefined, 9 })
1585// @as(@Vector(2, u500), undefined)
1586// @as(@Vector(2, u500), undefined)
1587// @as(@Vector(2, u500), undefined)
1588// @as(@Vector(2, u500), undefined)
1589// @as(@Vector(2, u500), undefined)
1590// @as(u500, undefined)
1591// @as(u500, undefined)
1592// @as(@Vector(2, u500), .{ 24, undefined })
1593// @as(@Vector(2, u500), .{ undefined, 24 })
1594// @as(@Vector(2, u500), undefined)
1595// @as(@Vector(2, u500), .{ 24, undefined })
1596// @as(@Vector(2, u500), .{ 24, undefined })
1597// @as(@Vector(2, u500), undefined)
1598// @as(@Vector(2, u500), undefined)
1599// @as(@Vector(2, u500), .{ undefined, 24 })
1600// @as(@Vector(2, u500), undefined)
1601// @as(@Vector(2, u500), .{ undefined, 24 })
1602// @as(@Vector(2, u500), undefined)
1603// @as(@Vector(2, u500), undefined)
1604// @as(@Vector(2, u500), undefined)
1605// @as(@Vector(2, u500), undefined)
1606// @as(@Vector(2, u500), undefined)
1607// @as(u500, undefined)
1608// @as(u500, undefined)
1609// @as(@Vector(2, u500), .{ 0, undefined })
1610// @as(@Vector(2, u500), .{ undefined, 0 })
1611// @as(@Vector(2, u500), undefined)
1612// @as(@Vector(2, u500), .{ 0, undefined })
1613// @as(@Vector(2, u500), .{ 0, undefined })
1614// @as(@Vector(2, u500), undefined)
1615// @as(@Vector(2, u500), undefined)
1616// @as(@Vector(2, u500), .{ undefined, 0 })
1617// @as(@Vector(2, u500), undefined)
1618// @as(@Vector(2, u500), .{ undefined, 0 })
1619// @as(@Vector(2, u500), undefined)
1620// @as(@Vector(2, u500), undefined)
1621// @as(@Vector(2, u500), undefined)
1622// @as(@Vector(2, u500), undefined)
1623// @as(@Vector(2, u500), undefined)
1624// @as(u500, undefined)
1625// @as(@Vector(2, u500), undefined)
1626// @as(u500, undefined)
1627// @as(u500, undefined)
1628// @as(@Vector(2, u500), undefined)
1629// @as(@Vector(2, u500), undefined)
1630// @as(u1, undefined)
1631// @as(@Vector(2, u1), .{ 1, undefined })
1632// @as(@Vector(2, u1), .{ undefined, 1 })
1633// @as(@Vector(2, u1), undefined)
1634// @as(u500, undefined)
1635// @as(@Vector(2, u500), undefined)
1636// @as(u500, undefined)
1637// @as(u500, undefined)
1638// @as(@Vector(2, u500), [runtime value])
1639// @as(@Vector(2, u500), [runtime value])
1640// @as(@Vector(2, u500), undefined)
1641// @as(@Vector(2, u500), [runtime value])
1642// @as(@Vector(2, u500), [runtime value])
1643// @as(@Vector(2, u500), [runtime value])
1644// @as(@Vector(2, u500), undefined)
1645// @as(@Vector(2, u500), [runtime value])
1646// @as(@Vector(2, u500), [runtime value])
1647// @as(@Vector(2, u500), [runtime value])
1648// @as(@Vector(2, u500), undefined)
1649// @as(@Vector(2, u500), undefined)
1650// @as(@Vector(2, u500), undefined)
1651// @as(@Vector(2, u500), undefined)
1652// @as(@Vector(2, u500), undefined)
1653// @as(u500, undefined)
1654// @as(u500, undefined)
1655// @as(@Vector(2, u500), [runtime value])
1656// @as(@Vector(2, u500), [runtime value])
1657// @as(@Vector(2, u500), undefined)
1658// @as(@Vector(2, u500), [runtime value])
1659// @as(@Vector(2, u500), [runtime value])
1660// @as(@Vector(2, u500), [runtime value])
1661// @as(@Vector(2, u500), undefined)
1662// @as(@Vector(2, u500), [runtime value])
1663// @as(@Vector(2, u500), [runtime value])
1664// @as(@Vector(2, u500), [runtime value])
1665// @as(@Vector(2, u500), undefined)
1666// @as(@Vector(2, u500), undefined)
1667// @as(@Vector(2, u500), undefined)
1668// @as(@Vector(2, u500), undefined)
1669// @as(@Vector(2, u500), undefined)
1670// @as(u500, undefined)
1671// @as(u500, undefined)
1672// @as(@Vector(2, u500), [runtime value])
1673// @as(@Vector(2, u500), [runtime value])
1674// @as(@Vector(2, u500), undefined)
1675// @as(@Vector(2, u500), [runtime value])
1676// @as(@Vector(2, u500), [runtime value])
1677// @as(@Vector(2, u500), [runtime value])
1678// @as(@Vector(2, u500), undefined)
1679// @as(@Vector(2, u500), [runtime value])
1680// @as(@Vector(2, u500), [runtime value])
1681// @as(@Vector(2, u500), [runtime value])
1682// @as(@Vector(2, u500), undefined)
1683// @as(@Vector(2, u500), undefined)
1684// @as(@Vector(2, u500), undefined)
1685// @as(@Vector(2, u500), undefined)
1686// @as(@Vector(2, u500), undefined)
1687// @as(u500, undefined)
1688// @as(u500, undefined)
1689// @as(@Vector(2, u500), [runtime value])
1690// @as(@Vector(2, u500), [runtime value])
1691// @as(@Vector(2, u500), undefined)
1692// @as(@Vector(2, u500), [runtime value])
1693// @as(@Vector(2, u500), [runtime value])
1694// @as(@Vector(2, u500), [runtime value])
1695// @as(@Vector(2, u500), undefined)
1696// @as(@Vector(2, u500), [runtime value])
1697// @as(@Vector(2, u500), [runtime value])
1698// @as(@Vector(2, u500), [runtime value])
1699// @as(@Vector(2, u500), undefined)
1700// @as(@Vector(2, u500), undefined)
1701// @as(@Vector(2, u500), undefined)
1702// @as(@Vector(2, u500), undefined)
1703// @as(@Vector(2, u500), undefined)
1704// @as(u500, undefined)
1705// @as(u500, undefined)
1706// @as(@Vector(2, u500), [runtime value])
1707// @as(@Vector(2, u500), [runtime value])
1708// @as(@Vector(2, u500), undefined)
1709// @as(@Vector(2, u500), [runtime value])
1710// @as(@Vector(2, u500), [runtime value])
1711// @as(@Vector(2, u500), [runtime value])
1712// @as(@Vector(2, u500), undefined)
1713// @as(@Vector(2, u500), [runtime value])
1714// @as(@Vector(2, u500), [runtime value])
1715// @as(@Vector(2, u500), [runtime value])
1716// @as(@Vector(2, u500), undefined)
1717// @as(@Vector(2, u500), undefined)
1718// @as(@Vector(2, u500), undefined)
1719// @as(@Vector(2, u500), undefined)
1720// @as(@Vector(2, u500), undefined)
1721// @as(u500, undefined)
1722// @as(u500, undefined)
1723// @as(@Vector(2, u500), [runtime value])
1724// @as(@Vector(2, u500), [runtime value])
1725// @as(@Vector(2, u500), undefined)
1726// @as(@Vector(2, u500), [runtime value])
1727// @as(@Vector(2, u500), [runtime value])
1728// @as(@Vector(2, u500), [runtime value])
1729// @as(@Vector(2, u500), undefined)
1730// @as(@Vector(2, u500), [runtime value])
1731// @as(@Vector(2, u500), [runtime value])
1732// @as(@Vector(2, u500), [runtime value])
1733// @as(@Vector(2, u500), undefined)
1734// @as(@Vector(2, u500), undefined)
1735// @as(@Vector(2, u500), undefined)
1736// @as(@Vector(2, u500), undefined)
1737// @as(@Vector(2, u500), undefined)
1738// @as(u500, undefined)
1739// @as(u500, undefined)
1740// @as(@Vector(2, u500), [runtime value])
1741// @as(@Vector(2, u500), [runtime value])
1742// @as(@Vector(2, u500), undefined)
1743// @as(@Vector(2, u500), [runtime value])
1744// @as(@Vector(2, u500), [runtime value])
1745// @as(@Vector(2, u500), [runtime value])
1746// @as(@Vector(2, u500), undefined)
1747// @as(@Vector(2, u500), [runtime value])
1748// @as(@Vector(2, u500), [runtime value])
1749// @as(@Vector(2, u500), [runtime value])
1750// @as(@Vector(2, u500), undefined)
1751// @as(@Vector(2, u500), undefined)
1752// @as(@Vector(2, u500), undefined)
1753// @as(@Vector(2, u500), undefined)
1754// @as(@Vector(2, u500), undefined)
1755// @as(u500, [runtime value])
1756// @as(u500, [runtime value])
1757// @as(@Vector(2, u500), [runtime value])
1758// @as(@Vector(2, u500), [runtime value])
1759// @as(@Vector(2, u500), [runtime value])
1760// @as(@Vector(2, u500), [runtime value])
1761// @as(@Vector(2, u500), [runtime value])
1762// @as(@Vector(2, u500), [runtime value])
1763// @as(@Vector(2, u500), [runtime value])
1764// @as(@Vector(2, u500), [runtime value])
1765// @as(@Vector(2, u500), [runtime value])
1766// @as(@Vector(2, u500), [runtime value])
1767// @as(@Vector(2, u500), [runtime value])
1768// @as(@Vector(2, u500), [runtime value])
1769// @as(@Vector(2, u500), [runtime value])
1770// @as(@Vector(2, u500), [runtime value])
1771// @as(@Vector(2, u500), undefined)
1772// @as(u500, undefined)
1773// @as(@Vector(2, u500), undefined)
1774// @as(u500, undefined)
1775// @as(u500, undefined)
1776// @as(@Vector(2, u500), undefined)
1777// @as(@Vector(2, u500), undefined)
1778// @as(u1, undefined)
1779// @as(@Vector(2, u1), [runtime value])
1780// @as(@Vector(2, u1), [runtime value])
1781// @as(@Vector(2, u1), undefined)
1782// @as(u500, undefined)
1783// @as(@Vector(2, u500), undefined)
1784// @as(i500, undefined)
1785// @as(i500, undefined)
1786// @as(@Vector(2, i500), .{ 6, undefined })
1787// @as(@Vector(2, i500), .{ undefined, 6 })
1788// @as(@Vector(2, i500), undefined)
1789// @as(@Vector(2, i500), .{ 6, undefined })
1790// @as(@Vector(2, i500), .{ 6, undefined })
1791// @as(@Vector(2, i500), undefined)
1792// @as(@Vector(2, i500), undefined)
1793// @as(@Vector(2, i500), .{ undefined, 6 })
1794// @as(@Vector(2, i500), undefined)
1795// @as(@Vector(2, i500), .{ undefined, 6 })
1796// @as(@Vector(2, i500), undefined)
1797// @as(@Vector(2, i500), undefined)
1798// @as(@Vector(2, i500), undefined)
1799// @as(@Vector(2, i500), undefined)
1800// @as(@Vector(2, i500), undefined)
1801// @as(i500, undefined)
1802// @as(i500, undefined)
1803// @as(@Vector(2, i500), .{ 6, undefined })
1804// @as(@Vector(2, i500), .{ undefined, 6 })
1805// @as(@Vector(2, i500), undefined)
1806// @as(@Vector(2, i500), .{ 6, undefined })
1807// @as(@Vector(2, i500), .{ 6, undefined })
1808// @as(@Vector(2, i500), undefined)
1809// @as(@Vector(2, i500), undefined)
1810// @as(@Vector(2, i500), .{ undefined, 6 })
1811// @as(@Vector(2, i500), undefined)
1812// @as(@Vector(2, i500), .{ undefined, 6 })
1813// @as(@Vector(2, i500), undefined)
1814// @as(@Vector(2, i500), undefined)
1815// @as(@Vector(2, i500), undefined)
1816// @as(@Vector(2, i500), undefined)
1817// @as(@Vector(2, i500), undefined)
1818// @as(i500, undefined)
1819// @as(i500, undefined)
1820// @as(@Vector(2, i500), .{ 0, undefined })
1821// @as(@Vector(2, i500), .{ undefined, 0 })
1822// @as(@Vector(2, i500), undefined)
1823// @as(@Vector(2, i500), .{ 0, undefined })
1824// @as(@Vector(2, i500), .{ 0, undefined })
1825// @as(@Vector(2, i500), undefined)
1826// @as(@Vector(2, i500), undefined)
1827// @as(@Vector(2, i500), .{ undefined, 0 })
1828// @as(@Vector(2, i500), undefined)
1829// @as(@Vector(2, i500), .{ undefined, 0 })
1830// @as(@Vector(2, i500), undefined)
1831// @as(@Vector(2, i500), undefined)
1832// @as(@Vector(2, i500), undefined)
1833// @as(@Vector(2, i500), undefined)
1834// @as(@Vector(2, i500), undefined)
1835// @as(i500, undefined)
1836// @as(i500, undefined)
1837// @as(@Vector(2, i500), .{ 0, undefined })
1838// @as(@Vector(2, i500), .{ undefined, 0 })
1839// @as(@Vector(2, i500), undefined)
1840// @as(@Vector(2, i500), .{ 0, undefined })
1841// @as(@Vector(2, i500), .{ 0, undefined })
1842// @as(@Vector(2, i500), undefined)
1843// @as(@Vector(2, i500), undefined)
1844// @as(@Vector(2, i500), .{ undefined, 0 })
1845// @as(@Vector(2, i500), undefined)
1846// @as(@Vector(2, i500), .{ undefined, 0 })
1847// @as(@Vector(2, i500), undefined)
1848// @as(@Vector(2, i500), undefined)
1849// @as(@Vector(2, i500), undefined)
1850// @as(@Vector(2, i500), undefined)
1851// @as(@Vector(2, i500), undefined)
1852// @as(i500, undefined)
1853// @as(i500, undefined)
1854// @as(@Vector(2, i500), .{ 9, undefined })
1855// @as(@Vector(2, i500), .{ undefined, 9 })
1856// @as(@Vector(2, i500), undefined)
1857// @as(@Vector(2, i500), .{ 9, undefined })
1858// @as(@Vector(2, i500), .{ 9, undefined })
1859// @as(@Vector(2, i500), undefined)
1860// @as(@Vector(2, i500), undefined)
1861// @as(@Vector(2, i500), .{ undefined, 9 })
1862// @as(@Vector(2, i500), undefined)
1863// @as(@Vector(2, i500), .{ undefined, 9 })
1864// @as(@Vector(2, i500), undefined)
1865// @as(@Vector(2, i500), undefined)
1866// @as(@Vector(2, i500), undefined)
1867// @as(@Vector(2, i500), undefined)
1868// @as(@Vector(2, i500), undefined)
1869// @as(i500, undefined)
1870// @as(i500, undefined)
1871// @as(@Vector(2, i500), .{ 9, undefined })
1872// @as(@Vector(2, i500), .{ undefined, 9 })
1873// @as(@Vector(2, i500), undefined)
1874// @as(@Vector(2, i500), .{ 9, undefined })
1875// @as(@Vector(2, i500), .{ 9, undefined })
1876// @as(@Vector(2, i500), undefined)
1877// @as(@Vector(2, i500), undefined)
1878// @as(@Vector(2, i500), .{ undefined, 9 })
1879// @as(@Vector(2, i500), undefined)
1880// @as(@Vector(2, i500), .{ undefined, 9 })
1881// @as(@Vector(2, i500), undefined)
1882// @as(@Vector(2, i500), undefined)
1883// @as(@Vector(2, i500), undefined)
1884// @as(@Vector(2, i500), undefined)
1885// @as(@Vector(2, i500), undefined)
1886// @as(i500, undefined)
1887// @as(i500, undefined)
1888// @as(@Vector(2, i500), .{ 0, undefined })
1889// @as(@Vector(2, i500), .{ undefined, 0 })
1890// @as(@Vector(2, i500), undefined)
1891// @as(@Vector(2, i500), .{ 0, undefined })
1892// @as(@Vector(2, i500), .{ 0, undefined })
1893// @as(@Vector(2, i500), undefined)
1894// @as(@Vector(2, i500), undefined)
1895// @as(@Vector(2, i500), .{ undefined, 0 })
1896// @as(@Vector(2, i500), undefined)
1897// @as(@Vector(2, i500), .{ undefined, 0 })
1898// @as(@Vector(2, i500), undefined)
1899// @as(@Vector(2, i500), undefined)
1900// @as(@Vector(2, i500), undefined)
1901// @as(@Vector(2, i500), undefined)
1902// @as(@Vector(2, i500), undefined)
1903// @as(i500, undefined)
1904// @as(@Vector(2, i500), undefined)
1905// @as(i500, undefined)
1906// @as(i500, undefined)
1907// @as(@Vector(2, i500), undefined)
1908// @as(@Vector(2, i500), undefined)
1909// @as(i500, undefined)
1910// @as(@Vector(2, i500), undefined)
1911// @as(i500, undefined)
1912// @as(i500, undefined)
1913// @as(@Vector(2, i500), [runtime value])
1914// @as(@Vector(2, i500), [runtime value])
1915// @as(@Vector(2, i500), undefined)
1916// @as(@Vector(2, i500), [runtime value])
1917// @as(@Vector(2, i500), [runtime value])
1918// @as(@Vector(2, i500), [runtime value])
1919// @as(@Vector(2, i500), undefined)
1920// @as(@Vector(2, i500), [runtime value])
1921// @as(@Vector(2, i500), [runtime value])
1922// @as(@Vector(2, i500), [runtime value])
1923// @as(@Vector(2, i500), undefined)
1924// @as(@Vector(2, i500), undefined)
1925// @as(@Vector(2, i500), undefined)
1926// @as(@Vector(2, i500), undefined)
1927// @as(@Vector(2, i500), undefined)
1928// @as(i500, undefined)
1929// @as(i500, undefined)
1930// @as(@Vector(2, i500), [runtime value])
1931// @as(@Vector(2, i500), [runtime value])
1932// @as(@Vector(2, i500), undefined)
1933// @as(@Vector(2, i500), [runtime value])
1934// @as(@Vector(2, i500), [runtime value])
1935// @as(@Vector(2, i500), [runtime value])
1936// @as(@Vector(2, i500), undefined)
1937// @as(@Vector(2, i500), [runtime value])
1938// @as(@Vector(2, i500), [runtime value])
1939// @as(@Vector(2, i500), [runtime value])
1940// @as(@Vector(2, i500), undefined)
1941// @as(@Vector(2, i500), undefined)
1942// @as(@Vector(2, i500), undefined)
1943// @as(@Vector(2, i500), undefined)
1944// @as(@Vector(2, i500), undefined)
1945// @as(i500, undefined)
1946// @as(i500, undefined)
1947// @as(@Vector(2, i500), [runtime value])
1948// @as(@Vector(2, i500), [runtime value])
1949// @as(@Vector(2, i500), undefined)
1950// @as(@Vector(2, i500), [runtime value])
1951// @as(@Vector(2, i500), [runtime value])
1952// @as(@Vector(2, i500), [runtime value])
1953// @as(@Vector(2, i500), undefined)
1954// @as(@Vector(2, i500), [runtime value])
1955// @as(@Vector(2, i500), [runtime value])
1956// @as(@Vector(2, i500), [runtime value])
1957// @as(@Vector(2, i500), undefined)
1958// @as(@Vector(2, i500), undefined)
1959// @as(@Vector(2, i500), undefined)
1960// @as(@Vector(2, i500), undefined)
1961// @as(@Vector(2, i500), undefined)
1962// @as(i500, undefined)
1963// @as(i500, undefined)
1964// @as(@Vector(2, i500), [runtime value])
1965// @as(@Vector(2, i500), [runtime value])
1966// @as(@Vector(2, i500), undefined)
1967// @as(@Vector(2, i500), [runtime value])
1968// @as(@Vector(2, i500), [runtime value])
1969// @as(@Vector(2, i500), [runtime value])
1970// @as(@Vector(2, i500), undefined)
1971// @as(@Vector(2, i500), [runtime value])
1972// @as(@Vector(2, i500), [runtime value])
1973// @as(@Vector(2, i500), [runtime value])
1974// @as(@Vector(2, i500), undefined)
1975// @as(@Vector(2, i500), undefined)
1976// @as(@Vector(2, i500), undefined)
1977// @as(@Vector(2, i500), undefined)
1978// @as(@Vector(2, i500), undefined)
1979// @as(i500, undefined)
1980// @as(i500, undefined)
1981// @as(@Vector(2, i500), [runtime value])
1982// @as(@Vector(2, i500), [runtime value])
1983// @as(@Vector(2, i500), undefined)
1984// @as(@Vector(2, i500), [runtime value])
1985// @as(@Vector(2, i500), [runtime value])
1986// @as(@Vector(2, i500), [runtime value])
1987// @as(@Vector(2, i500), undefined)
1988// @as(@Vector(2, i500), [runtime value])
1989// @as(@Vector(2, i500), [runtime value])
1990// @as(@Vector(2, i500), [runtime value])
1991// @as(@Vector(2, i500), undefined)
1992// @as(@Vector(2, i500), undefined)
1993// @as(@Vector(2, i500), undefined)
1994// @as(@Vector(2, i500), undefined)
1995// @as(@Vector(2, i500), undefined)
1996// @as(i500, undefined)
1997// @as(i500, undefined)
1998// @as(@Vector(2, i500), [runtime value])
1999// @as(@Vector(2, i500), [runtime value])
2000// @as(@Vector(2, i500), undefined)
2001// @as(@Vector(2, i500), [runtime value])
2002// @as(@Vector(2, i500), [runtime value])
2003// @as(@Vector(2, i500), [runtime value])
2004// @as(@Vector(2, i500), undefined)
2005// @as(@Vector(2, i500), [runtime value])
2006// @as(@Vector(2, i500), [runtime value])
2007// @as(@Vector(2, i500), [runtime value])
2008// @as(@Vector(2, i500), undefined)
2009// @as(@Vector(2, i500), undefined)
2010// @as(@Vector(2, i500), undefined)
2011// @as(@Vector(2, i500), undefined)
2012// @as(@Vector(2, i500), undefined)
2013// @as(i500, [runtime value])
2014// @as(i500, [runtime value])
2015// @as(@Vector(2, i500), [runtime value])
2016// @as(@Vector(2, i500), [runtime value])
2017// @as(@Vector(2, i500), [runtime value])
2018// @as(@Vector(2, i500), [runtime value])
2019// @as(@Vector(2, i500), [runtime value])
2020// @as(@Vector(2, i500), [runtime value])
2021// @as(@Vector(2, i500), [runtime value])
2022// @as(@Vector(2, i500), [runtime value])
2023// @as(@Vector(2, i500), [runtime value])
2024// @as(@Vector(2, i500), [runtime value])
2025// @as(@Vector(2, i500), [runtime value])
2026// @as(@Vector(2, i500), [runtime value])
2027// @as(@Vector(2, i500), [runtime value])
2028// @as(@Vector(2, i500), [runtime value])
2029// @as(@Vector(2, i500), undefined)
2030// @as(i500, undefined)
2031// @as(@Vector(2, i500), undefined)
2032// @as(i500, undefined)
2033// @as(i500, undefined)
2034// @as(@Vector(2, i500), undefined)
2035// @as(@Vector(2, i500), undefined)
2036// @as(i500, undefined)
2037// @as(@Vector(2, i500), undefined)
2038// @as(f16, undefined)
2039// @as(f16, undefined)
2040// @as(@Vector(2, f16), .{ 6, undefined })
2041// @as(@Vector(2, f16), .{ undefined, 6 })
2042// @as(@Vector(2, f16), undefined)
2043// @as(@Vector(2, f16), .{ 6, undefined })
2044// @as(@Vector(2, f16), .{ 6, undefined })
2045// @as(@Vector(2, f16), undefined)
2046// @as(@Vector(2, f16), undefined)
2047// @as(@Vector(2, f16), .{ undefined, 6 })
2048// @as(@Vector(2, f16), undefined)
2049// @as(@Vector(2, f16), .{ undefined, 6 })
2050// @as(@Vector(2, f16), undefined)
2051// @as(@Vector(2, f16), undefined)
2052// @as(@Vector(2, f16), undefined)
2053// @as(@Vector(2, f16), undefined)
2054// @as(@Vector(2, f16), undefined)
2055// @as(f16, undefined)
2056// @as(f16, undefined)
2057// @as(@Vector(2, f16), .{ 0, undefined })
2058// @as(@Vector(2, f16), .{ undefined, 0 })
2059// @as(@Vector(2, f16), undefined)
2060// @as(@Vector(2, f16), .{ 0, undefined })
2061// @as(@Vector(2, f16), .{ 0, undefined })
2062// @as(@Vector(2, f16), undefined)
2063// @as(@Vector(2, f16), undefined)
2064// @as(@Vector(2, f16), .{ undefined, 0 })
2065// @as(@Vector(2, f16), undefined)
2066// @as(@Vector(2, f16), .{ undefined, 0 })
2067// @as(@Vector(2, f16), undefined)
2068// @as(@Vector(2, f16), undefined)
2069// @as(@Vector(2, f16), undefined)
2070// @as(@Vector(2, f16), undefined)
2071// @as(@Vector(2, f16), undefined)
2072// @as(f16, undefined)
2073// @as(f16, undefined)
2074// @as(@Vector(2, f16), .{ 9, undefined })
2075// @as(@Vector(2, f16), .{ undefined, 9 })
2076// @as(@Vector(2, f16), undefined)
2077// @as(@Vector(2, f16), .{ 9, undefined })
2078// @as(@Vector(2, f16), .{ 9, undefined })
2079// @as(@Vector(2, f16), undefined)
2080// @as(@Vector(2, f16), undefined)
2081// @as(@Vector(2, f16), .{ undefined, 9 })
2082// @as(@Vector(2, f16), undefined)
2083// @as(@Vector(2, f16), .{ undefined, 9 })
2084// @as(@Vector(2, f16), undefined)
2085// @as(@Vector(2, f16), undefined)
2086// @as(@Vector(2, f16), undefined)
2087// @as(@Vector(2, f16), undefined)
2088// @as(@Vector(2, f16), undefined)
2089// @as(f16, undefined)
2090// @as(@Vector(2, f16), .{ -3, undefined })
2091// @as(@Vector(2, f16), .{ undefined, -3 })
2092// @as(@Vector(2, f16), undefined)
2093// @as(f16, undefined)
2094// @as(f16, undefined)
2095// @as(@Vector(2, f16), [runtime value])
2096// @as(@Vector(2, f16), [runtime value])
2097// @as(@Vector(2, f16), undefined)
2098// @as(@Vector(2, f16), [runtime value])
2099// @as(@Vector(2, f16), [runtime value])
2100// @as(@Vector(2, f16), [runtime value])
2101// @as(@Vector(2, f16), undefined)
2102// @as(@Vector(2, f16), [runtime value])
2103// @as(@Vector(2, f16), [runtime value])
2104// @as(@Vector(2, f16), [runtime value])
2105// @as(@Vector(2, f16), undefined)
2106// @as(@Vector(2, f16), undefined)
2107// @as(@Vector(2, f16), undefined)
2108// @as(@Vector(2, f16), undefined)
2109// @as(@Vector(2, f16), undefined)
2110// @as(f16, undefined)
2111// @as(f16, undefined)
2112// @as(@Vector(2, f16), [runtime value])
2113// @as(@Vector(2, f16), [runtime value])
2114// @as(@Vector(2, f16), undefined)
2115// @as(@Vector(2, f16), [runtime value])
2116// @as(@Vector(2, f16), [runtime value])
2117// @as(@Vector(2, f16), [runtime value])
2118// @as(@Vector(2, f16), undefined)
2119// @as(@Vector(2, f16), [runtime value])
2120// @as(@Vector(2, f16), [runtime value])
2121// @as(@Vector(2, f16), [runtime value])
2122// @as(@Vector(2, f16), undefined)
2123// @as(@Vector(2, f16), undefined)
2124// @as(@Vector(2, f16), undefined)
2125// @as(@Vector(2, f16), undefined)
2126// @as(@Vector(2, f16), undefined)
2127// @as(f16, undefined)
2128// @as(f16, undefined)
2129// @as(@Vector(2, f16), [runtime value])
2130// @as(@Vector(2, f16), [runtime value])
2131// @as(@Vector(2, f16), undefined)
2132// @as(@Vector(2, f16), [runtime value])
2133// @as(@Vector(2, f16), [runtime value])
2134// @as(@Vector(2, f16), [runtime value])
2135// @as(@Vector(2, f16), undefined)
2136// @as(@Vector(2, f16), [runtime value])
2137// @as(@Vector(2, f16), [runtime value])
2138// @as(@Vector(2, f16), [runtime value])
2139// @as(@Vector(2, f16), undefined)
2140// @as(@Vector(2, f16), undefined)
2141// @as(@Vector(2, f16), undefined)
2142// @as(@Vector(2, f16), undefined)
2143// @as(@Vector(2, f16), undefined)
2144// @as(f16, undefined)
2145// @as(@Vector(2, f16), [runtime value])
2146// @as(@Vector(2, f16), [runtime value])
2147// @as(@Vector(2, f16), undefined)
2148// @as(f32, undefined)
2149// @as(f32, undefined)
2150// @as(@Vector(2, f32), .{ 6, undefined })
2151// @as(@Vector(2, f32), .{ undefined, 6 })
2152// @as(@Vector(2, f32), undefined)
2153// @as(@Vector(2, f32), .{ 6, undefined })
2154// @as(@Vector(2, f32), .{ 6, undefined })
2155// @as(@Vector(2, f32), undefined)
2156// @as(@Vector(2, f32), undefined)
2157// @as(@Vector(2, f32), .{ undefined, 6 })
2158// @as(@Vector(2, f32), undefined)
2159// @as(@Vector(2, f32), .{ undefined, 6 })
2160// @as(@Vector(2, f32), undefined)
2161// @as(@Vector(2, f32), undefined)
2162// @as(@Vector(2, f32), undefined)
2163// @as(@Vector(2, f32), undefined)
2164// @as(@Vector(2, f32), undefined)
2165// @as(f32, undefined)
2166// @as(f32, undefined)
2167// @as(@Vector(2, f32), .{ 0, undefined })
2168// @as(@Vector(2, f32), .{ undefined, 0 })
2169// @as(@Vector(2, f32), undefined)
2170// @as(@Vector(2, f32), .{ 0, undefined })
2171// @as(@Vector(2, f32), .{ 0, undefined })
2172// @as(@Vector(2, f32), undefined)
2173// @as(@Vector(2, f32), undefined)
2174// @as(@Vector(2, f32), .{ undefined, 0 })
2175// @as(@Vector(2, f32), undefined)
2176// @as(@Vector(2, f32), .{ undefined, 0 })
2177// @as(@Vector(2, f32), undefined)
2178// @as(@Vector(2, f32), undefined)
2179// @as(@Vector(2, f32), undefined)
2180// @as(@Vector(2, f32), undefined)
2181// @as(@Vector(2, f32), undefined)
2182// @as(f32, undefined)
2183// @as(f32, undefined)
2184// @as(@Vector(2, f32), .{ 9, undefined })
2185// @as(@Vector(2, f32), .{ undefined, 9 })
2186// @as(@Vector(2, f32), undefined)
2187// @as(@Vector(2, f32), .{ 9, undefined })
2188// @as(@Vector(2, f32), .{ 9, undefined })
2189// @as(@Vector(2, f32), undefined)
2190// @as(@Vector(2, f32), undefined)
2191// @as(@Vector(2, f32), .{ undefined, 9 })
2192// @as(@Vector(2, f32), undefined)
2193// @as(@Vector(2, f32), .{ undefined, 9 })
2194// @as(@Vector(2, f32), undefined)
2195// @as(@Vector(2, f32), undefined)
2196// @as(@Vector(2, f32), undefined)
2197// @as(@Vector(2, f32), undefined)
2198// @as(@Vector(2, f32), undefined)
2199// @as(f32, undefined)
2200// @as(@Vector(2, f32), .{ -3, undefined })
2201// @as(@Vector(2, f32), .{ undefined, -3 })
2202// @as(@Vector(2, f32), undefined)
2203// @as(f32, undefined)
2204// @as(f32, undefined)
2205// @as(@Vector(2, f32), [runtime value])
2206// @as(@Vector(2, f32), [runtime value])
2207// @as(@Vector(2, f32), undefined)
2208// @as(@Vector(2, f32), [runtime value])
2209// @as(@Vector(2, f32), [runtime value])
2210// @as(@Vector(2, f32), [runtime value])
2211// @as(@Vector(2, f32), undefined)
2212// @as(@Vector(2, f32), [runtime value])
2213// @as(@Vector(2, f32), [runtime value])
2214// @as(@Vector(2, f32), [runtime value])
2215// @as(@Vector(2, f32), undefined)
2216// @as(@Vector(2, f32), undefined)
2217// @as(@Vector(2, f32), undefined)
2218// @as(@Vector(2, f32), undefined)
2219// @as(@Vector(2, f32), undefined)
2220// @as(f32, undefined)
2221// @as(f32, undefined)
2222// @as(@Vector(2, f32), [runtime value])
2223// @as(@Vector(2, f32), [runtime value])
2224// @as(@Vector(2, f32), undefined)
2225// @as(@Vector(2, f32), [runtime value])
2226// @as(@Vector(2, f32), [runtime value])
2227// @as(@Vector(2, f32), [runtime value])
2228// @as(@Vector(2, f32), undefined)
2229// @as(@Vector(2, f32), [runtime value])
2230// @as(@Vector(2, f32), [runtime value])
2231// @as(@Vector(2, f32), [runtime value])
2232// @as(@Vector(2, f32), undefined)
2233// @as(@Vector(2, f32), undefined)
2234// @as(@Vector(2, f32), undefined)
2235// @as(@Vector(2, f32), undefined)
2236// @as(@Vector(2, f32), undefined)
2237// @as(f32, undefined)
2238// @as(f32, undefined)
2239// @as(@Vector(2, f32), [runtime value])
2240// @as(@Vector(2, f32), [runtime value])
2241// @as(@Vector(2, f32), undefined)
2242// @as(@Vector(2, f32), [runtime value])
2243// @as(@Vector(2, f32), [runtime value])
2244// @as(@Vector(2, f32), [runtime value])
2245// @as(@Vector(2, f32), undefined)
2246// @as(@Vector(2, f32), [runtime value])
2247// @as(@Vector(2, f32), [runtime value])
2248// @as(@Vector(2, f32), [runtime value])
2249// @as(@Vector(2, f32), undefined)
2250// @as(@Vector(2, f32), undefined)
2251// @as(@Vector(2, f32), undefined)
2252// @as(@Vector(2, f32), undefined)
2253// @as(@Vector(2, f32), undefined)
2254// @as(f32, undefined)
2255// @as(@Vector(2, f32), [runtime value])
2256// @as(@Vector(2, f32), [runtime value])
2257// @as(@Vector(2, f32), undefined)
2258// @as(f64, undefined)
2259// @as(f64, undefined)
2260// @as(@Vector(2, f64), .{ 6, undefined })
2261// @as(@Vector(2, f64), .{ undefined, 6 })
2262// @as(@Vector(2, f64), undefined)
2263// @as(@Vector(2, f64), .{ 6, undefined })
2264// @as(@Vector(2, f64), .{ 6, undefined })
2265// @as(@Vector(2, f64), undefined)
2266// @as(@Vector(2, f64), undefined)
2267// @as(@Vector(2, f64), .{ undefined, 6 })
2268// @as(@Vector(2, f64), undefined)
2269// @as(@Vector(2, f64), .{ undefined, 6 })
2270// @as(@Vector(2, f64), undefined)
2271// @as(@Vector(2, f64), undefined)
2272// @as(@Vector(2, f64), undefined)
2273// @as(@Vector(2, f64), undefined)
2274// @as(@Vector(2, f64), undefined)
2275// @as(f64, undefined)
2276// @as(f64, undefined)
2277// @as(@Vector(2, f64), .{ 0, undefined })
2278// @as(@Vector(2, f64), .{ undefined, 0 })
2279// @as(@Vector(2, f64), undefined)
2280// @as(@Vector(2, f64), .{ 0, undefined })
2281// @as(@Vector(2, f64), .{ 0, undefined })
2282// @as(@Vector(2, f64), undefined)
2283// @as(@Vector(2, f64), undefined)
2284// @as(@Vector(2, f64), .{ undefined, 0 })
2285// @as(@Vector(2, f64), undefined)
2286// @as(@Vector(2, f64), .{ undefined, 0 })
2287// @as(@Vector(2, f64), undefined)
2288// @as(@Vector(2, f64), undefined)
2289// @as(@Vector(2, f64), undefined)
2290// @as(@Vector(2, f64), undefined)
2291// @as(@Vector(2, f64), undefined)
2292// @as(f64, undefined)
2293// @as(f64, undefined)
2294// @as(@Vector(2, f64), .{ 9, undefined })
2295// @as(@Vector(2, f64), .{ undefined, 9 })
2296// @as(@Vector(2, f64), undefined)
2297// @as(@Vector(2, f64), .{ 9, undefined })
2298// @as(@Vector(2, f64), .{ 9, undefined })
2299// @as(@Vector(2, f64), undefined)
2300// @as(@Vector(2, f64), undefined)
2301// @as(@Vector(2, f64), .{ undefined, 9 })
2302// @as(@Vector(2, f64), undefined)
2303// @as(@Vector(2, f64), .{ undefined, 9 })
2304// @as(@Vector(2, f64), undefined)
2305// @as(@Vector(2, f64), undefined)
2306// @as(@Vector(2, f64), undefined)
2307// @as(@Vector(2, f64), undefined)
2308// @as(@Vector(2, f64), undefined)
2309// @as(f64, undefined)
2310// @as(@Vector(2, f64), .{ -3, undefined })
2311// @as(@Vector(2, f64), .{ undefined, -3 })
2312// @as(@Vector(2, f64), undefined)
2313// @as(f64, undefined)
2314// @as(f64, undefined)
2315// @as(@Vector(2, f64), [runtime value])
2316// @as(@Vector(2, f64), [runtime value])
2317// @as(@Vector(2, f64), undefined)
2318// @as(@Vector(2, f64), [runtime value])
2319// @as(@Vector(2, f64), [runtime value])
2320// @as(@Vector(2, f64), [runtime value])
2321// @as(@Vector(2, f64), undefined)
2322// @as(@Vector(2, f64), [runtime value])
2323// @as(@Vector(2, f64), [runtime value])
2324// @as(@Vector(2, f64), [runtime value])
2325// @as(@Vector(2, f64), undefined)
2326// @as(@Vector(2, f64), undefined)
2327// @as(@Vector(2, f64), undefined)
2328// @as(@Vector(2, f64), undefined)
2329// @as(@Vector(2, f64), undefined)
2330// @as(f64, undefined)
2331// @as(f64, undefined)
2332// @as(@Vector(2, f64), [runtime value])
2333// @as(@Vector(2, f64), [runtime value])
2334// @as(@Vector(2, f64), undefined)
2335// @as(@Vector(2, f64), [runtime value])
2336// @as(@Vector(2, f64), [runtime value])
2337// @as(@Vector(2, f64), [runtime value])
2338// @as(@Vector(2, f64), undefined)
2339// @as(@Vector(2, f64), [runtime value])
2340// @as(@Vector(2, f64), [runtime value])
2341// @as(@Vector(2, f64), [runtime value])
2342// @as(@Vector(2, f64), undefined)
2343// @as(@Vector(2, f64), undefined)
2344// @as(@Vector(2, f64), undefined)
2345// @as(@Vector(2, f64), undefined)
2346// @as(@Vector(2, f64), undefined)
2347// @as(f64, undefined)
2348// @as(f64, undefined)
2349// @as(@Vector(2, f64), [runtime value])
2350// @as(@Vector(2, f64), [runtime value])
2351// @as(@Vector(2, f64), undefined)
2352// @as(@Vector(2, f64), [runtime value])
2353// @as(@Vector(2, f64), [runtime value])
2354// @as(@Vector(2, f64), [runtime value])
2355// @as(@Vector(2, f64), undefined)
2356// @as(@Vector(2, f64), [runtime value])
2357// @as(@Vector(2, f64), [runtime value])
2358// @as(@Vector(2, f64), [runtime value])
2359// @as(@Vector(2, f64), undefined)
2360// @as(@Vector(2, f64), undefined)
2361// @as(@Vector(2, f64), undefined)
2362// @as(@Vector(2, f64), undefined)
2363// @as(@Vector(2, f64), undefined)
2364// @as(f64, undefined)
2365// @as(@Vector(2, f64), [runtime value])
2366// @as(@Vector(2, f64), [runtime value])
2367// @as(@Vector(2, f64), undefined)
2368// @as(f80, undefined)
2369// @as(f80, undefined)
2370// @as(@Vector(2, f80), .{ 6, undefined })
2371// @as(@Vector(2, f80), .{ undefined, 6 })
2372// @as(@Vector(2, f80), undefined)
2373// @as(@Vector(2, f80), .{ 6, undefined })
2374// @as(@Vector(2, f80), .{ 6, undefined })
2375// @as(@Vector(2, f80), undefined)
2376// @as(@Vector(2, f80), undefined)
2377// @as(@Vector(2, f80), .{ undefined, 6 })
2378// @as(@Vector(2, f80), undefined)
2379// @as(@Vector(2, f80), .{ undefined, 6 })
2380// @as(@Vector(2, f80), undefined)
2381// @as(@Vector(2, f80), undefined)
2382// @as(@Vector(2, f80), undefined)
2383// @as(@Vector(2, f80), undefined)
2384// @as(@Vector(2, f80), undefined)
2385// @as(f80, undefined)
2386// @as(f80, undefined)
2387// @as(@Vector(2, f80), .{ 0, undefined })
2388// @as(@Vector(2, f80), .{ undefined, 0 })
2389// @as(@Vector(2, f80), undefined)
2390// @as(@Vector(2, f80), .{ 0, undefined })
2391// @as(@Vector(2, f80), .{ 0, undefined })
2392// @as(@Vector(2, f80), undefined)
2393// @as(@Vector(2, f80), undefined)
2394// @as(@Vector(2, f80), .{ undefined, 0 })
2395// @as(@Vector(2, f80), undefined)
2396// @as(@Vector(2, f80), .{ undefined, 0 })
2397// @as(@Vector(2, f80), undefined)
2398// @as(@Vector(2, f80), undefined)
2399// @as(@Vector(2, f80), undefined)
2400// @as(@Vector(2, f80), undefined)
2401// @as(@Vector(2, f80), undefined)
2402// @as(f80, undefined)
2403// @as(f80, undefined)
2404// @as(@Vector(2, f80), .{ 9, undefined })
2405// @as(@Vector(2, f80), .{ undefined, 9 })
2406// @as(@Vector(2, f80), undefined)
2407// @as(@Vector(2, f80), .{ 9, undefined })
2408// @as(@Vector(2, f80), .{ 9, undefined })
2409// @as(@Vector(2, f80), undefined)
2410// @as(@Vector(2, f80), undefined)
2411// @as(@Vector(2, f80), .{ undefined, 9 })
2412// @as(@Vector(2, f80), undefined)
2413// @as(@Vector(2, f80), .{ undefined, 9 })
2414// @as(@Vector(2, f80), undefined)
2415// @as(@Vector(2, f80), undefined)
2416// @as(@Vector(2, f80), undefined)
2417// @as(@Vector(2, f80), undefined)
2418// @as(@Vector(2, f80), undefined)
2419// @as(f80, undefined)
2420// @as(@Vector(2, f80), .{ -3, undefined })
2421// @as(@Vector(2, f80), .{ undefined, -3 })
2422// @as(@Vector(2, f80), undefined)
2423// @as(f80, undefined)
2424// @as(f80, undefined)
2425// @as(@Vector(2, f80), [runtime value])
2426// @as(@Vector(2, f80), [runtime value])
2427// @as(@Vector(2, f80), undefined)
2428// @as(@Vector(2, f80), [runtime value])
2429// @as(@Vector(2, f80), [runtime value])
2430// @as(@Vector(2, f80), [runtime value])
2431// @as(@Vector(2, f80), undefined)
2432// @as(@Vector(2, f80), [runtime value])
2433// @as(@Vector(2, f80), [runtime value])
2434// @as(@Vector(2, f80), [runtime value])
2435// @as(@Vector(2, f80), undefined)
2436// @as(@Vector(2, f80), undefined)
2437// @as(@Vector(2, f80), undefined)
2438// @as(@Vector(2, f80), undefined)
2439// @as(@Vector(2, f80), undefined)
2440// @as(f80, undefined)
2441// @as(f80, undefined)
2442// @as(@Vector(2, f80), [runtime value])
2443// @as(@Vector(2, f80), [runtime value])
2444// @as(@Vector(2, f80), undefined)
2445// @as(@Vector(2, f80), [runtime value])
2446// @as(@Vector(2, f80), [runtime value])
2447// @as(@Vector(2, f80), [runtime value])
2448// @as(@Vector(2, f80), undefined)
2449// @as(@Vector(2, f80), [runtime value])
2450// @as(@Vector(2, f80), [runtime value])
2451// @as(@Vector(2, f80), [runtime value])
2452// @as(@Vector(2, f80), undefined)
2453// @as(@Vector(2, f80), undefined)
2454// @as(@Vector(2, f80), undefined)
2455// @as(@Vector(2, f80), undefined)
2456// @as(@Vector(2, f80), undefined)
2457// @as(f80, undefined)
2458// @as(f80, undefined)
2459// @as(@Vector(2, f80), [runtime value])
2460// @as(@Vector(2, f80), [runtime value])
2461// @as(@Vector(2, f80), undefined)
2462// @as(@Vector(2, f80), [runtime value])
2463// @as(@Vector(2, f80), [runtime value])
2464// @as(@Vector(2, f80), [runtime value])
2465// @as(@Vector(2, f80), undefined)
2466// @as(@Vector(2, f80), [runtime value])
2467// @as(@Vector(2, f80), [runtime value])
2468// @as(@Vector(2, f80), [runtime value])
2469// @as(@Vector(2, f80), undefined)
2470// @as(@Vector(2, f80), undefined)
2471// @as(@Vector(2, f80), undefined)
2472// @as(@Vector(2, f80), undefined)
2473// @as(@Vector(2, f80), undefined)
2474// @as(f80, undefined)
2475// @as(@Vector(2, f80), [runtime value])
2476// @as(@Vector(2, f80), [runtime value])
2477// @as(@Vector(2, f80), undefined)
684// @as(i500, undefined)
685// @as(i500, undefined)
686// @as(@Vector(2, i500), .{ 6, undefined })
687// @as(@Vector(2, i500), .{ undefined, 6 })
688// @as(@Vector(2, i500), undefined)
689// @as(@Vector(2, i500), .{ 6, undefined })
690// @as(@Vector(2, i500), .{ 6, undefined })
691// @as(@Vector(2, i500), undefined)
692// @as(@Vector(2, i500), undefined)
693// @as(@Vector(2, i500), .{ undefined, 6 })
694// @as(@Vector(2, i500), undefined)
695// @as(@Vector(2, i500), .{ undefined, 6 })
696// @as(@Vector(2, i500), undefined)
697// @as(@Vector(2, i500), undefined)
698// @as(@Vector(2, i500), undefined)
699// @as(@Vector(2, i500), undefined)
700// @as(@Vector(2, i500), undefined)
701// @as(i500, undefined)
702// @as(i500, undefined)
703// @as(@Vector(2, i500), .{ 6, undefined })
704// @as(@Vector(2, i500), .{ undefined, 6 })
705// @as(@Vector(2, i500), undefined)
706// @as(@Vector(2, i500), .{ 6, undefined })
707// @as(@Vector(2, i500), .{ 6, undefined })
708// @as(@Vector(2, i500), undefined)
709// @as(@Vector(2, i500), undefined)
710// @as(@Vector(2, i500), .{ undefined, 6 })
711// @as(@Vector(2, i500), undefined)
712// @as(@Vector(2, i500), .{ undefined, 6 })
713// @as(@Vector(2, i500), undefined)
714// @as(@Vector(2, i500), undefined)
715// @as(@Vector(2, i500), undefined)
716// @as(@Vector(2, i500), undefined)
717// @as(@Vector(2, i500), undefined)
718// @as(i500, undefined)
719// @as(i500, undefined)
720// @as(@Vector(2, i500), .{ 0, undefined })
721// @as(@Vector(2, i500), .{ undefined, 0 })
722// @as(@Vector(2, i500), undefined)
723// @as(@Vector(2, i500), .{ 0, undefined })
724// @as(@Vector(2, i500), .{ 0, undefined })
725// @as(@Vector(2, i500), undefined)
726// @as(@Vector(2, i500), undefined)
727// @as(@Vector(2, i500), .{ undefined, 0 })
728// @as(@Vector(2, i500), undefined)
729// @as(@Vector(2, i500), .{ undefined, 0 })
730// @as(@Vector(2, i500), undefined)
731// @as(@Vector(2, i500), undefined)
732// @as(@Vector(2, i500), undefined)
733// @as(@Vector(2, i500), undefined)
734// @as(@Vector(2, i500), undefined)
735// @as(i500, undefined)
736// @as(i500, undefined)
737// @as(@Vector(2, i500), .{ 0, undefined })
738// @as(@Vector(2, i500), .{ undefined, 0 })
739// @as(@Vector(2, i500), undefined)
740// @as(@Vector(2, i500), .{ 0, undefined })
741// @as(@Vector(2, i500), .{ 0, undefined })
742// @as(@Vector(2, i500), undefined)
743// @as(@Vector(2, i500), undefined)
744// @as(@Vector(2, i500), .{ undefined, 0 })
745// @as(@Vector(2, i500), undefined)
746// @as(@Vector(2, i500), .{ undefined, 0 })
747// @as(@Vector(2, i500), undefined)
748// @as(@Vector(2, i500), undefined)
749// @as(@Vector(2, i500), undefined)
750// @as(@Vector(2, i500), undefined)
751// @as(@Vector(2, i500), undefined)
752// @as(i500, undefined)
753// @as(i500, undefined)
754// @as(@Vector(2, i500), .{ 9, undefined })
755// @as(@Vector(2, i500), .{ undefined, 9 })
756// @as(@Vector(2, i500), undefined)
757// @as(@Vector(2, i500), .{ 9, undefined })
758// @as(@Vector(2, i500), .{ 9, undefined })
759// @as(@Vector(2, i500), undefined)
760// @as(@Vector(2, i500), undefined)
761// @as(@Vector(2, i500), .{ undefined, 9 })
762// @as(@Vector(2, i500), undefined)
763// @as(@Vector(2, i500), .{ undefined, 9 })
764// @as(@Vector(2, i500), undefined)
765// @as(@Vector(2, i500), undefined)
766// @as(@Vector(2, i500), undefined)
767// @as(@Vector(2, i500), undefined)
768// @as(@Vector(2, i500), undefined)
769// @as(i500, undefined)
770// @as(i500, undefined)
771// @as(@Vector(2, i500), .{ 9, undefined })
772// @as(@Vector(2, i500), .{ undefined, 9 })
773// @as(@Vector(2, i500), undefined)
774// @as(@Vector(2, i500), .{ 9, undefined })
775// @as(@Vector(2, i500), .{ 9, undefined })
776// @as(@Vector(2, i500), undefined)
777// @as(@Vector(2, i500), undefined)
778// @as(@Vector(2, i500), .{ undefined, 9 })
779// @as(@Vector(2, i500), undefined)
780// @as(@Vector(2, i500), .{ undefined, 9 })
781// @as(@Vector(2, i500), undefined)
782// @as(@Vector(2, i500), undefined)
783// @as(@Vector(2, i500), undefined)
784// @as(@Vector(2, i500), undefined)
785// @as(@Vector(2, i500), undefined)
786// @as(i500, undefined)
787// @as(i500, undefined)
788// @as(@Vector(2, i500), .{ 0, undefined })
789// @as(@Vector(2, i500), .{ undefined, 0 })
790// @as(@Vector(2, i500), undefined)
791// @as(@Vector(2, i500), .{ 0, undefined })
792// @as(@Vector(2, i500), .{ 0, undefined })
793// @as(@Vector(2, i500), undefined)
794// @as(@Vector(2, i500), undefined)
795// @as(@Vector(2, i500), .{ undefined, 0 })
796// @as(@Vector(2, i500), undefined)
797// @as(@Vector(2, i500), .{ undefined, 0 })
798// @as(@Vector(2, i500), undefined)
799// @as(@Vector(2, i500), undefined)
800// @as(@Vector(2, i500), undefined)
801// @as(@Vector(2, i500), undefined)
802// @as(@Vector(2, i500), undefined)
803// @as(i500, undefined)
804// @as(@Vector(2, i500), undefined)
805// @as(i500, undefined)
806// @as(i500, undefined)
807// @as(@Vector(2, i500), undefined)
808// @as(@Vector(2, i500), undefined)
809// @as(i500, undefined)
810// @as(@Vector(2, i500), undefined)
811// @as(i500, undefined)
812// @as(i500, undefined)
813// @as(@Vector(2, i500), [runtime value])
814// @as(@Vector(2, i500), [runtime value])
815// @as(@Vector(2, i500), undefined)
816// @as(@Vector(2, i500), [runtime value])
817// @as(@Vector(2, i500), [runtime value])
818// @as(@Vector(2, i500), [runtime value])
819// @as(@Vector(2, i500), undefined)
820// @as(@Vector(2, i500), [runtime value])
821// @as(@Vector(2, i500), [runtime value])
822// @as(@Vector(2, i500), [runtime value])
823// @as(@Vector(2, i500), undefined)
824// @as(@Vector(2, i500), undefined)
825// @as(@Vector(2, i500), undefined)
826// @as(@Vector(2, i500), undefined)
827// @as(@Vector(2, i500), undefined)
828// @as(i500, undefined)
829// @as(i500, undefined)
830// @as(@Vector(2, i500), [runtime value])
831// @as(@Vector(2, i500), [runtime value])
832// @as(@Vector(2, i500), undefined)
833// @as(@Vector(2, i500), [runtime value])
834// @as(@Vector(2, i500), [runtime value])
835// @as(@Vector(2, i500), [runtime value])
836// @as(@Vector(2, i500), undefined)
837// @as(@Vector(2, i500), [runtime value])
838// @as(@Vector(2, i500), [runtime value])
839// @as(@Vector(2, i500), [runtime value])
840// @as(@Vector(2, i500), undefined)
841// @as(@Vector(2, i500), undefined)
842// @as(@Vector(2, i500), undefined)
843// @as(@Vector(2, i500), undefined)
844// @as(@Vector(2, i500), undefined)
845// @as(i500, undefined)
846// @as(i500, undefined)
847// @as(@Vector(2, i500), [runtime value])
848// @as(@Vector(2, i500), [runtime value])
849// @as(@Vector(2, i500), undefined)
850// @as(@Vector(2, i500), [runtime value])
851// @as(@Vector(2, i500), [runtime value])
852// @as(@Vector(2, i500), [runtime value])
853// @as(@Vector(2, i500), undefined)
854// @as(@Vector(2, i500), [runtime value])
855// @as(@Vector(2, i500), [runtime value])
856// @as(@Vector(2, i500), [runtime value])
857// @as(@Vector(2, i500), undefined)
858// @as(@Vector(2, i500), undefined)
859// @as(@Vector(2, i500), undefined)
860// @as(@Vector(2, i500), undefined)
861// @as(@Vector(2, i500), undefined)
862// @as(i500, undefined)
863// @as(i500, undefined)
864// @as(@Vector(2, i500), [runtime value])
865// @as(@Vector(2, i500), [runtime value])
866// @as(@Vector(2, i500), undefined)
867// @as(@Vector(2, i500), [runtime value])
868// @as(@Vector(2, i500), [runtime value])
869// @as(@Vector(2, i500), [runtime value])
870// @as(@Vector(2, i500), undefined)
871// @as(@Vector(2, i500), [runtime value])
872// @as(@Vector(2, i500), [runtime value])
873// @as(@Vector(2, i500), [runtime value])
874// @as(@Vector(2, i500), undefined)
875// @as(@Vector(2, i500), undefined)
876// @as(@Vector(2, i500), undefined)
877// @as(@Vector(2, i500), undefined)
878// @as(@Vector(2, i500), undefined)
879// @as(i500, undefined)
880// @as(i500, undefined)
881// @as(@Vector(2, i500), [runtime value])
882// @as(@Vector(2, i500), [runtime value])
883// @as(@Vector(2, i500), undefined)
884// @as(@Vector(2, i500), [runtime value])
885// @as(@Vector(2, i500), [runtime value])
886// @as(@Vector(2, i500), [runtime value])
887// @as(@Vector(2, i500), undefined)
888// @as(@Vector(2, i500), [runtime value])
889// @as(@Vector(2, i500), [runtime value])
890// @as(@Vector(2, i500), [runtime value])
891// @as(@Vector(2, i500), undefined)
892// @as(@Vector(2, i500), undefined)
893// @as(@Vector(2, i500), undefined)
894// @as(@Vector(2, i500), undefined)
895// @as(@Vector(2, i500), undefined)
896// @as(i500, undefined)
897// @as(i500, undefined)
898// @as(@Vector(2, i500), [runtime value])
899// @as(@Vector(2, i500), [runtime value])
900// @as(@Vector(2, i500), undefined)
901// @as(@Vector(2, i500), [runtime value])
902// @as(@Vector(2, i500), [runtime value])
903// @as(@Vector(2, i500), [runtime value])
904// @as(@Vector(2, i500), undefined)
905// @as(@Vector(2, i500), [runtime value])
906// @as(@Vector(2, i500), [runtime value])
907// @as(@Vector(2, i500), [runtime value])
908// @as(@Vector(2, i500), undefined)
909// @as(@Vector(2, i500), undefined)
910// @as(@Vector(2, i500), undefined)
911// @as(@Vector(2, i500), undefined)
912// @as(@Vector(2, i500), undefined)
913// @as(i500, [runtime value])
914// @as(i500, [runtime value])
915// @as(@Vector(2, i500), [runtime value])
916// @as(@Vector(2, i500), [runtime value])
917// @as(@Vector(2, i500), [runtime value])
918// @as(@Vector(2, i500), [runtime value])
919// @as(@Vector(2, i500), [runtime value])
920// @as(@Vector(2, i500), [runtime value])
921// @as(@Vector(2, i500), [runtime value])
922// @as(@Vector(2, i500), [runtime value])
923// @as(@Vector(2, i500), [runtime value])
924// @as(@Vector(2, i500), [runtime value])
925// @as(@Vector(2, i500), [runtime value])
926// @as(@Vector(2, i500), [runtime value])
927// @as(@Vector(2, i500), [runtime value])
928// @as(@Vector(2, i500), [runtime value])
929// @as(@Vector(2, i500), undefined)
930// @as(i500, undefined)
931// @as(@Vector(2, i500), undefined)
932// @as(i500, undefined)
933// @as(i500, undefined)
934// @as(@Vector(2, i500), undefined)
935// @as(@Vector(2, i500), undefined)
936// @as(i500, undefined)
937// @as(@Vector(2, i500), undefined)
938// @as(u500, undefined)
939// @as(u500, undefined)
940// @as(@Vector(2, u500), .{ 6, undefined })
941// @as(@Vector(2, u500), .{ undefined, 6 })
942// @as(@Vector(2, u500), undefined)
943// @as(@Vector(2, u500), .{ 6, undefined })
944// @as(@Vector(2, u500), .{ 6, undefined })
945// @as(@Vector(2, u500), undefined)
946// @as(@Vector(2, u500), undefined)
947// @as(@Vector(2, u500), .{ undefined, 6 })
948// @as(@Vector(2, u500), undefined)
949// @as(@Vector(2, u500), .{ undefined, 6 })
950// @as(@Vector(2, u500), undefined)
951// @as(@Vector(2, u500), undefined)
952// @as(@Vector(2, u500), undefined)
953// @as(@Vector(2, u500), undefined)
954// @as(@Vector(2, u500), undefined)
955// @as(u500, undefined)
956// @as(u500, undefined)
957// @as(@Vector(2, u500), .{ 6, undefined })
958// @as(@Vector(2, u500), .{ undefined, 6 })
959// @as(@Vector(2, u500), undefined)
960// @as(@Vector(2, u500), .{ 6, undefined })
961// @as(@Vector(2, u500), .{ 6, undefined })
962// @as(@Vector(2, u500), undefined)
963// @as(@Vector(2, u500), undefined)
964// @as(@Vector(2, u500), .{ undefined, 6 })
965// @as(@Vector(2, u500), undefined)
966// @as(@Vector(2, u500), .{ undefined, 6 })
967// @as(@Vector(2, u500), undefined)
968// @as(@Vector(2, u500), undefined)
969// @as(@Vector(2, u500), undefined)
970// @as(@Vector(2, u500), undefined)
971// @as(@Vector(2, u500), undefined)
972// @as(u500, undefined)
973// @as(u500, undefined)
974// @as(@Vector(2, u500), .{ 0, undefined })
975// @as(@Vector(2, u500), .{ undefined, 0 })
976// @as(@Vector(2, u500), undefined)
977// @as(@Vector(2, u500), .{ 0, undefined })
978// @as(@Vector(2, u500), .{ 0, undefined })
979// @as(@Vector(2, u500), undefined)
980// @as(@Vector(2, u500), undefined)
981// @as(@Vector(2, u500), .{ undefined, 0 })
982// @as(@Vector(2, u500), undefined)
983// @as(@Vector(2, u500), .{ undefined, 0 })
984// @as(@Vector(2, u500), undefined)
985// @as(@Vector(2, u500), undefined)
986// @as(@Vector(2, u500), undefined)
987// @as(@Vector(2, u500), undefined)
988// @as(@Vector(2, u500), undefined)
989// @as(u500, undefined)
990// @as(u500, undefined)
991// @as(@Vector(2, u500), .{ 0, undefined })
992// @as(@Vector(2, u500), .{ undefined, 0 })
993// @as(@Vector(2, u500), undefined)
994// @as(@Vector(2, u500), .{ 0, undefined })
995// @as(@Vector(2, u500), .{ 0, undefined })
996// @as(@Vector(2, u500), undefined)
997// @as(@Vector(2, u500), undefined)
998// @as(@Vector(2, u500), .{ undefined, 0 })
999// @as(@Vector(2, u500), undefined)
1000// @as(@Vector(2, u500), .{ undefined, 0 })
1001// @as(@Vector(2, u500), undefined)
1002// @as(@Vector(2, u500), undefined)
1003// @as(@Vector(2, u500), undefined)
1004// @as(@Vector(2, u500), undefined)
1005// @as(@Vector(2, u500), undefined)
1006// @as(u500, undefined)
1007// @as(u500, undefined)
1008// @as(@Vector(2, u500), .{ 9, undefined })
1009// @as(@Vector(2, u500), .{ undefined, 9 })
1010// @as(@Vector(2, u500), undefined)
1011// @as(@Vector(2, u500), .{ 9, undefined })
1012// @as(@Vector(2, u500), .{ 9, undefined })
1013// @as(@Vector(2, u500), undefined)
1014// @as(@Vector(2, u500), undefined)
1015// @as(@Vector(2, u500), .{ undefined, 9 })
1016// @as(@Vector(2, u500), undefined)
1017// @as(@Vector(2, u500), .{ undefined, 9 })
1018// @as(@Vector(2, u500), undefined)
1019// @as(@Vector(2, u500), undefined)
1020// @as(@Vector(2, u500), undefined)
1021// @as(@Vector(2, u500), undefined)
1022// @as(@Vector(2, u500), undefined)
1023// @as(u500, undefined)
1024// @as(u500, undefined)
1025// @as(@Vector(2, u500), .{ 9, undefined })
1026// @as(@Vector(2, u500), .{ undefined, 9 })
1027// @as(@Vector(2, u500), undefined)
1028// @as(@Vector(2, u500), .{ 9, undefined })
1029// @as(@Vector(2, u500), .{ 9, undefined })
1030// @as(@Vector(2, u500), undefined)
1031// @as(@Vector(2, u500), undefined)
1032// @as(@Vector(2, u500), .{ undefined, 9 })
1033// @as(@Vector(2, u500), undefined)
1034// @as(@Vector(2, u500), .{ undefined, 9 })
1035// @as(@Vector(2, u500), undefined)
1036// @as(@Vector(2, u500), undefined)
1037// @as(@Vector(2, u500), undefined)
1038// @as(@Vector(2, u500), undefined)
1039// @as(@Vector(2, u500), undefined)
1040// @as(u500, undefined)
1041// @as(u500, undefined)
1042// @as(@Vector(2, u500), .{ 24, undefined })
1043// @as(@Vector(2, u500), .{ undefined, 24 })
1044// @as(@Vector(2, u500), undefined)
1045// @as(@Vector(2, u500), .{ 24, undefined })
1046// @as(@Vector(2, u500), .{ 24, undefined })
1047// @as(@Vector(2, u500), undefined)
1048// @as(@Vector(2, u500), undefined)
1049// @as(@Vector(2, u500), .{ undefined, 24 })
1050// @as(@Vector(2, u500), undefined)
1051// @as(@Vector(2, u500), .{ undefined, 24 })
1052// @as(@Vector(2, u500), undefined)
1053// @as(@Vector(2, u500), undefined)
1054// @as(@Vector(2, u500), undefined)
1055// @as(@Vector(2, u500), undefined)
1056// @as(@Vector(2, u500), undefined)
1057// @as(u500, undefined)
1058// @as(u500, undefined)
1059// @as(@Vector(2, u500), .{ 0, undefined })
1060// @as(@Vector(2, u500), .{ undefined, 0 })
1061// @as(@Vector(2, u500), undefined)
1062// @as(@Vector(2, u500), .{ 0, undefined })
1063// @as(@Vector(2, u500), .{ 0, undefined })
1064// @as(@Vector(2, u500), undefined)
1065// @as(@Vector(2, u500), undefined)
1066// @as(@Vector(2, u500), .{ undefined, 0 })
1067// @as(@Vector(2, u500), undefined)
1068// @as(@Vector(2, u500), .{ undefined, 0 })
1069// @as(@Vector(2, u500), undefined)
1070// @as(@Vector(2, u500), undefined)
1071// @as(@Vector(2, u500), undefined)
1072// @as(@Vector(2, u500), undefined)
1073// @as(@Vector(2, u500), undefined)
1074// @as(u500, undefined)
1075// @as(@Vector(2, u500), undefined)
1076// @as(u500, undefined)
1077// @as(u500, undefined)
1078// @as(@Vector(2, u500), undefined)
1079// @as(@Vector(2, u500), undefined)
1080// @as(u1, undefined)
1081// @as(@Vector(2, u1), .{ 1, undefined })
1082// @as(@Vector(2, u1), .{ undefined, 1 })
1083// @as(@Vector(2, u1), undefined)
1084// @as(u500, undefined)
1085// @as(@Vector(2, u500), undefined)
1086// @as(u500, undefined)
1087// @as(u500, undefined)
1088// @as(@Vector(2, u500), [runtime value])
1089// @as(@Vector(2, u500), [runtime value])
1090// @as(@Vector(2, u500), undefined)
1091// @as(@Vector(2, u500), [runtime value])
1092// @as(@Vector(2, u500), [runtime value])
1093// @as(@Vector(2, u500), [runtime value])
1094// @as(@Vector(2, u500), undefined)
1095// @as(@Vector(2, u500), [runtime value])
1096// @as(@Vector(2, u500), [runtime value])
1097// @as(@Vector(2, u500), [runtime value])
1098// @as(@Vector(2, u500), undefined)
1099// @as(@Vector(2, u500), undefined)
1100// @as(@Vector(2, u500), undefined)
1101// @as(@Vector(2, u500), undefined)
1102// @as(@Vector(2, u500), undefined)
1103// @as(u500, undefined)
1104// @as(u500, undefined)
1105// @as(@Vector(2, u500), [runtime value])
1106// @as(@Vector(2, u500), [runtime value])
1107// @as(@Vector(2, u500), undefined)
1108// @as(@Vector(2, u500), [runtime value])
1109// @as(@Vector(2, u500), [runtime value])
1110// @as(@Vector(2, u500), [runtime value])
1111// @as(@Vector(2, u500), undefined)
1112// @as(@Vector(2, u500), [runtime value])
1113// @as(@Vector(2, u500), [runtime value])
1114// @as(@Vector(2, u500), [runtime value])
1115// @as(@Vector(2, u500), undefined)
1116// @as(@Vector(2, u500), undefined)
1117// @as(@Vector(2, u500), undefined)
1118// @as(@Vector(2, u500), undefined)
1119// @as(@Vector(2, u500), undefined)
1120// @as(u500, undefined)
1121// @as(u500, undefined)
1122// @as(@Vector(2, u500), [runtime value])
1123// @as(@Vector(2, u500), [runtime value])
1124// @as(@Vector(2, u500), undefined)
1125// @as(@Vector(2, u500), [runtime value])
1126// @as(@Vector(2, u500), [runtime value])
1127// @as(@Vector(2, u500), [runtime value])
1128// @as(@Vector(2, u500), undefined)
1129// @as(@Vector(2, u500), [runtime value])
1130// @as(@Vector(2, u500), [runtime value])
1131// @as(@Vector(2, u500), [runtime value])
1132// @as(@Vector(2, u500), undefined)
1133// @as(@Vector(2, u500), undefined)
1134// @as(@Vector(2, u500), undefined)
1135// @as(@Vector(2, u500), undefined)
1136// @as(@Vector(2, u500), undefined)
1137// @as(u500, undefined)
1138// @as(u500, undefined)
1139// @as(@Vector(2, u500), [runtime value])
1140// @as(@Vector(2, u500), [runtime value])
1141// @as(@Vector(2, u500), undefined)
1142// @as(@Vector(2, u500), [runtime value])
1143// @as(@Vector(2, u500), [runtime value])
1144// @as(@Vector(2, u500), [runtime value])
1145// @as(@Vector(2, u500), undefined)
1146// @as(@Vector(2, u500), [runtime value])
1147// @as(@Vector(2, u500), [runtime value])
1148// @as(@Vector(2, u500), [runtime value])
1149// @as(@Vector(2, u500), undefined)
1150// @as(@Vector(2, u500), undefined)
1151// @as(@Vector(2, u500), undefined)
1152// @as(@Vector(2, u500), undefined)
1153// @as(@Vector(2, u500), undefined)
1154// @as(u500, undefined)
1155// @as(u500, undefined)
1156// @as(@Vector(2, u500), [runtime value])
1157// @as(@Vector(2, u500), [runtime value])
1158// @as(@Vector(2, u500), undefined)
1159// @as(@Vector(2, u500), [runtime value])
1160// @as(@Vector(2, u500), [runtime value])
1161// @as(@Vector(2, u500), [runtime value])
1162// @as(@Vector(2, u500), undefined)
1163// @as(@Vector(2, u500), [runtime value])
1164// @as(@Vector(2, u500), [runtime value])
1165// @as(@Vector(2, u500), [runtime value])
1166// @as(@Vector(2, u500), undefined)
1167// @as(@Vector(2, u500), undefined)
1168// @as(@Vector(2, u500), undefined)
1169// @as(@Vector(2, u500), undefined)
1170// @as(@Vector(2, u500), undefined)
1171// @as(u500, undefined)
1172// @as(u500, undefined)
1173// @as(@Vector(2, u500), [runtime value])
1174// @as(@Vector(2, u500), [runtime value])
1175// @as(@Vector(2, u500), undefined)
1176// @as(@Vector(2, u500), [runtime value])
1177// @as(@Vector(2, u500), [runtime value])
1178// @as(@Vector(2, u500), [runtime value])
1179// @as(@Vector(2, u500), undefined)
1180// @as(@Vector(2, u500), [runtime value])
1181// @as(@Vector(2, u500), [runtime value])
1182// @as(@Vector(2, u500), [runtime value])
1183// @as(@Vector(2, u500), undefined)
1184// @as(@Vector(2, u500), undefined)
1185// @as(@Vector(2, u500), undefined)
1186// @as(@Vector(2, u500), undefined)
1187// @as(@Vector(2, u500), undefined)
1188// @as(u500, undefined)
1189// @as(u500, undefined)
1190// @as(@Vector(2, u500), [runtime value])
1191// @as(@Vector(2, u500), [runtime value])
1192// @as(@Vector(2, u500), undefined)
1193// @as(@Vector(2, u500), [runtime value])
1194// @as(@Vector(2, u500), [runtime value])
1195// @as(@Vector(2, u500), [runtime value])
1196// @as(@Vector(2, u500), undefined)
1197// @as(@Vector(2, u500), [runtime value])
1198// @as(@Vector(2, u500), [runtime value])
1199// @as(@Vector(2, u500), [runtime value])
1200// @as(@Vector(2, u500), undefined)
1201// @as(@Vector(2, u500), undefined)
1202// @as(@Vector(2, u500), undefined)
1203// @as(@Vector(2, u500), undefined)
1204// @as(@Vector(2, u500), undefined)
1205// @as(u500, [runtime value])
1206// @as(u500, [runtime value])
1207// @as(@Vector(2, u500), [runtime value])
1208// @as(@Vector(2, u500), [runtime value])
1209// @as(@Vector(2, u500), [runtime value])
1210// @as(@Vector(2, u500), [runtime value])
1211// @as(@Vector(2, u500), [runtime value])
1212// @as(@Vector(2, u500), [runtime value])
1213// @as(@Vector(2, u500), [runtime value])
1214// @as(@Vector(2, u500), [runtime value])
1215// @as(@Vector(2, u500), [runtime value])
1216// @as(@Vector(2, u500), [runtime value])
1217// @as(@Vector(2, u500), [runtime value])
1218// @as(@Vector(2, u500), [runtime value])
1219// @as(@Vector(2, u500), [runtime value])
1220// @as(@Vector(2, u500), [runtime value])
1221// @as(@Vector(2, u500), undefined)
1222// @as(u500, undefined)
1223// @as(@Vector(2, u500), undefined)
1224// @as(u500, undefined)
1225// @as(u500, undefined)
1226// @as(@Vector(2, u500), undefined)
1227// @as(@Vector(2, u500), undefined)
1228// @as(u1, undefined)
1229// @as(@Vector(2, u1), [runtime value])
1230// @as(@Vector(2, u1), [runtime value])
1231// @as(@Vector(2, u1), undefined)
1232// @as(u500, undefined)
1233// @as(@Vector(2, u500), undefined)
1234// @as(i32, undefined)
1235// @as(i32, undefined)
1236// @as(@Vector(2, i32), .{ 6, undefined })
1237// @as(@Vector(2, i32), .{ undefined, 6 })
1238// @as(@Vector(2, i32), undefined)
1239// @as(@Vector(2, i32), .{ 6, undefined })
1240// @as(@Vector(2, i32), .{ 6, undefined })
1241// @as(@Vector(2, i32), undefined)
1242// @as(@Vector(2, i32), undefined)
1243// @as(@Vector(2, i32), .{ undefined, 6 })
1244// @as(@Vector(2, i32), undefined)
1245// @as(@Vector(2, i32), .{ undefined, 6 })
1246// @as(@Vector(2, i32), undefined)
1247// @as(@Vector(2, i32), undefined)
1248// @as(@Vector(2, i32), undefined)
1249// @as(@Vector(2, i32), undefined)
1250// @as(@Vector(2, i32), undefined)
1251// @as(i32, undefined)
1252// @as(i32, undefined)
1253// @as(@Vector(2, i32), .{ 6, undefined })
1254// @as(@Vector(2, i32), .{ undefined, 6 })
1255// @as(@Vector(2, i32), undefined)
1256// @as(@Vector(2, i32), .{ 6, undefined })
1257// @as(@Vector(2, i32), .{ 6, undefined })
1258// @as(@Vector(2, i32), undefined)
1259// @as(@Vector(2, i32), undefined)
1260// @as(@Vector(2, i32), .{ undefined, 6 })
1261// @as(@Vector(2, i32), undefined)
1262// @as(@Vector(2, i32), .{ undefined, 6 })
1263// @as(@Vector(2, i32), undefined)
1264// @as(@Vector(2, i32), undefined)
1265// @as(@Vector(2, i32), undefined)
1266// @as(@Vector(2, i32), undefined)
1267// @as(@Vector(2, i32), undefined)
1268// @as(i32, undefined)
1269// @as(i32, undefined)
1270// @as(@Vector(2, i32), .{ 0, undefined })
1271// @as(@Vector(2, i32), .{ undefined, 0 })
1272// @as(@Vector(2, i32), undefined)
1273// @as(@Vector(2, i32), .{ 0, undefined })
1274// @as(@Vector(2, i32), .{ 0, undefined })
1275// @as(@Vector(2, i32), undefined)
1276// @as(@Vector(2, i32), undefined)
1277// @as(@Vector(2, i32), .{ undefined, 0 })
1278// @as(@Vector(2, i32), undefined)
1279// @as(@Vector(2, i32), .{ undefined, 0 })
1280// @as(@Vector(2, i32), undefined)
1281// @as(@Vector(2, i32), undefined)
1282// @as(@Vector(2, i32), undefined)
1283// @as(@Vector(2, i32), undefined)
1284// @as(@Vector(2, i32), undefined)
1285// @as(i32, undefined)
1286// @as(i32, undefined)
1287// @as(@Vector(2, i32), .{ 0, undefined })
1288// @as(@Vector(2, i32), .{ undefined, 0 })
1289// @as(@Vector(2, i32), undefined)
1290// @as(@Vector(2, i32), .{ 0, undefined })
1291// @as(@Vector(2, i32), .{ 0, undefined })
1292// @as(@Vector(2, i32), undefined)
1293// @as(@Vector(2, i32), undefined)
1294// @as(@Vector(2, i32), .{ undefined, 0 })
1295// @as(@Vector(2, i32), undefined)
1296// @as(@Vector(2, i32), .{ undefined, 0 })
1297// @as(@Vector(2, i32), undefined)
1298// @as(@Vector(2, i32), undefined)
1299// @as(@Vector(2, i32), undefined)
1300// @as(@Vector(2, i32), undefined)
1301// @as(@Vector(2, i32), undefined)
1302// @as(i32, undefined)
1303// @as(i32, undefined)
1304// @as(@Vector(2, i32), .{ 9, undefined })
1305// @as(@Vector(2, i32), .{ undefined, 9 })
1306// @as(@Vector(2, i32), undefined)
1307// @as(@Vector(2, i32), .{ 9, undefined })
1308// @as(@Vector(2, i32), .{ 9, undefined })
1309// @as(@Vector(2, i32), undefined)
1310// @as(@Vector(2, i32), undefined)
1311// @as(@Vector(2, i32), .{ undefined, 9 })
1312// @as(@Vector(2, i32), undefined)
1313// @as(@Vector(2, i32), .{ undefined, 9 })
1314// @as(@Vector(2, i32), undefined)
1315// @as(@Vector(2, i32), undefined)
1316// @as(@Vector(2, i32), undefined)
1317// @as(@Vector(2, i32), undefined)
1318// @as(@Vector(2, i32), undefined)
1319// @as(i32, undefined)
1320// @as(i32, undefined)
1321// @as(@Vector(2, i32), .{ 9, undefined })
1322// @as(@Vector(2, i32), .{ undefined, 9 })
1323// @as(@Vector(2, i32), undefined)
1324// @as(@Vector(2, i32), .{ 9, undefined })
1325// @as(@Vector(2, i32), .{ 9, undefined })
1326// @as(@Vector(2, i32), undefined)
1327// @as(@Vector(2, i32), undefined)
1328// @as(@Vector(2, i32), .{ undefined, 9 })
1329// @as(@Vector(2, i32), undefined)
1330// @as(@Vector(2, i32), .{ undefined, 9 })
1331// @as(@Vector(2, i32), undefined)
1332// @as(@Vector(2, i32), undefined)
1333// @as(@Vector(2, i32), undefined)
1334// @as(@Vector(2, i32), undefined)
1335// @as(@Vector(2, i32), undefined)
1336// @as(i32, undefined)
1337// @as(i32, undefined)
1338// @as(@Vector(2, i32), .{ 0, undefined })
1339// @as(@Vector(2, i32), .{ undefined, 0 })
1340// @as(@Vector(2, i32), undefined)
1341// @as(@Vector(2, i32), .{ 0, undefined })
1342// @as(@Vector(2, i32), .{ 0, undefined })
1343// @as(@Vector(2, i32), undefined)
1344// @as(@Vector(2, i32), undefined)
1345// @as(@Vector(2, i32), .{ undefined, 0 })
1346// @as(@Vector(2, i32), undefined)
1347// @as(@Vector(2, i32), .{ undefined, 0 })
1348// @as(@Vector(2, i32), undefined)
1349// @as(@Vector(2, i32), undefined)
1350// @as(@Vector(2, i32), undefined)
1351// @as(@Vector(2, i32), undefined)
1352// @as(@Vector(2, i32), undefined)
1353// @as(i32, undefined)
1354// @as(@Vector(2, i32), undefined)
1355// @as(i32, undefined)
1356// @as(i32, undefined)
1357// @as(@Vector(2, i32), undefined)
1358// @as(@Vector(2, i32), undefined)
1359// @as(i32, undefined)
1360// @as(@Vector(2, i32), undefined)
1361// @as(i32, undefined)
1362// @as(i32, undefined)
1363// @as(@Vector(2, i32), [runtime value])
1364// @as(@Vector(2, i32), [runtime value])
1365// @as(@Vector(2, i32), undefined)
1366// @as(@Vector(2, i32), [runtime value])
1367// @as(@Vector(2, i32), [runtime value])
1368// @as(@Vector(2, i32), [runtime value])
1369// @as(@Vector(2, i32), undefined)
1370// @as(@Vector(2, i32), [runtime value])
1371// @as(@Vector(2, i32), [runtime value])
1372// @as(@Vector(2, i32), [runtime value])
1373// @as(@Vector(2, i32), undefined)
1374// @as(@Vector(2, i32), undefined)
1375// @as(@Vector(2, i32), undefined)
1376// @as(@Vector(2, i32), undefined)
1377// @as(@Vector(2, i32), undefined)
1378// @as(i32, undefined)
1379// @as(i32, undefined)
1380// @as(@Vector(2, i32), [runtime value])
1381// @as(@Vector(2, i32), [runtime value])
1382// @as(@Vector(2, i32), undefined)
1383// @as(@Vector(2, i32), [runtime value])
1384// @as(@Vector(2, i32), [runtime value])
1385// @as(@Vector(2, i32), [runtime value])
1386// @as(@Vector(2, i32), undefined)
1387// @as(@Vector(2, i32), [runtime value])
1388// @as(@Vector(2, i32), [runtime value])
1389// @as(@Vector(2, i32), [runtime value])
1390// @as(@Vector(2, i32), undefined)
1391// @as(@Vector(2, i32), undefined)
1392// @as(@Vector(2, i32), undefined)
1393// @as(@Vector(2, i32), undefined)
1394// @as(@Vector(2, i32), undefined)
1395// @as(i32, undefined)
1396// @as(i32, undefined)
1397// @as(@Vector(2, i32), [runtime value])
1398// @as(@Vector(2, i32), [runtime value])
1399// @as(@Vector(2, i32), undefined)
1400// @as(@Vector(2, i32), [runtime value])
1401// @as(@Vector(2, i32), [runtime value])
1402// @as(@Vector(2, i32), [runtime value])
1403// @as(@Vector(2, i32), undefined)
1404// @as(@Vector(2, i32), [runtime value])
1405// @as(@Vector(2, i32), [runtime value])
1406// @as(@Vector(2, i32), [runtime value])
1407// @as(@Vector(2, i32), undefined)
1408// @as(@Vector(2, i32), undefined)
1409// @as(@Vector(2, i32), undefined)
1410// @as(@Vector(2, i32), undefined)
1411// @as(@Vector(2, i32), undefined)
1412// @as(i32, undefined)
1413// @as(i32, undefined)
1414// @as(@Vector(2, i32), [runtime value])
1415// @as(@Vector(2, i32), [runtime value])
1416// @as(@Vector(2, i32), undefined)
1417// @as(@Vector(2, i32), [runtime value])
1418// @as(@Vector(2, i32), [runtime value])
1419// @as(@Vector(2, i32), [runtime value])
1420// @as(@Vector(2, i32), undefined)
1421// @as(@Vector(2, i32), [runtime value])
1422// @as(@Vector(2, i32), [runtime value])
1423// @as(@Vector(2, i32), [runtime value])
1424// @as(@Vector(2, i32), undefined)
1425// @as(@Vector(2, i32), undefined)
1426// @as(@Vector(2, i32), undefined)
1427// @as(@Vector(2, i32), undefined)
1428// @as(@Vector(2, i32), undefined)
1429// @as(i32, undefined)
1430// @as(i32, undefined)
1431// @as(@Vector(2, i32), [runtime value])
1432// @as(@Vector(2, i32), [runtime value])
1433// @as(@Vector(2, i32), undefined)
1434// @as(@Vector(2, i32), [runtime value])
1435// @as(@Vector(2, i32), [runtime value])
1436// @as(@Vector(2, i32), [runtime value])
1437// @as(@Vector(2, i32), undefined)
1438// @as(@Vector(2, i32), [runtime value])
1439// @as(@Vector(2, i32), [runtime value])
1440// @as(@Vector(2, i32), [runtime value])
1441// @as(@Vector(2, i32), undefined)
1442// @as(@Vector(2, i32), undefined)
1443// @as(@Vector(2, i32), undefined)
1444// @as(@Vector(2, i32), undefined)
1445// @as(@Vector(2, i32), undefined)
1446// @as(i32, undefined)
1447// @as(i32, undefined)
1448// @as(@Vector(2, i32), [runtime value])
1449// @as(@Vector(2, i32), [runtime value])
1450// @as(@Vector(2, i32), undefined)
1451// @as(@Vector(2, i32), [runtime value])
1452// @as(@Vector(2, i32), [runtime value])
1453// @as(@Vector(2, i32), [runtime value])
1454// @as(@Vector(2, i32), undefined)
1455// @as(@Vector(2, i32), [runtime value])
1456// @as(@Vector(2, i32), [runtime value])
1457// @as(@Vector(2, i32), [runtime value])
1458// @as(@Vector(2, i32), undefined)
1459// @as(@Vector(2, i32), undefined)
1460// @as(@Vector(2, i32), undefined)
1461// @as(@Vector(2, i32), undefined)
1462// @as(@Vector(2, i32), undefined)
1463// @as(i32, [runtime value])
1464// @as(i32, [runtime value])
1465// @as(@Vector(2, i32), [runtime value])
1466// @as(@Vector(2, i32), [runtime value])
1467// @as(@Vector(2, i32), [runtime value])
1468// @as(@Vector(2, i32), [runtime value])
1469// @as(@Vector(2, i32), [runtime value])
1470// @as(@Vector(2, i32), [runtime value])
1471// @as(@Vector(2, i32), [runtime value])
1472// @as(@Vector(2, i32), [runtime value])
1473// @as(@Vector(2, i32), [runtime value])
1474// @as(@Vector(2, i32), [runtime value])
1475// @as(@Vector(2, i32), [runtime value])
1476// @as(@Vector(2, i32), [runtime value])
1477// @as(@Vector(2, i32), [runtime value])
1478// @as(@Vector(2, i32), [runtime value])
1479// @as(@Vector(2, i32), undefined)
1480// @as(i32, undefined)
1481// @as(@Vector(2, i32), undefined)
1482// @as(i32, undefined)
1483// @as(i32, undefined)
1484// @as(@Vector(2, i32), undefined)
1485// @as(@Vector(2, i32), undefined)
1486// @as(i32, undefined)
1487// @as(@Vector(2, i32), undefined)
1488// @as(u32, undefined)
1489// @as(u32, undefined)
1490// @as(@Vector(2, u32), .{ 6, undefined })
1491// @as(@Vector(2, u32), .{ undefined, 6 })
1492// @as(@Vector(2, u32), undefined)
1493// @as(@Vector(2, u32), .{ 6, undefined })
1494// @as(@Vector(2, u32), .{ 6, undefined })
1495// @as(@Vector(2, u32), undefined)
1496// @as(@Vector(2, u32), undefined)
1497// @as(@Vector(2, u32), .{ undefined, 6 })
1498// @as(@Vector(2, u32), undefined)
1499// @as(@Vector(2, u32), .{ undefined, 6 })
1500// @as(@Vector(2, u32), undefined)
1501// @as(@Vector(2, u32), undefined)
1502// @as(@Vector(2, u32), undefined)
1503// @as(@Vector(2, u32), undefined)
1504// @as(@Vector(2, u32), undefined)
1505// @as(u32, undefined)
1506// @as(u32, undefined)
1507// @as(@Vector(2, u32), .{ 6, undefined })
1508// @as(@Vector(2, u32), .{ undefined, 6 })
1509// @as(@Vector(2, u32), undefined)
1510// @as(@Vector(2, u32), .{ 6, undefined })
1511// @as(@Vector(2, u32), .{ 6, undefined })
1512// @as(@Vector(2, u32), undefined)
1513// @as(@Vector(2, u32), undefined)
1514// @as(@Vector(2, u32), .{ undefined, 6 })
1515// @as(@Vector(2, u32), undefined)
1516// @as(@Vector(2, u32), .{ undefined, 6 })
1517// @as(@Vector(2, u32), undefined)
1518// @as(@Vector(2, u32), undefined)
1519// @as(@Vector(2, u32), undefined)
1520// @as(@Vector(2, u32), undefined)
1521// @as(@Vector(2, u32), undefined)
1522// @as(u32, undefined)
1523// @as(u32, undefined)
1524// @as(@Vector(2, u32), .{ 0, undefined })
1525// @as(@Vector(2, u32), .{ undefined, 0 })
1526// @as(@Vector(2, u32), undefined)
1527// @as(@Vector(2, u32), .{ 0, undefined })
1528// @as(@Vector(2, u32), .{ 0, undefined })
1529// @as(@Vector(2, u32), undefined)
1530// @as(@Vector(2, u32), undefined)
1531// @as(@Vector(2, u32), .{ undefined, 0 })
1532// @as(@Vector(2, u32), undefined)
1533// @as(@Vector(2, u32), .{ undefined, 0 })
1534// @as(@Vector(2, u32), undefined)
1535// @as(@Vector(2, u32), undefined)
1536// @as(@Vector(2, u32), undefined)
1537// @as(@Vector(2, u32), undefined)
1538// @as(@Vector(2, u32), undefined)
1539// @as(u32, undefined)
1540// @as(u32, undefined)
1541// @as(@Vector(2, u32), .{ 0, undefined })
1542// @as(@Vector(2, u32), .{ undefined, 0 })
1543// @as(@Vector(2, u32), undefined)
1544// @as(@Vector(2, u32), .{ 0, undefined })
1545// @as(@Vector(2, u32), .{ 0, undefined })
1546// @as(@Vector(2, u32), undefined)
1547// @as(@Vector(2, u32), undefined)
1548// @as(@Vector(2, u32), .{ undefined, 0 })
1549// @as(@Vector(2, u32), undefined)
1550// @as(@Vector(2, u32), .{ undefined, 0 })
1551// @as(@Vector(2, u32), undefined)
1552// @as(@Vector(2, u32), undefined)
1553// @as(@Vector(2, u32), undefined)
1554// @as(@Vector(2, u32), undefined)
1555// @as(@Vector(2, u32), undefined)
1556// @as(u32, undefined)
1557// @as(u32, undefined)
1558// @as(@Vector(2, u32), .{ 9, undefined })
1559// @as(@Vector(2, u32), .{ undefined, 9 })
1560// @as(@Vector(2, u32), undefined)
1561// @as(@Vector(2, u32), .{ 9, undefined })
1562// @as(@Vector(2, u32), .{ 9, undefined })
1563// @as(@Vector(2, u32), undefined)
1564// @as(@Vector(2, u32), undefined)
1565// @as(@Vector(2, u32), .{ undefined, 9 })
1566// @as(@Vector(2, u32), undefined)
1567// @as(@Vector(2, u32), .{ undefined, 9 })
1568// @as(@Vector(2, u32), undefined)
1569// @as(@Vector(2, u32), undefined)
1570// @as(@Vector(2, u32), undefined)
1571// @as(@Vector(2, u32), undefined)
1572// @as(@Vector(2, u32), undefined)
1573// @as(u32, undefined)
1574// @as(u32, undefined)
1575// @as(@Vector(2, u32), .{ 9, undefined })
1576// @as(@Vector(2, u32), .{ undefined, 9 })
1577// @as(@Vector(2, u32), undefined)
1578// @as(@Vector(2, u32), .{ 9, undefined })
1579// @as(@Vector(2, u32), .{ 9, undefined })
1580// @as(@Vector(2, u32), undefined)
1581// @as(@Vector(2, u32), undefined)
1582// @as(@Vector(2, u32), .{ undefined, 9 })
1583// @as(@Vector(2, u32), undefined)
1584// @as(@Vector(2, u32), .{ undefined, 9 })
1585// @as(@Vector(2, u32), undefined)
1586// @as(@Vector(2, u32), undefined)
1587// @as(@Vector(2, u32), undefined)
1588// @as(@Vector(2, u32), undefined)
1589// @as(@Vector(2, u32), undefined)
1590// @as(u32, undefined)
1591// @as(u32, undefined)
1592// @as(@Vector(2, u32), .{ 24, undefined })
1593// @as(@Vector(2, u32), .{ undefined, 24 })
1594// @as(@Vector(2, u32), undefined)
1595// @as(@Vector(2, u32), .{ 24, undefined })
1596// @as(@Vector(2, u32), .{ 24, undefined })
1597// @as(@Vector(2, u32), undefined)
1598// @as(@Vector(2, u32), undefined)
1599// @as(@Vector(2, u32), .{ undefined, 24 })
1600// @as(@Vector(2, u32), undefined)
1601// @as(@Vector(2, u32), .{ undefined, 24 })
1602// @as(@Vector(2, u32), undefined)
1603// @as(@Vector(2, u32), undefined)
1604// @as(@Vector(2, u32), undefined)
1605// @as(@Vector(2, u32), undefined)
1606// @as(@Vector(2, u32), undefined)
1607// @as(u32, undefined)
1608// @as(u32, undefined)
1609// @as(@Vector(2, u32), .{ 0, undefined })
1610// @as(@Vector(2, u32), .{ undefined, 0 })
1611// @as(@Vector(2, u32), undefined)
1612// @as(@Vector(2, u32), .{ 0, undefined })
1613// @as(@Vector(2, u32), .{ 0, undefined })
1614// @as(@Vector(2, u32), undefined)
1615// @as(@Vector(2, u32), undefined)
1616// @as(@Vector(2, u32), .{ undefined, 0 })
1617// @as(@Vector(2, u32), undefined)
1618// @as(@Vector(2, u32), .{ undefined, 0 })
1619// @as(@Vector(2, u32), undefined)
1620// @as(@Vector(2, u32), undefined)
1621// @as(@Vector(2, u32), undefined)
1622// @as(@Vector(2, u32), undefined)
1623// @as(@Vector(2, u32), undefined)
1624// @as(u32, undefined)
1625// @as(@Vector(2, u32), undefined)
1626// @as(u32, undefined)
1627// @as(u32, undefined)
1628// @as(@Vector(2, u32), undefined)
1629// @as(@Vector(2, u32), undefined)
1630// @as(u1, undefined)
1631// @as(@Vector(2, u1), .{ 1, undefined })
1632// @as(@Vector(2, u1), .{ undefined, 1 })
1633// @as(@Vector(2, u1), undefined)
1634// @as(u32, undefined)
1635// @as(@Vector(2, u32), undefined)
1636// @as(u32, undefined)
1637// @as(u32, undefined)
1638// @as(@Vector(2, u32), [runtime value])
1639// @as(@Vector(2, u32), [runtime value])
1640// @as(@Vector(2, u32), undefined)
1641// @as(@Vector(2, u32), [runtime value])
1642// @as(@Vector(2, u32), [runtime value])
1643// @as(@Vector(2, u32), [runtime value])
1644// @as(@Vector(2, u32), undefined)
1645// @as(@Vector(2, u32), [runtime value])
1646// @as(@Vector(2, u32), [runtime value])
1647// @as(@Vector(2, u32), [runtime value])
1648// @as(@Vector(2, u32), undefined)
1649// @as(@Vector(2, u32), undefined)
1650// @as(@Vector(2, u32), undefined)
1651// @as(@Vector(2, u32), undefined)
1652// @as(@Vector(2, u32), undefined)
1653// @as(u32, undefined)
1654// @as(u32, undefined)
1655// @as(@Vector(2, u32), [runtime value])
1656// @as(@Vector(2, u32), [runtime value])
1657// @as(@Vector(2, u32), undefined)
1658// @as(@Vector(2, u32), [runtime value])
1659// @as(@Vector(2, u32), [runtime value])
1660// @as(@Vector(2, u32), [runtime value])
1661// @as(@Vector(2, u32), undefined)
1662// @as(@Vector(2, u32), [runtime value])
1663// @as(@Vector(2, u32), [runtime value])
1664// @as(@Vector(2, u32), [runtime value])
1665// @as(@Vector(2, u32), undefined)
1666// @as(@Vector(2, u32), undefined)
1667// @as(@Vector(2, u32), undefined)
1668// @as(@Vector(2, u32), undefined)
1669// @as(@Vector(2, u32), undefined)
1670// @as(u32, undefined)
1671// @as(u32, undefined)
1672// @as(@Vector(2, u32), [runtime value])
1673// @as(@Vector(2, u32), [runtime value])
1674// @as(@Vector(2, u32), undefined)
1675// @as(@Vector(2, u32), [runtime value])
1676// @as(@Vector(2, u32), [runtime value])
1677// @as(@Vector(2, u32), [runtime value])
1678// @as(@Vector(2, u32), undefined)
1679// @as(@Vector(2, u32), [runtime value])
1680// @as(@Vector(2, u32), [runtime value])
1681// @as(@Vector(2, u32), [runtime value])
1682// @as(@Vector(2, u32), undefined)
1683// @as(@Vector(2, u32), undefined)
1684// @as(@Vector(2, u32), undefined)
1685// @as(@Vector(2, u32), undefined)
1686// @as(@Vector(2, u32), undefined)
1687// @as(u32, undefined)
1688// @as(u32, undefined)
1689// @as(@Vector(2, u32), [runtime value])
1690// @as(@Vector(2, u32), [runtime value])
1691// @as(@Vector(2, u32), undefined)
1692// @as(@Vector(2, u32), [runtime value])
1693// @as(@Vector(2, u32), [runtime value])
1694// @as(@Vector(2, u32), [runtime value])
1695// @as(@Vector(2, u32), undefined)
1696// @as(@Vector(2, u32), [runtime value])
1697// @as(@Vector(2, u32), [runtime value])
1698// @as(@Vector(2, u32), [runtime value])
1699// @as(@Vector(2, u32), undefined)
1700// @as(@Vector(2, u32), undefined)
1701// @as(@Vector(2, u32), undefined)
1702// @as(@Vector(2, u32), undefined)
1703// @as(@Vector(2, u32), undefined)
1704// @as(u32, undefined)
1705// @as(u32, undefined)
1706// @as(@Vector(2, u32), [runtime value])
1707// @as(@Vector(2, u32), [runtime value])
1708// @as(@Vector(2, u32), undefined)
1709// @as(@Vector(2, u32), [runtime value])
1710// @as(@Vector(2, u32), [runtime value])
1711// @as(@Vector(2, u32), [runtime value])
1712// @as(@Vector(2, u32), undefined)
1713// @as(@Vector(2, u32), [runtime value])
1714// @as(@Vector(2, u32), [runtime value])
1715// @as(@Vector(2, u32), [runtime value])
1716// @as(@Vector(2, u32), undefined)
1717// @as(@Vector(2, u32), undefined)
1718// @as(@Vector(2, u32), undefined)
1719// @as(@Vector(2, u32), undefined)
1720// @as(@Vector(2, u32), undefined)
1721// @as(u32, undefined)
1722// @as(u32, undefined)
1723// @as(@Vector(2, u32), [runtime value])
1724// @as(@Vector(2, u32), [runtime value])
1725// @as(@Vector(2, u32), undefined)
1726// @as(@Vector(2, u32), [runtime value])
1727// @as(@Vector(2, u32), [runtime value])
1728// @as(@Vector(2, u32), [runtime value])
1729// @as(@Vector(2, u32), undefined)
1730// @as(@Vector(2, u32), [runtime value])
1731// @as(@Vector(2, u32), [runtime value])
1732// @as(@Vector(2, u32), [runtime value])
1733// @as(@Vector(2, u32), undefined)
1734// @as(@Vector(2, u32), undefined)
1735// @as(@Vector(2, u32), undefined)
1736// @as(@Vector(2, u32), undefined)
1737// @as(@Vector(2, u32), undefined)
1738// @as(u32, undefined)
1739// @as(u32, undefined)
1740// @as(@Vector(2, u32), [runtime value])
1741// @as(@Vector(2, u32), [runtime value])
1742// @as(@Vector(2, u32), undefined)
1743// @as(@Vector(2, u32), [runtime value])
1744// @as(@Vector(2, u32), [runtime value])
1745// @as(@Vector(2, u32), [runtime value])
1746// @as(@Vector(2, u32), undefined)
1747// @as(@Vector(2, u32), [runtime value])
1748// @as(@Vector(2, u32), [runtime value])
1749// @as(@Vector(2, u32), [runtime value])
1750// @as(@Vector(2, u32), undefined)
1751// @as(@Vector(2, u32), undefined)
1752// @as(@Vector(2, u32), undefined)
1753// @as(@Vector(2, u32), undefined)
1754// @as(@Vector(2, u32), undefined)
1755// @as(u32, [runtime value])
1756// @as(u32, [runtime value])
1757// @as(@Vector(2, u32), [runtime value])
1758// @as(@Vector(2, u32), [runtime value])
1759// @as(@Vector(2, u32), [runtime value])
1760// @as(@Vector(2, u32), [runtime value])
1761// @as(@Vector(2, u32), [runtime value])
1762// @as(@Vector(2, u32), [runtime value])
1763// @as(@Vector(2, u32), [runtime value])
1764// @as(@Vector(2, u32), [runtime value])
1765// @as(@Vector(2, u32), [runtime value])
1766// @as(@Vector(2, u32), [runtime value])
1767// @as(@Vector(2, u32), [runtime value])
1768// @as(@Vector(2, u32), [runtime value])
1769// @as(@Vector(2, u32), [runtime value])
1770// @as(@Vector(2, u32), [runtime value])
1771// @as(@Vector(2, u32), undefined)
1772// @as(u32, undefined)
1773// @as(@Vector(2, u32), undefined)
1774// @as(u32, undefined)
1775// @as(u32, undefined)
1776// @as(@Vector(2, u32), undefined)
1777// @as(@Vector(2, u32), undefined)
1778// @as(u1, undefined)
1779// @as(@Vector(2, u1), [runtime value])
1780// @as(@Vector(2, u1), [runtime value])
1781// @as(@Vector(2, u1), undefined)
1782// @as(u32, undefined)
1783// @as(@Vector(2, u32), undefined)
1784// @as(i8, undefined)
1785// @as(i8, undefined)
1786// @as(@Vector(2, i8), .{ 6, undefined })
1787// @as(@Vector(2, i8), .{ undefined, 6 })
1788// @as(@Vector(2, i8), undefined)
1789// @as(@Vector(2, i8), .{ 6, undefined })
1790// @as(@Vector(2, i8), .{ 6, undefined })
1791// @as(@Vector(2, i8), undefined)
1792// @as(@Vector(2, i8), undefined)
1793// @as(@Vector(2, i8), .{ undefined, 6 })
1794// @as(@Vector(2, i8), undefined)
1795// @as(@Vector(2, i8), .{ undefined, 6 })
1796// @as(@Vector(2, i8), undefined)
1797// @as(@Vector(2, i8), undefined)
1798// @as(@Vector(2, i8), undefined)
1799// @as(@Vector(2, i8), undefined)
1800// @as(@Vector(2, i8), undefined)
1801// @as(i8, undefined)
1802// @as(i8, undefined)
1803// @as(@Vector(2, i8), .{ 6, undefined })
1804// @as(@Vector(2, i8), .{ undefined, 6 })
1805// @as(@Vector(2, i8), undefined)
1806// @as(@Vector(2, i8), .{ 6, undefined })
1807// @as(@Vector(2, i8), .{ 6, undefined })
1808// @as(@Vector(2, i8), undefined)
1809// @as(@Vector(2, i8), undefined)
1810// @as(@Vector(2, i8), .{ undefined, 6 })
1811// @as(@Vector(2, i8), undefined)
1812// @as(@Vector(2, i8), .{ undefined, 6 })
1813// @as(@Vector(2, i8), undefined)
1814// @as(@Vector(2, i8), undefined)
1815// @as(@Vector(2, i8), undefined)
1816// @as(@Vector(2, i8), undefined)
1817// @as(@Vector(2, i8), undefined)
1818// @as(i8, undefined)
1819// @as(i8, undefined)
1820// @as(@Vector(2, i8), .{ 0, undefined })
1821// @as(@Vector(2, i8), .{ undefined, 0 })
1822// @as(@Vector(2, i8), undefined)
1823// @as(@Vector(2, i8), .{ 0, undefined })
1824// @as(@Vector(2, i8), .{ 0, undefined })
1825// @as(@Vector(2, i8), undefined)
1826// @as(@Vector(2, i8), undefined)
1827// @as(@Vector(2, i8), .{ undefined, 0 })
1828// @as(@Vector(2, i8), undefined)
1829// @as(@Vector(2, i8), .{ undefined, 0 })
1830// @as(@Vector(2, i8), undefined)
1831// @as(@Vector(2, i8), undefined)
1832// @as(@Vector(2, i8), undefined)
1833// @as(@Vector(2, i8), undefined)
1834// @as(@Vector(2, i8), undefined)
1835// @as(i8, undefined)
1836// @as(i8, undefined)
1837// @as(@Vector(2, i8), .{ 0, undefined })
1838// @as(@Vector(2, i8), .{ undefined, 0 })
1839// @as(@Vector(2, i8), undefined)
1840// @as(@Vector(2, i8), .{ 0, undefined })
1841// @as(@Vector(2, i8), .{ 0, undefined })
1842// @as(@Vector(2, i8), undefined)
1843// @as(@Vector(2, i8), undefined)
1844// @as(@Vector(2, i8), .{ undefined, 0 })
1845// @as(@Vector(2, i8), undefined)
1846// @as(@Vector(2, i8), .{ undefined, 0 })
1847// @as(@Vector(2, i8), undefined)
1848// @as(@Vector(2, i8), undefined)
1849// @as(@Vector(2, i8), undefined)
1850// @as(@Vector(2, i8), undefined)
1851// @as(@Vector(2, i8), undefined)
1852// @as(i8, undefined)
1853// @as(i8, undefined)
1854// @as(@Vector(2, i8), .{ 9, undefined })
1855// @as(@Vector(2, i8), .{ undefined, 9 })
1856// @as(@Vector(2, i8), undefined)
1857// @as(@Vector(2, i8), .{ 9, undefined })
1858// @as(@Vector(2, i8), .{ 9, undefined })
1859// @as(@Vector(2, i8), undefined)
1860// @as(@Vector(2, i8), undefined)
1861// @as(@Vector(2, i8), .{ undefined, 9 })
1862// @as(@Vector(2, i8), undefined)
1863// @as(@Vector(2, i8), .{ undefined, 9 })
1864// @as(@Vector(2, i8), undefined)
1865// @as(@Vector(2, i8), undefined)
1866// @as(@Vector(2, i8), undefined)
1867// @as(@Vector(2, i8), undefined)
1868// @as(@Vector(2, i8), undefined)
1869// @as(i8, undefined)
1870// @as(i8, undefined)
1871// @as(@Vector(2, i8), .{ 9, undefined })
1872// @as(@Vector(2, i8), .{ undefined, 9 })
1873// @as(@Vector(2, i8), undefined)
1874// @as(@Vector(2, i8), .{ 9, undefined })
1875// @as(@Vector(2, i8), .{ 9, undefined })
1876// @as(@Vector(2, i8), undefined)
1877// @as(@Vector(2, i8), undefined)
1878// @as(@Vector(2, i8), .{ undefined, 9 })
1879// @as(@Vector(2, i8), undefined)
1880// @as(@Vector(2, i8), .{ undefined, 9 })
1881// @as(@Vector(2, i8), undefined)
1882// @as(@Vector(2, i8), undefined)
1883// @as(@Vector(2, i8), undefined)
1884// @as(@Vector(2, i8), undefined)
1885// @as(@Vector(2, i8), undefined)
1886// @as(i8, undefined)
1887// @as(i8, undefined)
1888// @as(@Vector(2, i8), .{ 0, undefined })
1889// @as(@Vector(2, i8), .{ undefined, 0 })
1890// @as(@Vector(2, i8), undefined)
1891// @as(@Vector(2, i8), .{ 0, undefined })
1892// @as(@Vector(2, i8), .{ 0, undefined })
1893// @as(@Vector(2, i8), undefined)
1894// @as(@Vector(2, i8), undefined)
1895// @as(@Vector(2, i8), .{ undefined, 0 })
1896// @as(@Vector(2, i8), undefined)
1897// @as(@Vector(2, i8), .{ undefined, 0 })
1898// @as(@Vector(2, i8), undefined)
1899// @as(@Vector(2, i8), undefined)
1900// @as(@Vector(2, i8), undefined)
1901// @as(@Vector(2, i8), undefined)
1902// @as(@Vector(2, i8), undefined)
1903// @as(i8, undefined)
1904// @as(@Vector(2, i8), undefined)
1905// @as(i8, undefined)
1906// @as(i8, undefined)
1907// @as(@Vector(2, i8), undefined)
1908// @as(@Vector(2, i8), undefined)
1909// @as(i8, undefined)
1910// @as(@Vector(2, i8), undefined)
1911// @as(i8, undefined)
1912// @as(i8, undefined)
1913// @as(@Vector(2, i8), [runtime value])
1914// @as(@Vector(2, i8), [runtime value])
1915// @as(@Vector(2, i8), undefined)
1916// @as(@Vector(2, i8), [runtime value])
1917// @as(@Vector(2, i8), [runtime value])
1918// @as(@Vector(2, i8), [runtime value])
1919// @as(@Vector(2, i8), undefined)
1920// @as(@Vector(2, i8), [runtime value])
1921// @as(@Vector(2, i8), [runtime value])
1922// @as(@Vector(2, i8), [runtime value])
1923// @as(@Vector(2, i8), undefined)
1924// @as(@Vector(2, i8), undefined)
1925// @as(@Vector(2, i8), undefined)
1926// @as(@Vector(2, i8), undefined)
1927// @as(@Vector(2, i8), undefined)
1928// @as(i8, undefined)
1929// @as(i8, undefined)
1930// @as(@Vector(2, i8), [runtime value])
1931// @as(@Vector(2, i8), [runtime value])
1932// @as(@Vector(2, i8), undefined)
1933// @as(@Vector(2, i8), [runtime value])
1934// @as(@Vector(2, i8), [runtime value])
1935// @as(@Vector(2, i8), [runtime value])
1936// @as(@Vector(2, i8), undefined)
1937// @as(@Vector(2, i8), [runtime value])
1938// @as(@Vector(2, i8), [runtime value])
1939// @as(@Vector(2, i8), [runtime value])
1940// @as(@Vector(2, i8), undefined)
1941// @as(@Vector(2, i8), undefined)
1942// @as(@Vector(2, i8), undefined)
1943// @as(@Vector(2, i8), undefined)
1944// @as(@Vector(2, i8), undefined)
1945// @as(i8, undefined)
1946// @as(i8, undefined)
1947// @as(@Vector(2, i8), [runtime value])
1948// @as(@Vector(2, i8), [runtime value])
1949// @as(@Vector(2, i8), undefined)
1950// @as(@Vector(2, i8), [runtime value])
1951// @as(@Vector(2, i8), [runtime value])
1952// @as(@Vector(2, i8), [runtime value])
1953// @as(@Vector(2, i8), undefined)
1954// @as(@Vector(2, i8), [runtime value])
1955// @as(@Vector(2, i8), [runtime value])
1956// @as(@Vector(2, i8), [runtime value])
1957// @as(@Vector(2, i8), undefined)
1958// @as(@Vector(2, i8), undefined)
1959// @as(@Vector(2, i8), undefined)
1960// @as(@Vector(2, i8), undefined)
1961// @as(@Vector(2, i8), undefined)
1962// @as(i8, undefined)
1963// @as(i8, undefined)
1964// @as(@Vector(2, i8), [runtime value])
1965// @as(@Vector(2, i8), [runtime value])
1966// @as(@Vector(2, i8), undefined)
1967// @as(@Vector(2, i8), [runtime value])
1968// @as(@Vector(2, i8), [runtime value])
1969// @as(@Vector(2, i8), [runtime value])
1970// @as(@Vector(2, i8), undefined)
1971// @as(@Vector(2, i8), [runtime value])
1972// @as(@Vector(2, i8), [runtime value])
1973// @as(@Vector(2, i8), [runtime value])
1974// @as(@Vector(2, i8), undefined)
1975// @as(@Vector(2, i8), undefined)
1976// @as(@Vector(2, i8), undefined)
1977// @as(@Vector(2, i8), undefined)
1978// @as(@Vector(2, i8), undefined)
1979// @as(i8, undefined)
1980// @as(i8, undefined)
1981// @as(@Vector(2, i8), [runtime value])
1982// @as(@Vector(2, i8), [runtime value])
1983// @as(@Vector(2, i8), undefined)
1984// @as(@Vector(2, i8), [runtime value])
1985// @as(@Vector(2, i8), [runtime value])
1986// @as(@Vector(2, i8), [runtime value])
1987// @as(@Vector(2, i8), undefined)
1988// @as(@Vector(2, i8), [runtime value])
1989// @as(@Vector(2, i8), [runtime value])
1990// @as(@Vector(2, i8), [runtime value])
1991// @as(@Vector(2, i8), undefined)
1992// @as(@Vector(2, i8), undefined)
1993// @as(@Vector(2, i8), undefined)
1994// @as(@Vector(2, i8), undefined)
1995// @as(@Vector(2, i8), undefined)
1996// @as(i8, undefined)
1997// @as(i8, undefined)
1998// @as(@Vector(2, i8), [runtime value])
1999// @as(@Vector(2, i8), [runtime value])
2000// @as(@Vector(2, i8), undefined)
2001// @as(@Vector(2, i8), [runtime value])
2002// @as(@Vector(2, i8), [runtime value])
2003// @as(@Vector(2, i8), [runtime value])
2004// @as(@Vector(2, i8), undefined)
2005// @as(@Vector(2, i8), [runtime value])
2006// @as(@Vector(2, i8), [runtime value])
2007// @as(@Vector(2, i8), [runtime value])
2008// @as(@Vector(2, i8), undefined)
2009// @as(@Vector(2, i8), undefined)
2010// @as(@Vector(2, i8), undefined)
2011// @as(@Vector(2, i8), undefined)
2012// @as(@Vector(2, i8), undefined)
2013// @as(i8, [runtime value])
2014// @as(i8, [runtime value])
2015// @as(@Vector(2, i8), [runtime value])
2016// @as(@Vector(2, i8), [runtime value])
2017// @as(@Vector(2, i8), [runtime value])
2018// @as(@Vector(2, i8), [runtime value])
2019// @as(@Vector(2, i8), [runtime value])
2020// @as(@Vector(2, i8), [runtime value])
2021// @as(@Vector(2, i8), [runtime value])
2022// @as(@Vector(2, i8), [runtime value])
2023// @as(@Vector(2, i8), [runtime value])
2024// @as(@Vector(2, i8), [runtime value])
2025// @as(@Vector(2, i8), [runtime value])
2026// @as(@Vector(2, i8), [runtime value])
2027// @as(@Vector(2, i8), [runtime value])
2028// @as(@Vector(2, i8), [runtime value])
2029// @as(@Vector(2, i8), undefined)
2030// @as(i8, undefined)
2031// @as(@Vector(2, i8), undefined)
2032// @as(i8, undefined)
2033// @as(i8, undefined)
2034// @as(@Vector(2, i8), undefined)
2035// @as(@Vector(2, i8), undefined)
2036// @as(i8, undefined)
2037// @as(@Vector(2, i8), undefined)
24782038// @as(f128, undefined)
24792039// @as(f128, undefined)
24802040// @as(@Vector(2, f128), .{ 6, undefined })
......@@ -2585,3 +2145,443 @@ inline fn testFloatWithValue(comptime Float: type, x: Float) void {
25852145// @as(@Vector(2, f128), [runtime value])
25862146// @as(@Vector(2, f128), [runtime value])
25872147// @as(@Vector(2, f128), undefined)
2148// @as(f80, undefined)
2149// @as(f80, undefined)
2150// @as(@Vector(2, f80), .{ 6, undefined })
2151// @as(@Vector(2, f80), .{ undefined, 6 })
2152// @as(@Vector(2, f80), undefined)
2153// @as(@Vector(2, f80), .{ 6, undefined })
2154// @as(@Vector(2, f80), .{ 6, undefined })
2155// @as(@Vector(2, f80), undefined)
2156// @as(@Vector(2, f80), undefined)
2157// @as(@Vector(2, f80), .{ undefined, 6 })
2158// @as(@Vector(2, f80), undefined)
2159// @as(@Vector(2, f80), .{ undefined, 6 })
2160// @as(@Vector(2, f80), undefined)
2161// @as(@Vector(2, f80), undefined)
2162// @as(@Vector(2, f80), undefined)
2163// @as(@Vector(2, f80), undefined)
2164// @as(@Vector(2, f80), undefined)
2165// @as(f80, undefined)
2166// @as(f80, undefined)
2167// @as(@Vector(2, f80), .{ 0, undefined })
2168// @as(@Vector(2, f80), .{ undefined, 0 })
2169// @as(@Vector(2, f80), undefined)
2170// @as(@Vector(2, f80), .{ 0, undefined })
2171// @as(@Vector(2, f80), .{ 0, undefined })
2172// @as(@Vector(2, f80), undefined)
2173// @as(@Vector(2, f80), undefined)
2174// @as(@Vector(2, f80), .{ undefined, 0 })
2175// @as(@Vector(2, f80), undefined)
2176// @as(@Vector(2, f80), .{ undefined, 0 })
2177// @as(@Vector(2, f80), undefined)
2178// @as(@Vector(2, f80), undefined)
2179// @as(@Vector(2, f80), undefined)
2180// @as(@Vector(2, f80), undefined)
2181// @as(@Vector(2, f80), undefined)
2182// @as(f80, undefined)
2183// @as(f80, undefined)
2184// @as(@Vector(2, f80), .{ 9, undefined })
2185// @as(@Vector(2, f80), .{ undefined, 9 })
2186// @as(@Vector(2, f80), undefined)
2187// @as(@Vector(2, f80), .{ 9, undefined })
2188// @as(@Vector(2, f80), .{ 9, undefined })
2189// @as(@Vector(2, f80), undefined)
2190// @as(@Vector(2, f80), undefined)
2191// @as(@Vector(2, f80), .{ undefined, 9 })
2192// @as(@Vector(2, f80), undefined)
2193// @as(@Vector(2, f80), .{ undefined, 9 })
2194// @as(@Vector(2, f80), undefined)
2195// @as(@Vector(2, f80), undefined)
2196// @as(@Vector(2, f80), undefined)
2197// @as(@Vector(2, f80), undefined)
2198// @as(@Vector(2, f80), undefined)
2199// @as(f80, undefined)
2200// @as(@Vector(2, f80), .{ -3, undefined })
2201// @as(@Vector(2, f80), .{ undefined, -3 })
2202// @as(@Vector(2, f80), undefined)
2203// @as(f80, undefined)
2204// @as(f80, undefined)
2205// @as(@Vector(2, f80), [runtime value])
2206// @as(@Vector(2, f80), [runtime value])
2207// @as(@Vector(2, f80), undefined)
2208// @as(@Vector(2, f80), [runtime value])
2209// @as(@Vector(2, f80), [runtime value])
2210// @as(@Vector(2, f80), [runtime value])
2211// @as(@Vector(2, f80), undefined)
2212// @as(@Vector(2, f80), [runtime value])
2213// @as(@Vector(2, f80), [runtime value])
2214// @as(@Vector(2, f80), [runtime value])
2215// @as(@Vector(2, f80), undefined)
2216// @as(@Vector(2, f80), undefined)
2217// @as(@Vector(2, f80), undefined)
2218// @as(@Vector(2, f80), undefined)
2219// @as(@Vector(2, f80), undefined)
2220// @as(f80, undefined)
2221// @as(f80, undefined)
2222// @as(@Vector(2, f80), [runtime value])
2223// @as(@Vector(2, f80), [runtime value])
2224// @as(@Vector(2, f80), undefined)
2225// @as(@Vector(2, f80), [runtime value])
2226// @as(@Vector(2, f80), [runtime value])
2227// @as(@Vector(2, f80), [runtime value])
2228// @as(@Vector(2, f80), undefined)
2229// @as(@Vector(2, f80), [runtime value])
2230// @as(@Vector(2, f80), [runtime value])
2231// @as(@Vector(2, f80), [runtime value])
2232// @as(@Vector(2, f80), undefined)
2233// @as(@Vector(2, f80), undefined)
2234// @as(@Vector(2, f80), undefined)
2235// @as(@Vector(2, f80), undefined)
2236// @as(@Vector(2, f80), undefined)
2237// @as(f80, undefined)
2238// @as(f80, undefined)
2239// @as(@Vector(2, f80), [runtime value])
2240// @as(@Vector(2, f80), [runtime value])
2241// @as(@Vector(2, f80), undefined)
2242// @as(@Vector(2, f80), [runtime value])
2243// @as(@Vector(2, f80), [runtime value])
2244// @as(@Vector(2, f80), [runtime value])
2245// @as(@Vector(2, f80), undefined)
2246// @as(@Vector(2, f80), [runtime value])
2247// @as(@Vector(2, f80), [runtime value])
2248// @as(@Vector(2, f80), [runtime value])
2249// @as(@Vector(2, f80), undefined)
2250// @as(@Vector(2, f80), undefined)
2251// @as(@Vector(2, f80), undefined)
2252// @as(@Vector(2, f80), undefined)
2253// @as(@Vector(2, f80), undefined)
2254// @as(f80, undefined)
2255// @as(@Vector(2, f80), [runtime value])
2256// @as(@Vector(2, f80), [runtime value])
2257// @as(@Vector(2, f80), undefined)
2258// @as(f64, undefined)
2259// @as(f64, undefined)
2260// @as(@Vector(2, f64), .{ 6, undefined })
2261// @as(@Vector(2, f64), .{ undefined, 6 })
2262// @as(@Vector(2, f64), undefined)
2263// @as(@Vector(2, f64), .{ 6, undefined })
2264// @as(@Vector(2, f64), .{ 6, undefined })
2265// @as(@Vector(2, f64), undefined)
2266// @as(@Vector(2, f64), undefined)
2267// @as(@Vector(2, f64), .{ undefined, 6 })
2268// @as(@Vector(2, f64), undefined)
2269// @as(@Vector(2, f64), .{ undefined, 6 })
2270// @as(@Vector(2, f64), undefined)
2271// @as(@Vector(2, f64), undefined)
2272// @as(@Vector(2, f64), undefined)
2273// @as(@Vector(2, f64), undefined)
2274// @as(@Vector(2, f64), undefined)
2275// @as(f64, undefined)
2276// @as(f64, undefined)
2277// @as(@Vector(2, f64), .{ 0, undefined })
2278// @as(@Vector(2, f64), .{ undefined, 0 })
2279// @as(@Vector(2, f64), undefined)
2280// @as(@Vector(2, f64), .{ 0, undefined })
2281// @as(@Vector(2, f64), .{ 0, undefined })
2282// @as(@Vector(2, f64), undefined)
2283// @as(@Vector(2, f64), undefined)
2284// @as(@Vector(2, f64), .{ undefined, 0 })
2285// @as(@Vector(2, f64), undefined)
2286// @as(@Vector(2, f64), .{ undefined, 0 })
2287// @as(@Vector(2, f64), undefined)
2288// @as(@Vector(2, f64), undefined)
2289// @as(@Vector(2, f64), undefined)
2290// @as(@Vector(2, f64), undefined)
2291// @as(@Vector(2, f64), undefined)
2292// @as(f64, undefined)
2293// @as(f64, undefined)
2294// @as(@Vector(2, f64), .{ 9, undefined })
2295// @as(@Vector(2, f64), .{ undefined, 9 })
2296// @as(@Vector(2, f64), undefined)
2297// @as(@Vector(2, f64), .{ 9, undefined })
2298// @as(@Vector(2, f64), .{ 9, undefined })
2299// @as(@Vector(2, f64), undefined)
2300// @as(@Vector(2, f64), undefined)
2301// @as(@Vector(2, f64), .{ undefined, 9 })
2302// @as(@Vector(2, f64), undefined)
2303// @as(@Vector(2, f64), .{ undefined, 9 })
2304// @as(@Vector(2, f64), undefined)
2305// @as(@Vector(2, f64), undefined)
2306// @as(@Vector(2, f64), undefined)
2307// @as(@Vector(2, f64), undefined)
2308// @as(@Vector(2, f64), undefined)
2309// @as(f64, undefined)
2310// @as(@Vector(2, f64), .{ -3, undefined })
2311// @as(@Vector(2, f64), .{ undefined, -3 })
2312// @as(@Vector(2, f64), undefined)
2313// @as(f64, undefined)
2314// @as(f64, undefined)
2315// @as(@Vector(2, f64), [runtime value])
2316// @as(@Vector(2, f64), [runtime value])
2317// @as(@Vector(2, f64), undefined)
2318// @as(@Vector(2, f64), [runtime value])
2319// @as(@Vector(2, f64), [runtime value])
2320// @as(@Vector(2, f64), [runtime value])
2321// @as(@Vector(2, f64), undefined)
2322// @as(@Vector(2, f64), [runtime value])
2323// @as(@Vector(2, f64), [runtime value])
2324// @as(@Vector(2, f64), [runtime value])
2325// @as(@Vector(2, f64), undefined)
2326// @as(@Vector(2, f64), undefined)
2327// @as(@Vector(2, f64), undefined)
2328// @as(@Vector(2, f64), undefined)
2329// @as(@Vector(2, f64), undefined)
2330// @as(f64, undefined)
2331// @as(f64, undefined)
2332// @as(@Vector(2, f64), [runtime value])
2333// @as(@Vector(2, f64), [runtime value])
2334// @as(@Vector(2, f64), undefined)
2335// @as(@Vector(2, f64), [runtime value])
2336// @as(@Vector(2, f64), [runtime value])
2337// @as(@Vector(2, f64), [runtime value])
2338// @as(@Vector(2, f64), undefined)
2339// @as(@Vector(2, f64), [runtime value])
2340// @as(@Vector(2, f64), [runtime value])
2341// @as(@Vector(2, f64), [runtime value])
2342// @as(@Vector(2, f64), undefined)
2343// @as(@Vector(2, f64), undefined)
2344// @as(@Vector(2, f64), undefined)
2345// @as(@Vector(2, f64), undefined)
2346// @as(@Vector(2, f64), undefined)
2347// @as(f64, undefined)
2348// @as(f64, undefined)
2349// @as(@Vector(2, f64), [runtime value])
2350// @as(@Vector(2, f64), [runtime value])
2351// @as(@Vector(2, f64), undefined)
2352// @as(@Vector(2, f64), [runtime value])
2353// @as(@Vector(2, f64), [runtime value])
2354// @as(@Vector(2, f64), [runtime value])
2355// @as(@Vector(2, f64), undefined)
2356// @as(@Vector(2, f64), [runtime value])
2357// @as(@Vector(2, f64), [runtime value])
2358// @as(@Vector(2, f64), [runtime value])
2359// @as(@Vector(2, f64), undefined)
2360// @as(@Vector(2, f64), undefined)
2361// @as(@Vector(2, f64), undefined)
2362// @as(@Vector(2, f64), undefined)
2363// @as(@Vector(2, f64), undefined)
2364// @as(f64, undefined)
2365// @as(@Vector(2, f64), [runtime value])
2366// @as(@Vector(2, f64), [runtime value])
2367// @as(@Vector(2, f64), undefined)
2368// @as(f32, undefined)
2369// @as(f32, undefined)
2370// @as(@Vector(2, f32), .{ 6, undefined })
2371// @as(@Vector(2, f32), .{ undefined, 6 })
2372// @as(@Vector(2, f32), undefined)
2373// @as(@Vector(2, f32), .{ 6, undefined })
2374// @as(@Vector(2, f32), .{ 6, undefined })
2375// @as(@Vector(2, f32), undefined)
2376// @as(@Vector(2, f32), undefined)
2377// @as(@Vector(2, f32), .{ undefined, 6 })
2378// @as(@Vector(2, f32), undefined)
2379// @as(@Vector(2, f32), .{ undefined, 6 })
2380// @as(@Vector(2, f32), undefined)
2381// @as(@Vector(2, f32), undefined)
2382// @as(@Vector(2, f32), undefined)
2383// @as(@Vector(2, f32), undefined)
2384// @as(@Vector(2, f32), undefined)
2385// @as(f32, undefined)
2386// @as(f32, undefined)
2387// @as(@Vector(2, f32), .{ 0, undefined })
2388// @as(@Vector(2, f32), .{ undefined, 0 })
2389// @as(@Vector(2, f32), undefined)
2390// @as(@Vector(2, f32), .{ 0, undefined })
2391// @as(@Vector(2, f32), .{ 0, undefined })
2392// @as(@Vector(2, f32), undefined)
2393// @as(@Vector(2, f32), undefined)
2394// @as(@Vector(2, f32), .{ undefined, 0 })
2395// @as(@Vector(2, f32), undefined)
2396// @as(@Vector(2, f32), .{ undefined, 0 })
2397// @as(@Vector(2, f32), undefined)
2398// @as(@Vector(2, f32), undefined)
2399// @as(@Vector(2, f32), undefined)
2400// @as(@Vector(2, f32), undefined)
2401// @as(@Vector(2, f32), undefined)
2402// @as(f32, undefined)
2403// @as(f32, undefined)
2404// @as(@Vector(2, f32), .{ 9, undefined })
2405// @as(@Vector(2, f32), .{ undefined, 9 })
2406// @as(@Vector(2, f32), undefined)
2407// @as(@Vector(2, f32), .{ 9, undefined })
2408// @as(@Vector(2, f32), .{ 9, undefined })
2409// @as(@Vector(2, f32), undefined)
2410// @as(@Vector(2, f32), undefined)
2411// @as(@Vector(2, f32), .{ undefined, 9 })
2412// @as(@Vector(2, f32), undefined)
2413// @as(@Vector(2, f32), .{ undefined, 9 })
2414// @as(@Vector(2, f32), undefined)
2415// @as(@Vector(2, f32), undefined)
2416// @as(@Vector(2, f32), undefined)
2417// @as(@Vector(2, f32), undefined)
2418// @as(@Vector(2, f32), undefined)
2419// @as(f32, undefined)
2420// @as(@Vector(2, f32), .{ -3, undefined })
2421// @as(@Vector(2, f32), .{ undefined, -3 })
2422// @as(@Vector(2, f32), undefined)
2423// @as(f32, undefined)
2424// @as(f32, undefined)
2425// @as(@Vector(2, f32), [runtime value])
2426// @as(@Vector(2, f32), [runtime value])
2427// @as(@Vector(2, f32), undefined)
2428// @as(@Vector(2, f32), [runtime value])
2429// @as(@Vector(2, f32), [runtime value])
2430// @as(@Vector(2, f32), [runtime value])
2431// @as(@Vector(2, f32), undefined)
2432// @as(@Vector(2, f32), [runtime value])
2433// @as(@Vector(2, f32), [runtime value])
2434// @as(@Vector(2, f32), [runtime value])
2435// @as(@Vector(2, f32), undefined)
2436// @as(@Vector(2, f32), undefined)
2437// @as(@Vector(2, f32), undefined)
2438// @as(@Vector(2, f32), undefined)
2439// @as(@Vector(2, f32), undefined)
2440// @as(f32, undefined)
2441// @as(f32, undefined)
2442// @as(@Vector(2, f32), [runtime value])
2443// @as(@Vector(2, f32), [runtime value])
2444// @as(@Vector(2, f32), undefined)
2445// @as(@Vector(2, f32), [runtime value])
2446// @as(@Vector(2, f32), [runtime value])
2447// @as(@Vector(2, f32), [runtime value])
2448// @as(@Vector(2, f32), undefined)
2449// @as(@Vector(2, f32), [runtime value])
2450// @as(@Vector(2, f32), [runtime value])
2451// @as(@Vector(2, f32), [runtime value])
2452// @as(@Vector(2, f32), undefined)
2453// @as(@Vector(2, f32), undefined)
2454// @as(@Vector(2, f32), undefined)
2455// @as(@Vector(2, f32), undefined)
2456// @as(@Vector(2, f32), undefined)
2457// @as(f32, undefined)
2458// @as(f32, undefined)
2459// @as(@Vector(2, f32), [runtime value])
2460// @as(@Vector(2, f32), [runtime value])
2461// @as(@Vector(2, f32), undefined)
2462// @as(@Vector(2, f32), [runtime value])
2463// @as(@Vector(2, f32), [runtime value])
2464// @as(@Vector(2, f32), [runtime value])
2465// @as(@Vector(2, f32), undefined)
2466// @as(@Vector(2, f32), [runtime value])
2467// @as(@Vector(2, f32), [runtime value])
2468// @as(@Vector(2, f32), [runtime value])
2469// @as(@Vector(2, f32), undefined)
2470// @as(@Vector(2, f32), undefined)
2471// @as(@Vector(2, f32), undefined)
2472// @as(@Vector(2, f32), undefined)
2473// @as(@Vector(2, f32), undefined)
2474// @as(f32, undefined)
2475// @as(@Vector(2, f32), [runtime value])
2476// @as(@Vector(2, f32), [runtime value])
2477// @as(@Vector(2, f32), undefined)
2478// @as(f16, undefined)
2479// @as(f16, undefined)
2480// @as(@Vector(2, f16), .{ 6, undefined })
2481// @as(@Vector(2, f16), .{ undefined, 6 })
2482// @as(@Vector(2, f16), undefined)
2483// @as(@Vector(2, f16), .{ 6, undefined })
2484// @as(@Vector(2, f16), .{ 6, undefined })
2485// @as(@Vector(2, f16), undefined)
2486// @as(@Vector(2, f16), undefined)
2487// @as(@Vector(2, f16), .{ undefined, 6 })
2488// @as(@Vector(2, f16), undefined)
2489// @as(@Vector(2, f16), .{ undefined, 6 })
2490// @as(@Vector(2, f16), undefined)
2491// @as(@Vector(2, f16), undefined)
2492// @as(@Vector(2, f16), undefined)
2493// @as(@Vector(2, f16), undefined)
2494// @as(@Vector(2, f16), undefined)
2495// @as(f16, undefined)
2496// @as(f16, undefined)
2497// @as(@Vector(2, f16), .{ 0, undefined })
2498// @as(@Vector(2, f16), .{ undefined, 0 })
2499// @as(@Vector(2, f16), undefined)
2500// @as(@Vector(2, f16), .{ 0, undefined })
2501// @as(@Vector(2, f16), .{ 0, undefined })
2502// @as(@Vector(2, f16), undefined)
2503// @as(@Vector(2, f16), undefined)
2504// @as(@Vector(2, f16), .{ undefined, 0 })
2505// @as(@Vector(2, f16), undefined)
2506// @as(@Vector(2, f16), .{ undefined, 0 })
2507// @as(@Vector(2, f16), undefined)
2508// @as(@Vector(2, f16), undefined)
2509// @as(@Vector(2, f16), undefined)
2510// @as(@Vector(2, f16), undefined)
2511// @as(@Vector(2, f16), undefined)
2512// @as(f16, undefined)
2513// @as(f16, undefined)
2514// @as(@Vector(2, f16), .{ 9, undefined })
2515// @as(@Vector(2, f16), .{ undefined, 9 })
2516// @as(@Vector(2, f16), undefined)
2517// @as(@Vector(2, f16), .{ 9, undefined })
2518// @as(@Vector(2, f16), .{ 9, undefined })
2519// @as(@Vector(2, f16), undefined)
2520// @as(@Vector(2, f16), undefined)
2521// @as(@Vector(2, f16), .{ undefined, 9 })
2522// @as(@Vector(2, f16), undefined)
2523// @as(@Vector(2, f16), .{ undefined, 9 })
2524// @as(@Vector(2, f16), undefined)
2525// @as(@Vector(2, f16), undefined)
2526// @as(@Vector(2, f16), undefined)
2527// @as(@Vector(2, f16), undefined)
2528// @as(@Vector(2, f16), undefined)
2529// @as(f16, undefined)
2530// @as(@Vector(2, f16), .{ -3, undefined })
2531// @as(@Vector(2, f16), .{ undefined, -3 })
2532// @as(@Vector(2, f16), undefined)
2533// @as(f16, undefined)
2534// @as(f16, undefined)
2535// @as(@Vector(2, f16), [runtime value])
2536// @as(@Vector(2, f16), [runtime value])
2537// @as(@Vector(2, f16), undefined)
2538// @as(@Vector(2, f16), [runtime value])
2539// @as(@Vector(2, f16), [runtime value])
2540// @as(@Vector(2, f16), [runtime value])
2541// @as(@Vector(2, f16), undefined)
2542// @as(@Vector(2, f16), [runtime value])
2543// @as(@Vector(2, f16), [runtime value])
2544// @as(@Vector(2, f16), [runtime value])
2545// @as(@Vector(2, f16), undefined)
2546// @as(@Vector(2, f16), undefined)
2547// @as(@Vector(2, f16), undefined)
2548// @as(@Vector(2, f16), undefined)
2549// @as(@Vector(2, f16), undefined)
2550// @as(f16, undefined)
2551// @as(f16, undefined)
2552// @as(@Vector(2, f16), [runtime value])
2553// @as(@Vector(2, f16), [runtime value])
2554// @as(@Vector(2, f16), undefined)
2555// @as(@Vector(2, f16), [runtime value])
2556// @as(@Vector(2, f16), [runtime value])
2557// @as(@Vector(2, f16), [runtime value])
2558// @as(@Vector(2, f16), undefined)
2559// @as(@Vector(2, f16), [runtime value])
2560// @as(@Vector(2, f16), [runtime value])
2561// @as(@Vector(2, f16), [runtime value])
2562// @as(@Vector(2, f16), undefined)
2563// @as(@Vector(2, f16), undefined)
2564// @as(@Vector(2, f16), undefined)
2565// @as(@Vector(2, f16), undefined)
2566// @as(@Vector(2, f16), undefined)
2567// @as(f16, undefined)
2568// @as(f16, undefined)
2569// @as(@Vector(2, f16), [runtime value])
2570// @as(@Vector(2, f16), [runtime value])
2571// @as(@Vector(2, f16), undefined)
2572// @as(@Vector(2, f16), [runtime value])
2573// @as(@Vector(2, f16), [runtime value])
2574// @as(@Vector(2, f16), [runtime value])
2575// @as(@Vector(2, f16), undefined)
2576// @as(@Vector(2, f16), [runtime value])
2577// @as(@Vector(2, f16), [runtime value])
2578// @as(@Vector(2, f16), [runtime value])
2579// @as(@Vector(2, f16), undefined)
2580// @as(@Vector(2, f16), undefined)
2581// @as(@Vector(2, f16), undefined)
2582// @as(@Vector(2, f16), undefined)
2583// @as(@Vector(2, f16), undefined)
2584// @as(f16, undefined)
2585// @as(@Vector(2, f16), [runtime value])
2586// @as(@Vector(2, f16), [runtime value])
2587// @as(@Vector(2, f16), undefined)
test/cases/compile_errors/undef_shifts_are_illegal.zig+587-587
......@@ -125,27 +125,19 @@ const std = @import("std");
125125// :53:17: error: use of undefined value here causes illegal behavior
126126// :53:17: error: use of undefined value here causes illegal behavior
127127// :53:17: error: use of undefined value here causes illegal behavior
128// :53:17: note: when computing vector element at index '0'
129128// :53:17: error: use of undefined value here causes illegal behavior
130// :53:17: note: when computing vector element at index '0'
131129// :53:17: error: use of undefined value here causes illegal behavior
132// :53:17: note: when computing vector element at index '0'
133130// :53:17: error: use of undefined value here causes illegal behavior
134// :53:17: note: when computing vector element at index '0'
135131// :53:17: error: use of undefined value here causes illegal behavior
136// :53:17: note: when computing vector element at index '1'
137132// :53:17: error: use of undefined value here causes illegal behavior
138// :53:17: note: when computing vector element at index '1'
139133// :53:17: error: use of undefined value here causes illegal behavior
140// :53:17: note: when computing vector element at index '0'
141134// :53:17: error: use of undefined value here causes illegal behavior
142// :53:17: note: when computing vector element at index '0'
143135// :53:17: error: use of undefined value here causes illegal behavior
144// :53:17: note: when computing vector element at index '0'
145136// :53:17: error: use of undefined value here causes illegal behavior
146// :53:17: note: when computing vector element at index '0'
147137// :53:17: error: use of undefined value here causes illegal behavior
138// :53:17: note: when computing vector element at index '0'
148139// :53:17: error: use of undefined value here causes illegal behavior
140// :53:17: note: when computing vector element at index '0'
149141// :53:17: error: use of undefined value here causes illegal behavior
150142// :53:17: note: when computing vector element at index '0'
151143// :53:17: error: use of undefined value here causes illegal behavior
......@@ -155,9 +147,9 @@ const std = @import("std");
155147// :53:17: error: use of undefined value here causes illegal behavior
156148// :53:17: note: when computing vector element at index '0'
157149// :53:17: error: use of undefined value here causes illegal behavior
158// :53:17: note: when computing vector element at index '1'
150// :53:17: note: when computing vector element at index '0'
159151// :53:17: error: use of undefined value here causes illegal behavior
160// :53:17: note: when computing vector element at index '1'
152// :53:17: note: when computing vector element at index '0'
161153// :53:17: error: use of undefined value here causes illegal behavior
162154// :53:17: note: when computing vector element at index '0'
163155// :53:17: error: use of undefined value here causes illegal behavior
......@@ -167,7 +159,9 @@ const std = @import("std");
167159// :53:17: error: use of undefined value here causes illegal behavior
168160// :53:17: note: when computing vector element at index '0'
169161// :53:17: error: use of undefined value here causes illegal behavior
162// :53:17: note: when computing vector element at index '0'
170163// :53:17: error: use of undefined value here causes illegal behavior
164// :53:17: note: when computing vector element at index '0'
171165// :53:17: error: use of undefined value here causes illegal behavior
172166// :53:17: note: when computing vector element at index '0'
173167// :53:17: error: use of undefined value here causes illegal behavior
......@@ -177,9 +171,9 @@ const std = @import("std");
177171// :53:17: error: use of undefined value here causes illegal behavior
178172// :53:17: note: when computing vector element at index '0'
179173// :53:17: error: use of undefined value here causes illegal behavior
180// :53:17: note: when computing vector element at index '1'
174// :53:17: note: when computing vector element at index '0'
181175// :53:17: error: use of undefined value here causes illegal behavior
182// :53:17: note: when computing vector element at index '1'
176// :53:17: note: when computing vector element at index '0'
183177// :53:17: error: use of undefined value here causes illegal behavior
184178// :53:17: note: when computing vector element at index '0'
185179// :53:17: error: use of undefined value here causes illegal behavior
......@@ -189,7 +183,9 @@ const std = @import("std");
189183// :53:17: error: use of undefined value here causes illegal behavior
190184// :53:17: note: when computing vector element at index '0'
191185// :53:17: error: use of undefined value here causes illegal behavior
186// :53:17: note: when computing vector element at index '0'
192187// :53:17: error: use of undefined value here causes illegal behavior
188// :53:17: note: when computing vector element at index '0'
193189// :53:17: error: use of undefined value here causes illegal behavior
194190// :53:17: note: when computing vector element at index '0'
195191// :53:17: error: use of undefined value here causes illegal behavior
......@@ -199,9 +195,9 @@ const std = @import("std");
199195// :53:17: error: use of undefined value here causes illegal behavior
200196// :53:17: note: when computing vector element at index '0'
201197// :53:17: error: use of undefined value here causes illegal behavior
202// :53:17: note: when computing vector element at index '1'
198// :53:17: note: when computing vector element at index '0'
203199// :53:17: error: use of undefined value here causes illegal behavior
204// :53:17: note: when computing vector element at index '1'
200// :53:17: note: when computing vector element at index '0'
205201// :53:17: error: use of undefined value here causes illegal behavior
206202// :53:17: note: when computing vector element at index '0'
207203// :53:17: error: use of undefined value here causes illegal behavior
......@@ -211,7 +207,9 @@ const std = @import("std");
211207// :53:17: error: use of undefined value here causes illegal behavior
212208// :53:17: note: when computing vector element at index '0'
213209// :53:17: error: use of undefined value here causes illegal behavior
210// :53:17: note: when computing vector element at index '0'
214211// :53:17: error: use of undefined value here causes illegal behavior
212// :53:17: note: when computing vector element at index '0'
215213// :53:17: error: use of undefined value here causes illegal behavior
216214// :53:17: note: when computing vector element at index '0'
217215// :53:17: error: use of undefined value here causes illegal behavior
......@@ -221,9 +219,9 @@ const std = @import("std");
221219// :53:17: error: use of undefined value here causes illegal behavior
222220// :53:17: note: when computing vector element at index '0'
223221// :53:17: error: use of undefined value here causes illegal behavior
224// :53:17: note: when computing vector element at index '1'
222// :53:17: note: when computing vector element at index '0'
225223// :53:17: error: use of undefined value here causes illegal behavior
226// :53:17: note: when computing vector element at index '1'
224// :53:17: note: when computing vector element at index '0'
227225// :53:17: error: use of undefined value here causes illegal behavior
228226// :53:17: note: when computing vector element at index '0'
229227// :53:17: error: use of undefined value here causes illegal behavior
......@@ -233,27 +231,29 @@ const std = @import("std");
233231// :53:17: error: use of undefined value here causes illegal behavior
234232// :53:17: note: when computing vector element at index '0'
235233// :53:17: error: use of undefined value here causes illegal behavior
234// :53:17: note: when computing vector element at index '1'
236235// :53:17: error: use of undefined value here causes illegal behavior
236// :53:17: note: when computing vector element at index '1'
237237// :53:17: error: use of undefined value here causes illegal behavior
238// :53:17: note: when computing vector element at index '0'
238// :53:17: note: when computing vector element at index '1'
239239// :53:17: error: use of undefined value here causes illegal behavior
240// :53:17: note: when computing vector element at index '0'
240// :53:17: note: when computing vector element at index '1'
241241// :53:17: error: use of undefined value here causes illegal behavior
242// :53:17: note: when computing vector element at index '0'
242// :53:17: note: when computing vector element at index '1'
243243// :53:17: error: use of undefined value here causes illegal behavior
244// :53:17: note: when computing vector element at index '0'
244// :53:17: note: when computing vector element at index '1'
245245// :53:17: error: use of undefined value here causes illegal behavior
246246// :53:17: note: when computing vector element at index '1'
247247// :53:17: error: use of undefined value here causes illegal behavior
248248// :53:17: note: when computing vector element at index '1'
249249// :53:17: error: use of undefined value here causes illegal behavior
250// :53:17: note: when computing vector element at index '0'
250// :53:17: note: when computing vector element at index '1'
251251// :53:17: error: use of undefined value here causes illegal behavior
252// :53:17: note: when computing vector element at index '0'
252// :53:17: note: when computing vector element at index '1'
253253// :53:17: error: use of undefined value here causes illegal behavior
254// :53:17: note: when computing vector element at index '0'
254// :53:17: note: when computing vector element at index '1'
255255// :53:17: error: use of undefined value here causes illegal behavior
256// :53:17: note: when computing vector element at index '0'
256// :53:17: note: when computing vector element at index '1'
257257// :53:22: error: use of undefined value here causes illegal behavior
258258// :53:22: note: when computing vector element at index '0'
259259// :53:22: error: use of undefined value here causes illegal behavior
......@@ -281,27 +281,19 @@ const std = @import("std");
281281// :56:27: error: use of undefined value here causes illegal behavior
282282// :56:27: error: use of undefined value here causes illegal behavior
283283// :56:27: error: use of undefined value here causes illegal behavior
284// :56:27: note: when computing vector element at index '0'
285284// :56:27: error: use of undefined value here causes illegal behavior
286// :56:27: note: when computing vector element at index '0'
287285// :56:27: error: use of undefined value here causes illegal behavior
288// :56:27: note: when computing vector element at index '0'
289286// :56:27: error: use of undefined value here causes illegal behavior
290// :56:27: note: when computing vector element at index '0'
291287// :56:27: error: use of undefined value here causes illegal behavior
292// :56:27: note: when computing vector element at index '1'
293288// :56:27: error: use of undefined value here causes illegal behavior
294// :56:27: note: when computing vector element at index '1'
295289// :56:27: error: use of undefined value here causes illegal behavior
296// :56:27: note: when computing vector element at index '0'
297290// :56:27: error: use of undefined value here causes illegal behavior
298// :56:27: note: when computing vector element at index '0'
299291// :56:27: error: use of undefined value here causes illegal behavior
300// :56:27: note: when computing vector element at index '0'
301292// :56:27: error: use of undefined value here causes illegal behavior
302// :56:27: note: when computing vector element at index '0'
303293// :56:27: error: use of undefined value here causes illegal behavior
294// :56:27: note: when computing vector element at index '0'
304295// :56:27: error: use of undefined value here causes illegal behavior
296// :56:27: note: when computing vector element at index '0'
305297// :56:27: error: use of undefined value here causes illegal behavior
306298// :56:27: note: when computing vector element at index '0'
307299// :56:27: error: use of undefined value here causes illegal behavior
......@@ -311,9 +303,9 @@ const std = @import("std");
311303// :56:27: error: use of undefined value here causes illegal behavior
312304// :56:27: note: when computing vector element at index '0'
313305// :56:27: error: use of undefined value here causes illegal behavior
314// :56:27: note: when computing vector element at index '1'
306// :56:27: note: when computing vector element at index '0'
315307// :56:27: error: use of undefined value here causes illegal behavior
316// :56:27: note: when computing vector element at index '1'
308// :56:27: note: when computing vector element at index '0'
317309// :56:27: error: use of undefined value here causes illegal behavior
318310// :56:27: note: when computing vector element at index '0'
319311// :56:27: error: use of undefined value here causes illegal behavior
......@@ -323,7 +315,9 @@ const std = @import("std");
323315// :56:27: error: use of undefined value here causes illegal behavior
324316// :56:27: note: when computing vector element at index '0'
325317// :56:27: error: use of undefined value here causes illegal behavior
318// :56:27: note: when computing vector element at index '0'
326319// :56:27: error: use of undefined value here causes illegal behavior
320// :56:27: note: when computing vector element at index '0'
327321// :56:27: error: use of undefined value here causes illegal behavior
328322// :56:27: note: when computing vector element at index '0'
329323// :56:27: error: use of undefined value here causes illegal behavior
......@@ -333,9 +327,9 @@ const std = @import("std");
333327// :56:27: error: use of undefined value here causes illegal behavior
334328// :56:27: note: when computing vector element at index '0'
335329// :56:27: error: use of undefined value here causes illegal behavior
336// :56:27: note: when computing vector element at index '1'
330// :56:27: note: when computing vector element at index '0'
337331// :56:27: error: use of undefined value here causes illegal behavior
338// :56:27: note: when computing vector element at index '1'
332// :56:27: note: when computing vector element at index '0'
339333// :56:27: error: use of undefined value here causes illegal behavior
340334// :56:27: note: when computing vector element at index '0'
341335// :56:27: error: use of undefined value here causes illegal behavior
......@@ -345,7 +339,9 @@ const std = @import("std");
345339// :56:27: error: use of undefined value here causes illegal behavior
346340// :56:27: note: when computing vector element at index '0'
347341// :56:27: error: use of undefined value here causes illegal behavior
342// :56:27: note: when computing vector element at index '0'
348343// :56:27: error: use of undefined value here causes illegal behavior
344// :56:27: note: when computing vector element at index '0'
349345// :56:27: error: use of undefined value here causes illegal behavior
350346// :56:27: note: when computing vector element at index '0'
351347// :56:27: error: use of undefined value here causes illegal behavior
......@@ -355,9 +351,9 @@ const std = @import("std");
355351// :56:27: error: use of undefined value here causes illegal behavior
356352// :56:27: note: when computing vector element at index '0'
357353// :56:27: error: use of undefined value here causes illegal behavior
358// :56:27: note: when computing vector element at index '1'
354// :56:27: note: when computing vector element at index '0'
359355// :56:27: error: use of undefined value here causes illegal behavior
360// :56:27: note: when computing vector element at index '1'
356// :56:27: note: when computing vector element at index '0'
361357// :56:27: error: use of undefined value here causes illegal behavior
362358// :56:27: note: when computing vector element at index '0'
363359// :56:27: error: use of undefined value here causes illegal behavior
......@@ -367,7 +363,9 @@ const std = @import("std");
367363// :56:27: error: use of undefined value here causes illegal behavior
368364// :56:27: note: when computing vector element at index '0'
369365// :56:27: error: use of undefined value here causes illegal behavior
366// :56:27: note: when computing vector element at index '0'
370367// :56:27: error: use of undefined value here causes illegal behavior
368// :56:27: note: when computing vector element at index '0'
371369// :56:27: error: use of undefined value here causes illegal behavior
372370// :56:27: note: when computing vector element at index '0'
373371// :56:27: error: use of undefined value here causes illegal behavior
......@@ -377,9 +375,9 @@ const std = @import("std");
377375// :56:27: error: use of undefined value here causes illegal behavior
378376// :56:27: note: when computing vector element at index '0'
379377// :56:27: error: use of undefined value here causes illegal behavior
380// :56:27: note: when computing vector element at index '1'
378// :56:27: note: when computing vector element at index '0'
381379// :56:27: error: use of undefined value here causes illegal behavior
382// :56:27: note: when computing vector element at index '1'
380// :56:27: note: when computing vector element at index '0'
383381// :56:27: error: use of undefined value here causes illegal behavior
384382// :56:27: note: when computing vector element at index '0'
385383// :56:27: error: use of undefined value here causes illegal behavior
......@@ -389,27 +387,29 @@ const std = @import("std");
389387// :56:27: error: use of undefined value here causes illegal behavior
390388// :56:27: note: when computing vector element at index '0'
391389// :56:27: error: use of undefined value here causes illegal behavior
390// :56:27: note: when computing vector element at index '1'
392391// :56:27: error: use of undefined value here causes illegal behavior
392// :56:27: note: when computing vector element at index '1'
393393// :56:27: error: use of undefined value here causes illegal behavior
394// :56:27: note: when computing vector element at index '0'
394// :56:27: note: when computing vector element at index '1'
395395// :56:27: error: use of undefined value here causes illegal behavior
396// :56:27: note: when computing vector element at index '0'
396// :56:27: note: when computing vector element at index '1'
397397// :56:27: error: use of undefined value here causes illegal behavior
398// :56:27: note: when computing vector element at index '0'
398// :56:27: note: when computing vector element at index '1'
399399// :56:27: error: use of undefined value here causes illegal behavior
400// :56:27: note: when computing vector element at index '0'
400// :56:27: note: when computing vector element at index '1'
401401// :56:27: error: use of undefined value here causes illegal behavior
402402// :56:27: note: when computing vector element at index '1'
403403// :56:27: error: use of undefined value here causes illegal behavior
404404// :56:27: note: when computing vector element at index '1'
405405// :56:27: error: use of undefined value here causes illegal behavior
406// :56:27: note: when computing vector element at index '0'
406// :56:27: note: when computing vector element at index '1'
407407// :56:27: error: use of undefined value here causes illegal behavior
408// :56:27: note: when computing vector element at index '0'
408// :56:27: note: when computing vector element at index '1'
409409// :56:27: error: use of undefined value here causes illegal behavior
410// :56:27: note: when computing vector element at index '0'
410// :56:27: note: when computing vector element at index '1'
411411// :56:27: error: use of undefined value here causes illegal behavior
412// :56:27: note: when computing vector element at index '0'
412// :56:27: note: when computing vector element at index '1'
413413// :56:30: error: use of undefined value here causes illegal behavior
414414// :56:30: note: when computing vector element at index '0'
415415// :56:30: error: use of undefined value here causes illegal behavior
......@@ -437,27 +437,19 @@ const std = @import("std");
437437// :59:34: error: use of undefined value here causes illegal behavior
438438// :59:34: error: use of undefined value here causes illegal behavior
439439// :59:34: error: use of undefined value here causes illegal behavior
440// :59:34: note: when computing vector element at index '0'
441440// :59:34: error: use of undefined value here causes illegal behavior
442// :59:34: note: when computing vector element at index '0'
443441// :59:34: error: use of undefined value here causes illegal behavior
444// :59:34: note: when computing vector element at index '0'
445442// :59:34: error: use of undefined value here causes illegal behavior
446// :59:34: note: when computing vector element at index '0'
447443// :59:34: error: use of undefined value here causes illegal behavior
448// :59:34: note: when computing vector element at index '1'
449444// :59:34: error: use of undefined value here causes illegal behavior
450// :59:34: note: when computing vector element at index '1'
451445// :59:34: error: use of undefined value here causes illegal behavior
452// :59:34: note: when computing vector element at index '0'
453446// :59:34: error: use of undefined value here causes illegal behavior
454// :59:34: note: when computing vector element at index '0'
455447// :59:34: error: use of undefined value here causes illegal behavior
456// :59:34: note: when computing vector element at index '0'
457448// :59:34: error: use of undefined value here causes illegal behavior
458// :59:34: note: when computing vector element at index '0'
459449// :59:34: error: use of undefined value here causes illegal behavior
450// :59:34: note: when computing vector element at index '0'
460451// :59:34: error: use of undefined value here causes illegal behavior
452// :59:34: note: when computing vector element at index '0'
461453// :59:34: error: use of undefined value here causes illegal behavior
462454// :59:34: note: when computing vector element at index '0'
463455// :59:34: error: use of undefined value here causes illegal behavior
......@@ -467,9 +459,9 @@ const std = @import("std");
467459// :59:34: error: use of undefined value here causes illegal behavior
468460// :59:34: note: when computing vector element at index '0'
469461// :59:34: error: use of undefined value here causes illegal behavior
470// :59:34: note: when computing vector element at index '1'
462// :59:34: note: when computing vector element at index '0'
471463// :59:34: error: use of undefined value here causes illegal behavior
472// :59:34: note: when computing vector element at index '1'
464// :59:34: note: when computing vector element at index '0'
473465// :59:34: error: use of undefined value here causes illegal behavior
474466// :59:34: note: when computing vector element at index '0'
475467// :59:34: error: use of undefined value here causes illegal behavior
......@@ -479,7 +471,9 @@ const std = @import("std");
479471// :59:34: error: use of undefined value here causes illegal behavior
480472// :59:34: note: when computing vector element at index '0'
481473// :59:34: error: use of undefined value here causes illegal behavior
474// :59:34: note: when computing vector element at index '0'
482475// :59:34: error: use of undefined value here causes illegal behavior
476// :59:34: note: when computing vector element at index '0'
483477// :59:34: error: use of undefined value here causes illegal behavior
484478// :59:34: note: when computing vector element at index '0'
485479// :59:34: error: use of undefined value here causes illegal behavior
......@@ -489,9 +483,9 @@ const std = @import("std");
489483// :59:34: error: use of undefined value here causes illegal behavior
490484// :59:34: note: when computing vector element at index '0'
491485// :59:34: error: use of undefined value here causes illegal behavior
492// :59:34: note: when computing vector element at index '1'
486// :59:34: note: when computing vector element at index '0'
493487// :59:34: error: use of undefined value here causes illegal behavior
494// :59:34: note: when computing vector element at index '1'
488// :59:34: note: when computing vector element at index '0'
495489// :59:34: error: use of undefined value here causes illegal behavior
496490// :59:34: note: when computing vector element at index '0'
497491// :59:34: error: use of undefined value here causes illegal behavior
......@@ -501,7 +495,9 @@ const std = @import("std");
501495// :59:34: error: use of undefined value here causes illegal behavior
502496// :59:34: note: when computing vector element at index '0'
503497// :59:34: error: use of undefined value here causes illegal behavior
498// :59:34: note: when computing vector element at index '0'
504499// :59:34: error: use of undefined value here causes illegal behavior
500// :59:34: note: when computing vector element at index '0'
505501// :59:34: error: use of undefined value here causes illegal behavior
506502// :59:34: note: when computing vector element at index '0'
507503// :59:34: error: use of undefined value here causes illegal behavior
......@@ -511,9 +507,9 @@ const std = @import("std");
511507// :59:34: error: use of undefined value here causes illegal behavior
512508// :59:34: note: when computing vector element at index '0'
513509// :59:34: error: use of undefined value here causes illegal behavior
514// :59:34: note: when computing vector element at index '1'
510// :59:34: note: when computing vector element at index '0'
515511// :59:34: error: use of undefined value here causes illegal behavior
516// :59:34: note: when computing vector element at index '1'
512// :59:34: note: when computing vector element at index '0'
517513// :59:34: error: use of undefined value here causes illegal behavior
518514// :59:34: note: when computing vector element at index '0'
519515// :59:34: error: use of undefined value here causes illegal behavior
......@@ -523,7 +519,9 @@ const std = @import("std");
523519// :59:34: error: use of undefined value here causes illegal behavior
524520// :59:34: note: when computing vector element at index '0'
525521// :59:34: error: use of undefined value here causes illegal behavior
522// :59:34: note: when computing vector element at index '0'
526523// :59:34: error: use of undefined value here causes illegal behavior
524// :59:34: note: when computing vector element at index '0'
527525// :59:34: error: use of undefined value here causes illegal behavior
528526// :59:34: note: when computing vector element at index '0'
529527// :59:34: error: use of undefined value here causes illegal behavior
......@@ -533,9 +531,9 @@ const std = @import("std");
533531// :59:34: error: use of undefined value here causes illegal behavior
534532// :59:34: note: when computing vector element at index '0'
535533// :59:34: error: use of undefined value here causes illegal behavior
536// :59:34: note: when computing vector element at index '1'
534// :59:34: note: when computing vector element at index '0'
537535// :59:34: error: use of undefined value here causes illegal behavior
538// :59:34: note: when computing vector element at index '1'
536// :59:34: note: when computing vector element at index '0'
539537// :59:34: error: use of undefined value here causes illegal behavior
540538// :59:34: note: when computing vector element at index '0'
541539// :59:34: error: use of undefined value here causes illegal behavior
......@@ -545,27 +543,29 @@ const std = @import("std");
545543// :59:34: error: use of undefined value here causes illegal behavior
546544// :59:34: note: when computing vector element at index '0'
547545// :59:34: error: use of undefined value here causes illegal behavior
546// :59:34: note: when computing vector element at index '1'
548547// :59:34: error: use of undefined value here causes illegal behavior
548// :59:34: note: when computing vector element at index '1'
549549// :59:34: error: use of undefined value here causes illegal behavior
550// :59:34: note: when computing vector element at index '0'
550// :59:34: note: when computing vector element at index '1'
551551// :59:34: error: use of undefined value here causes illegal behavior
552// :59:34: note: when computing vector element at index '0'
552// :59:34: note: when computing vector element at index '1'
553553// :59:34: error: use of undefined value here causes illegal behavior
554// :59:34: note: when computing vector element at index '0'
554// :59:34: note: when computing vector element at index '1'
555555// :59:34: error: use of undefined value here causes illegal behavior
556// :59:34: note: when computing vector element at index '0'
556// :59:34: note: when computing vector element at index '1'
557557// :59:34: error: use of undefined value here causes illegal behavior
558558// :59:34: note: when computing vector element at index '1'
559559// :59:34: error: use of undefined value here causes illegal behavior
560560// :59:34: note: when computing vector element at index '1'
561561// :59:34: error: use of undefined value here causes illegal behavior
562// :59:34: note: when computing vector element at index '0'
562// :59:34: note: when computing vector element at index '1'
563563// :59:34: error: use of undefined value here causes illegal behavior
564// :59:34: note: when computing vector element at index '0'
564// :59:34: note: when computing vector element at index '1'
565565// :59:34: error: use of undefined value here causes illegal behavior
566// :59:34: note: when computing vector element at index '0'
566// :59:34: note: when computing vector element at index '1'
567567// :59:34: error: use of undefined value here causes illegal behavior
568// :59:34: note: when computing vector element at index '0'
568// :59:34: note: when computing vector element at index '1'
569569// :59:37: error: use of undefined value here causes illegal behavior
570570// :59:37: note: when computing vector element at index '0'
571571// :59:37: error: use of undefined value here causes illegal behavior
......@@ -593,27 +593,19 @@ const std = @import("std");
593593// :62:17: error: use of undefined value here causes illegal behavior
594594// :62:17: error: use of undefined value here causes illegal behavior
595595// :62:17: error: use of undefined value here causes illegal behavior
596// :62:17: note: when computing vector element at index '0'
597596// :62:17: error: use of undefined value here causes illegal behavior
598// :62:17: note: when computing vector element at index '0'
599597// :62:17: error: use of undefined value here causes illegal behavior
600// :62:17: note: when computing vector element at index '0'
601598// :62:17: error: use of undefined value here causes illegal behavior
602// :62:17: note: when computing vector element at index '0'
603599// :62:17: error: use of undefined value here causes illegal behavior
604// :62:17: note: when computing vector element at index '1'
605600// :62:17: error: use of undefined value here causes illegal behavior
606// :62:17: note: when computing vector element at index '1'
607601// :62:17: error: use of undefined value here causes illegal behavior
608// :62:17: note: when computing vector element at index '0'
609602// :62:17: error: use of undefined value here causes illegal behavior
610// :62:17: note: when computing vector element at index '0'
611603// :62:17: error: use of undefined value here causes illegal behavior
612// :62:17: note: when computing vector element at index '0'
613604// :62:17: error: use of undefined value here causes illegal behavior
614// :62:17: note: when computing vector element at index '0'
615605// :62:17: error: use of undefined value here causes illegal behavior
606// :62:17: note: when computing vector element at index '0'
616607// :62:17: error: use of undefined value here causes illegal behavior
608// :62:17: note: when computing vector element at index '0'
617609// :62:17: error: use of undefined value here causes illegal behavior
618610// :62:17: note: when computing vector element at index '0'
619611// :62:17: error: use of undefined value here causes illegal behavior
......@@ -623,9 +615,9 @@ const std = @import("std");
623615// :62:17: error: use of undefined value here causes illegal behavior
624616// :62:17: note: when computing vector element at index '0'
625617// :62:17: error: use of undefined value here causes illegal behavior
626// :62:17: note: when computing vector element at index '1'
618// :62:17: note: when computing vector element at index '0'
627619// :62:17: error: use of undefined value here causes illegal behavior
628// :62:17: note: when computing vector element at index '1'
620// :62:17: note: when computing vector element at index '0'
629621// :62:17: error: use of undefined value here causes illegal behavior
630622// :62:17: note: when computing vector element at index '0'
631623// :62:17: error: use of undefined value here causes illegal behavior
......@@ -635,7 +627,9 @@ const std = @import("std");
635627// :62:17: error: use of undefined value here causes illegal behavior
636628// :62:17: note: when computing vector element at index '0'
637629// :62:17: error: use of undefined value here causes illegal behavior
630// :62:17: note: when computing vector element at index '0'
638631// :62:17: error: use of undefined value here causes illegal behavior
632// :62:17: note: when computing vector element at index '0'
639633// :62:17: error: use of undefined value here causes illegal behavior
640634// :62:17: note: when computing vector element at index '0'
641635// :62:17: error: use of undefined value here causes illegal behavior
......@@ -645,9 +639,9 @@ const std = @import("std");
645639// :62:17: error: use of undefined value here causes illegal behavior
646640// :62:17: note: when computing vector element at index '0'
647641// :62:17: error: use of undefined value here causes illegal behavior
648// :62:17: note: when computing vector element at index '1'
642// :62:17: note: when computing vector element at index '0'
649643// :62:17: error: use of undefined value here causes illegal behavior
650// :62:17: note: when computing vector element at index '1'
644// :62:17: note: when computing vector element at index '0'
651645// :62:17: error: use of undefined value here causes illegal behavior
652646// :62:17: note: when computing vector element at index '0'
653647// :62:17: error: use of undefined value here causes illegal behavior
......@@ -657,7 +651,9 @@ const std = @import("std");
657651// :62:17: error: use of undefined value here causes illegal behavior
658652// :62:17: note: when computing vector element at index '0'
659653// :62:17: error: use of undefined value here causes illegal behavior
654// :62:17: note: when computing vector element at index '0'
660655// :62:17: error: use of undefined value here causes illegal behavior
656// :62:17: note: when computing vector element at index '0'
661657// :62:17: error: use of undefined value here causes illegal behavior
662658// :62:17: note: when computing vector element at index '0'
663659// :62:17: error: use of undefined value here causes illegal behavior
......@@ -667,9 +663,9 @@ const std = @import("std");
667663// :62:17: error: use of undefined value here causes illegal behavior
668664// :62:17: note: when computing vector element at index '0'
669665// :62:17: error: use of undefined value here causes illegal behavior
670// :62:17: note: when computing vector element at index '1'
666// :62:17: note: when computing vector element at index '0'
671667// :62:17: error: use of undefined value here causes illegal behavior
672// :62:17: note: when computing vector element at index '1'
668// :62:17: note: when computing vector element at index '0'
673669// :62:17: error: use of undefined value here causes illegal behavior
674670// :62:17: note: when computing vector element at index '0'
675671// :62:17: error: use of undefined value here causes illegal behavior
......@@ -679,7 +675,9 @@ const std = @import("std");
679675// :62:17: error: use of undefined value here causes illegal behavior
680676// :62:17: note: when computing vector element at index '0'
681677// :62:17: error: use of undefined value here causes illegal behavior
678// :62:17: note: when computing vector element at index '0'
682679// :62:17: error: use of undefined value here causes illegal behavior
680// :62:17: note: when computing vector element at index '0'
683681// :62:17: error: use of undefined value here causes illegal behavior
684682// :62:17: note: when computing vector element at index '0'
685683// :62:17: error: use of undefined value here causes illegal behavior
......@@ -689,9 +687,9 @@ const std = @import("std");
689687// :62:17: error: use of undefined value here causes illegal behavior
690688// :62:17: note: when computing vector element at index '0'
691689// :62:17: error: use of undefined value here causes illegal behavior
692// :62:17: note: when computing vector element at index '1'
690// :62:17: note: when computing vector element at index '0'
693691// :62:17: error: use of undefined value here causes illegal behavior
694// :62:17: note: when computing vector element at index '1'
692// :62:17: note: when computing vector element at index '0'
695693// :62:17: error: use of undefined value here causes illegal behavior
696694// :62:17: note: when computing vector element at index '0'
697695// :62:17: error: use of undefined value here causes illegal behavior
......@@ -701,27 +699,29 @@ const std = @import("std");
701699// :62:17: error: use of undefined value here causes illegal behavior
702700// :62:17: note: when computing vector element at index '0'
703701// :62:17: error: use of undefined value here causes illegal behavior
702// :62:17: note: when computing vector element at index '1'
704703// :62:17: error: use of undefined value here causes illegal behavior
704// :62:17: note: when computing vector element at index '1'
705705// :62:17: error: use of undefined value here causes illegal behavior
706// :62:17: note: when computing vector element at index '0'
706// :62:17: note: when computing vector element at index '1'
707707// :62:17: error: use of undefined value here causes illegal behavior
708// :62:17: note: when computing vector element at index '0'
708// :62:17: note: when computing vector element at index '1'
709709// :62:17: error: use of undefined value here causes illegal behavior
710// :62:17: note: when computing vector element at index '0'
710// :62:17: note: when computing vector element at index '1'
711711// :62:17: error: use of undefined value here causes illegal behavior
712// :62:17: note: when computing vector element at index '0'
712// :62:17: note: when computing vector element at index '1'
713713// :62:17: error: use of undefined value here causes illegal behavior
714714// :62:17: note: when computing vector element at index '1'
715715// :62:17: error: use of undefined value here causes illegal behavior
716716// :62:17: note: when computing vector element at index '1'
717717// :62:17: error: use of undefined value here causes illegal behavior
718// :62:17: note: when computing vector element at index '0'
718// :62:17: note: when computing vector element at index '1'
719719// :62:17: error: use of undefined value here causes illegal behavior
720// :62:17: note: when computing vector element at index '0'
720// :62:17: note: when computing vector element at index '1'
721721// :62:17: error: use of undefined value here causes illegal behavior
722// :62:17: note: when computing vector element at index '0'
722// :62:17: note: when computing vector element at index '1'
723723// :62:17: error: use of undefined value here causes illegal behavior
724// :62:17: note: when computing vector element at index '0'
724// :62:17: note: when computing vector element at index '1'
725725// :62:22: error: use of undefined value here causes illegal behavior
726726// :62:22: note: when computing vector element at index '0'
727727// :62:22: error: use of undefined value here causes illegal behavior
......@@ -749,27 +749,19 @@ const std = @import("std");
749749// :65:27: error: use of undefined value here causes illegal behavior
750750// :65:27: error: use of undefined value here causes illegal behavior
751751// :65:27: error: use of undefined value here causes illegal behavior
752// :65:27: note: when computing vector element at index '0'
753752// :65:27: error: use of undefined value here causes illegal behavior
754// :65:27: note: when computing vector element at index '0'
755753// :65:27: error: use of undefined value here causes illegal behavior
756// :65:27: note: when computing vector element at index '0'
757754// :65:27: error: use of undefined value here causes illegal behavior
758// :65:27: note: when computing vector element at index '0'
759755// :65:27: error: use of undefined value here causes illegal behavior
760// :65:27: note: when computing vector element at index '1'
761756// :65:27: error: use of undefined value here causes illegal behavior
762// :65:27: note: when computing vector element at index '1'
763757// :65:27: error: use of undefined value here causes illegal behavior
764// :65:27: note: when computing vector element at index '0'
765758// :65:27: error: use of undefined value here causes illegal behavior
766// :65:27: note: when computing vector element at index '0'
767759// :65:27: error: use of undefined value here causes illegal behavior
768// :65:27: note: when computing vector element at index '0'
769760// :65:27: error: use of undefined value here causes illegal behavior
770// :65:27: note: when computing vector element at index '0'
771761// :65:27: error: use of undefined value here causes illegal behavior
762// :65:27: note: when computing vector element at index '0'
772763// :65:27: error: use of undefined value here causes illegal behavior
764// :65:27: note: when computing vector element at index '0'
773765// :65:27: error: use of undefined value here causes illegal behavior
774766// :65:27: note: when computing vector element at index '0'
775767// :65:27: error: use of undefined value here causes illegal behavior
......@@ -779,9 +771,9 @@ const std = @import("std");
779771// :65:27: error: use of undefined value here causes illegal behavior
780772// :65:27: note: when computing vector element at index '0'
781773// :65:27: error: use of undefined value here causes illegal behavior
782// :65:27: note: when computing vector element at index '1'
774// :65:27: note: when computing vector element at index '0'
783775// :65:27: error: use of undefined value here causes illegal behavior
784// :65:27: note: when computing vector element at index '1'
776// :65:27: note: when computing vector element at index '0'
785777// :65:27: error: use of undefined value here causes illegal behavior
786778// :65:27: note: when computing vector element at index '0'
787779// :65:27: error: use of undefined value here causes illegal behavior
......@@ -791,7 +783,9 @@ const std = @import("std");
791783// :65:27: error: use of undefined value here causes illegal behavior
792784// :65:27: note: when computing vector element at index '0'
793785// :65:27: error: use of undefined value here causes illegal behavior
786// :65:27: note: when computing vector element at index '0'
794787// :65:27: error: use of undefined value here causes illegal behavior
788// :65:27: note: when computing vector element at index '0'
795789// :65:27: error: use of undefined value here causes illegal behavior
796790// :65:27: note: when computing vector element at index '0'
797791// :65:27: error: use of undefined value here causes illegal behavior
......@@ -801,9 +795,9 @@ const std = @import("std");
801795// :65:27: error: use of undefined value here causes illegal behavior
802796// :65:27: note: when computing vector element at index '0'
803797// :65:27: error: use of undefined value here causes illegal behavior
804// :65:27: note: when computing vector element at index '1'
798// :65:27: note: when computing vector element at index '0'
805799// :65:27: error: use of undefined value here causes illegal behavior
806// :65:27: note: when computing vector element at index '1'
800// :65:27: note: when computing vector element at index '0'
807801// :65:27: error: use of undefined value here causes illegal behavior
808802// :65:27: note: when computing vector element at index '0'
809803// :65:27: error: use of undefined value here causes illegal behavior
......@@ -813,7 +807,9 @@ const std = @import("std");
813807// :65:27: error: use of undefined value here causes illegal behavior
814808// :65:27: note: when computing vector element at index '0'
815809// :65:27: error: use of undefined value here causes illegal behavior
810// :65:27: note: when computing vector element at index '0'
816811// :65:27: error: use of undefined value here causes illegal behavior
812// :65:27: note: when computing vector element at index '0'
817813// :65:27: error: use of undefined value here causes illegal behavior
818814// :65:27: note: when computing vector element at index '0'
819815// :65:27: error: use of undefined value here causes illegal behavior
......@@ -823,9 +819,9 @@ const std = @import("std");
823819// :65:27: error: use of undefined value here causes illegal behavior
824820// :65:27: note: when computing vector element at index '0'
825821// :65:27: error: use of undefined value here causes illegal behavior
826// :65:27: note: when computing vector element at index '1'
822// :65:27: note: when computing vector element at index '0'
827823// :65:27: error: use of undefined value here causes illegal behavior
828// :65:27: note: when computing vector element at index '1'
824// :65:27: note: when computing vector element at index '0'
829825// :65:27: error: use of undefined value here causes illegal behavior
830826// :65:27: note: when computing vector element at index '0'
831827// :65:27: error: use of undefined value here causes illegal behavior
......@@ -835,7 +831,9 @@ const std = @import("std");
835831// :65:27: error: use of undefined value here causes illegal behavior
836832// :65:27: note: when computing vector element at index '0'
837833// :65:27: error: use of undefined value here causes illegal behavior
834// :65:27: note: when computing vector element at index '0'
838835// :65:27: error: use of undefined value here causes illegal behavior
836// :65:27: note: when computing vector element at index '0'
839837// :65:27: error: use of undefined value here causes illegal behavior
840838// :65:27: note: when computing vector element at index '0'
841839// :65:27: error: use of undefined value here causes illegal behavior
......@@ -845,9 +843,9 @@ const std = @import("std");
845843// :65:27: error: use of undefined value here causes illegal behavior
846844// :65:27: note: when computing vector element at index '0'
847845// :65:27: error: use of undefined value here causes illegal behavior
848// :65:27: note: when computing vector element at index '1'
846// :65:27: note: when computing vector element at index '0'
849847// :65:27: error: use of undefined value here causes illegal behavior
850// :65:27: note: when computing vector element at index '1'
848// :65:27: note: when computing vector element at index '0'
851849// :65:27: error: use of undefined value here causes illegal behavior
852850// :65:27: note: when computing vector element at index '0'
853851// :65:27: error: use of undefined value here causes illegal behavior
......@@ -857,27 +855,29 @@ const std = @import("std");
857855// :65:27: error: use of undefined value here causes illegal behavior
858856// :65:27: note: when computing vector element at index '0'
859857// :65:27: error: use of undefined value here causes illegal behavior
858// :65:27: note: when computing vector element at index '1'
860859// :65:27: error: use of undefined value here causes illegal behavior
860// :65:27: note: when computing vector element at index '1'
861861// :65:27: error: use of undefined value here causes illegal behavior
862// :65:27: note: when computing vector element at index '0'
862// :65:27: note: when computing vector element at index '1'
863863// :65:27: error: use of undefined value here causes illegal behavior
864// :65:27: note: when computing vector element at index '0'
864// :65:27: note: when computing vector element at index '1'
865865// :65:27: error: use of undefined value here causes illegal behavior
866// :65:27: note: when computing vector element at index '0'
866// :65:27: note: when computing vector element at index '1'
867867// :65:27: error: use of undefined value here causes illegal behavior
868// :65:27: note: when computing vector element at index '0'
868// :65:27: note: when computing vector element at index '1'
869869// :65:27: error: use of undefined value here causes illegal behavior
870870// :65:27: note: when computing vector element at index '1'
871871// :65:27: error: use of undefined value here causes illegal behavior
872872// :65:27: note: when computing vector element at index '1'
873873// :65:27: error: use of undefined value here causes illegal behavior
874// :65:27: note: when computing vector element at index '0'
874// :65:27: note: when computing vector element at index '1'
875875// :65:27: error: use of undefined value here causes illegal behavior
876// :65:27: note: when computing vector element at index '0'
876// :65:27: note: when computing vector element at index '1'
877877// :65:27: error: use of undefined value here causes illegal behavior
878// :65:27: note: when computing vector element at index '0'
878// :65:27: note: when computing vector element at index '1'
879879// :65:27: error: use of undefined value here causes illegal behavior
880// :65:27: note: when computing vector element at index '0'
880// :65:27: note: when computing vector element at index '1'
881881// :65:30: error: use of undefined value here causes illegal behavior
882882// :65:30: note: when computing vector element at index '0'
883883// :65:30: error: use of undefined value here causes illegal behavior
......@@ -909,21 +909,13 @@ const std = @import("std");
909909// :70:17: error: use of undefined value here causes illegal behavior
910910// :70:17: error: use of undefined value here causes illegal behavior
911911// :70:17: error: use of undefined value here causes illegal behavior
912// :70:17: note: when computing vector element at index '1'
913912// :70:17: error: use of undefined value here causes illegal behavior
914// :70:17: note: when computing vector element at index '1'
915913// :70:17: error: use of undefined value here causes illegal behavior
916// :70:17: note: when computing vector element at index '1'
917914// :70:17: error: use of undefined value here causes illegal behavior
918// :70:17: note: when computing vector element at index '1'
919915// :70:17: error: use of undefined value here causes illegal behavior
920// :70:17: note: when computing vector element at index '0'
921916// :70:17: error: use of undefined value here causes illegal behavior
922// :70:17: note: when computing vector element at index '0'
923917// :70:17: error: use of undefined value here causes illegal behavior
924// :70:17: note: when computing vector element at index '0'
925918// :70:17: error: use of undefined value here causes illegal behavior
926// :70:17: note: when computing vector element at index '0'
927919// :70:17: error: use of undefined value here causes illegal behavior
928920// :70:17: error: use of undefined value here causes illegal behavior
929921// :70:17: error: use of undefined value here causes illegal behavior
......@@ -931,21 +923,13 @@ const std = @import("std");
931923// :70:17: error: use of undefined value here causes illegal behavior
932924// :70:17: error: use of undefined value here causes illegal behavior
933925// :70:17: error: use of undefined value here causes illegal behavior
934// :70:17: note: when computing vector element at index '1'
935926// :70:17: error: use of undefined value here causes illegal behavior
936// :70:17: note: when computing vector element at index '1'
937927// :70:17: error: use of undefined value here causes illegal behavior
938// :70:17: note: when computing vector element at index '1'
939928// :70:17: error: use of undefined value here causes illegal behavior
940// :70:17: note: when computing vector element at index '1'
941929// :70:17: error: use of undefined value here causes illegal behavior
942// :70:17: note: when computing vector element at index '0'
943930// :70:17: error: use of undefined value here causes illegal behavior
944// :70:17: note: when computing vector element at index '0'
945931// :70:17: error: use of undefined value here causes illegal behavior
946// :70:17: note: when computing vector element at index '0'
947932// :70:17: error: use of undefined value here causes illegal behavior
948// :70:17: note: when computing vector element at index '0'
949933// :70:17: error: use of undefined value here causes illegal behavior
950934// :70:17: error: use of undefined value here causes illegal behavior
951935// :70:17: error: use of undefined value here causes illegal behavior
......@@ -953,13 +937,11 @@ const std = @import("std");
953937// :70:17: error: use of undefined value here causes illegal behavior
954938// :70:17: error: use of undefined value here causes illegal behavior
955939// :70:17: error: use of undefined value here causes illegal behavior
956// :70:17: note: when computing vector element at index '1'
957940// :70:17: error: use of undefined value here causes illegal behavior
958// :70:17: note: when computing vector element at index '1'
959941// :70:17: error: use of undefined value here causes illegal behavior
960// :70:17: note: when computing vector element at index '1'
942// :70:17: note: when computing vector element at index '0'
961943// :70:17: error: use of undefined value here causes illegal behavior
962// :70:17: note: when computing vector element at index '1'
944// :70:17: note: when computing vector element at index '0'
963945// :70:17: error: use of undefined value here causes illegal behavior
964946// :70:17: note: when computing vector element at index '0'
965947// :70:17: error: use of undefined value here causes illegal behavior
......@@ -969,19 +951,25 @@ const std = @import("std");
969951// :70:17: error: use of undefined value here causes illegal behavior
970952// :70:17: note: when computing vector element at index '0'
971953// :70:17: error: use of undefined value here causes illegal behavior
954// :70:17: note: when computing vector element at index '0'
972955// :70:17: error: use of undefined value here causes illegal behavior
956// :70:17: note: when computing vector element at index '0'
973957// :70:17: error: use of undefined value here causes illegal behavior
958// :70:17: note: when computing vector element at index '0'
974959// :70:17: error: use of undefined value here causes illegal behavior
960// :70:17: note: when computing vector element at index '0'
975961// :70:17: error: use of undefined value here causes illegal behavior
962// :70:17: note: when computing vector element at index '0'
976963// :70:17: error: use of undefined value here causes illegal behavior
964// :70:17: note: when computing vector element at index '0'
977965// :70:17: error: use of undefined value here causes illegal behavior
978// :70:17: note: when computing vector element at index '1'
966// :70:17: note: when computing vector element at index '0'
979967// :70:17: error: use of undefined value here causes illegal behavior
980// :70:17: note: when computing vector element at index '1'
968// :70:17: note: when computing vector element at index '0'
981969// :70:17: error: use of undefined value here causes illegal behavior
982// :70:17: note: when computing vector element at index '1'
970// :70:17: note: when computing vector element at index '0'
983971// :70:17: error: use of undefined value here causes illegal behavior
984// :70:17: note: when computing vector element at index '1'
972// :70:17: note: when computing vector element at index '0'
985973// :70:17: error: use of undefined value here causes illegal behavior
986974// :70:17: note: when computing vector element at index '0'
987975// :70:17: error: use of undefined value here causes illegal behavior
......@@ -991,11 +979,17 @@ const std = @import("std");
991979// :70:17: error: use of undefined value here causes illegal behavior
992980// :70:17: note: when computing vector element at index '0'
993981// :70:17: error: use of undefined value here causes illegal behavior
982// :70:17: note: when computing vector element at index '0'
994983// :70:17: error: use of undefined value here causes illegal behavior
984// :70:17: note: when computing vector element at index '0'
995985// :70:17: error: use of undefined value here causes illegal behavior
986// :70:17: note: when computing vector element at index '0'
996987// :70:17: error: use of undefined value here causes illegal behavior
988// :70:17: note: when computing vector element at index '0'
997989// :70:17: error: use of undefined value here causes illegal behavior
990// :70:17: note: when computing vector element at index '1'
998991// :70:17: error: use of undefined value here causes illegal behavior
992// :70:17: note: when computing vector element at index '1'
999993// :70:17: error: use of undefined value here causes illegal behavior
1000994// :70:17: note: when computing vector element at index '1'
1001995// :70:17: error: use of undefined value here causes illegal behavior
......@@ -1005,19 +999,25 @@ const std = @import("std");
1005999// :70:17: error: use of undefined value here causes illegal behavior
10061000// :70:17: note: when computing vector element at index '1'
10071001// :70:17: error: use of undefined value here causes illegal behavior
1008// :70:17: note: when computing vector element at index '0'
1002// :70:17: note: when computing vector element at index '1'
10091003// :70:17: error: use of undefined value here causes illegal behavior
1010// :70:17: note: when computing vector element at index '0'
1004// :70:17: note: when computing vector element at index '1'
10111005// :70:17: error: use of undefined value here causes illegal behavior
1012// :70:17: note: when computing vector element at index '0'
1006// :70:17: note: when computing vector element at index '1'
10131007// :70:17: error: use of undefined value here causes illegal behavior
1014// :70:17: note: when computing vector element at index '0'
1008// :70:17: note: when computing vector element at index '1'
10151009// :70:17: error: use of undefined value here causes illegal behavior
1010// :70:17: note: when computing vector element at index '1'
10161011// :70:17: error: use of undefined value here causes illegal behavior
1012// :70:17: note: when computing vector element at index '1'
10171013// :70:17: error: use of undefined value here causes illegal behavior
1014// :70:17: note: when computing vector element at index '1'
10181015// :70:17: error: use of undefined value here causes illegal behavior
1016// :70:17: note: when computing vector element at index '1'
10191017// :70:17: error: use of undefined value here causes illegal behavior
1018// :70:17: note: when computing vector element at index '1'
10201019// :70:17: error: use of undefined value here causes illegal behavior
1020// :70:17: note: when computing vector element at index '1'
10211021// :70:17: error: use of undefined value here causes illegal behavior
10221022// :70:17: note: when computing vector element at index '1'
10231023// :70:17: error: use of undefined value here causes illegal behavior
......@@ -1027,13 +1027,13 @@ const std = @import("std");
10271027// :70:17: error: use of undefined value here causes illegal behavior
10281028// :70:17: note: when computing vector element at index '1'
10291029// :70:17: error: use of undefined value here causes illegal behavior
1030// :70:17: note: when computing vector element at index '0'
1030// :70:17: note: when computing vector element at index '1'
10311031// :70:17: error: use of undefined value here causes illegal behavior
1032// :70:17: note: when computing vector element at index '0'
1032// :70:17: note: when computing vector element at index '1'
10331033// :70:17: error: use of undefined value here causes illegal behavior
1034// :70:17: note: when computing vector element at index '0'
1034// :70:17: note: when computing vector element at index '1'
10351035// :70:17: error: use of undefined value here causes illegal behavior
1036// :70:17: note: when computing vector element at index '0'
1036// :70:17: note: when computing vector element at index '1'
10371037// :73:27: error: use of undefined value here causes illegal behavior
10381038// :73:27: error: use of undefined value here causes illegal behavior
10391039// :73:27: error: use of undefined value here causes illegal behavior
......@@ -1041,21 +1041,13 @@ const std = @import("std");
10411041// :73:27: error: use of undefined value here causes illegal behavior
10421042// :73:27: error: use of undefined value here causes illegal behavior
10431043// :73:27: error: use of undefined value here causes illegal behavior
1044// :73:27: note: when computing vector element at index '1'
10451044// :73:27: error: use of undefined value here causes illegal behavior
1046// :73:27: note: when computing vector element at index '1'
10471045// :73:27: error: use of undefined value here causes illegal behavior
1048// :73:27: note: when computing vector element at index '1'
10491046// :73:27: error: use of undefined value here causes illegal behavior
1050// :73:27: note: when computing vector element at index '1'
10511047// :73:27: error: use of undefined value here causes illegal behavior
1052// :73:27: note: when computing vector element at index '0'
10531048// :73:27: error: use of undefined value here causes illegal behavior
1054// :73:27: note: when computing vector element at index '0'
10551049// :73:27: error: use of undefined value here causes illegal behavior
1056// :73:27: note: when computing vector element at index '0'
10571050// :73:27: error: use of undefined value here causes illegal behavior
1058// :73:27: note: when computing vector element at index '0'
10591051// :73:27: error: use of undefined value here causes illegal behavior
10601052// :73:27: error: use of undefined value here causes illegal behavior
10611053// :73:27: error: use of undefined value here causes illegal behavior
......@@ -1063,21 +1055,13 @@ const std = @import("std");
10631055// :73:27: error: use of undefined value here causes illegal behavior
10641056// :73:27: error: use of undefined value here causes illegal behavior
10651057// :73:27: error: use of undefined value here causes illegal behavior
1066// :73:27: note: when computing vector element at index '1'
10671058// :73:27: error: use of undefined value here causes illegal behavior
1068// :73:27: note: when computing vector element at index '1'
10691059// :73:27: error: use of undefined value here causes illegal behavior
1070// :73:27: note: when computing vector element at index '1'
10711060// :73:27: error: use of undefined value here causes illegal behavior
1072// :73:27: note: when computing vector element at index '1'
10731061// :73:27: error: use of undefined value here causes illegal behavior
1074// :73:27: note: when computing vector element at index '0'
10751062// :73:27: error: use of undefined value here causes illegal behavior
1076// :73:27: note: when computing vector element at index '0'
10771063// :73:27: error: use of undefined value here causes illegal behavior
1078// :73:27: note: when computing vector element at index '0'
10791064// :73:27: error: use of undefined value here causes illegal behavior
1080// :73:27: note: when computing vector element at index '0'
10811065// :73:27: error: use of undefined value here causes illegal behavior
10821066// :73:27: error: use of undefined value here causes illegal behavior
10831067// :73:27: error: use of undefined value here causes illegal behavior
......@@ -1085,13 +1069,11 @@ const std = @import("std");
10851069// :73:27: error: use of undefined value here causes illegal behavior
10861070// :73:27: error: use of undefined value here causes illegal behavior
10871071// :73:27: error: use of undefined value here causes illegal behavior
1088// :73:27: note: when computing vector element at index '1'
10891072// :73:27: error: use of undefined value here causes illegal behavior
1090// :73:27: note: when computing vector element at index '1'
10911073// :73:27: error: use of undefined value here causes illegal behavior
1092// :73:27: note: when computing vector element at index '1'
1074// :73:27: note: when computing vector element at index '0'
10931075// :73:27: error: use of undefined value here causes illegal behavior
1094// :73:27: note: when computing vector element at index '1'
1076// :73:27: note: when computing vector element at index '0'
10951077// :73:27: error: use of undefined value here causes illegal behavior
10961078// :73:27: note: when computing vector element at index '0'
10971079// :73:27: error: use of undefined value here causes illegal behavior
......@@ -1101,19 +1083,25 @@ const std = @import("std");
11011083// :73:27: error: use of undefined value here causes illegal behavior
11021084// :73:27: note: when computing vector element at index '0'
11031085// :73:27: error: use of undefined value here causes illegal behavior
1086// :73:27: note: when computing vector element at index '0'
11041087// :73:27: error: use of undefined value here causes illegal behavior
1088// :73:27: note: when computing vector element at index '0'
11051089// :73:27: error: use of undefined value here causes illegal behavior
1090// :73:27: note: when computing vector element at index '0'
11061091// :73:27: error: use of undefined value here causes illegal behavior
1092// :73:27: note: when computing vector element at index '0'
11071093// :73:27: error: use of undefined value here causes illegal behavior
1094// :73:27: note: when computing vector element at index '0'
11081095// :73:27: error: use of undefined value here causes illegal behavior
1096// :73:27: note: when computing vector element at index '0'
11091097// :73:27: error: use of undefined value here causes illegal behavior
1110// :73:27: note: when computing vector element at index '1'
1098// :73:27: note: when computing vector element at index '0'
11111099// :73:27: error: use of undefined value here causes illegal behavior
1112// :73:27: note: when computing vector element at index '1'
1100// :73:27: note: when computing vector element at index '0'
11131101// :73:27: error: use of undefined value here causes illegal behavior
1114// :73:27: note: when computing vector element at index '1'
1102// :73:27: note: when computing vector element at index '0'
11151103// :73:27: error: use of undefined value here causes illegal behavior
1116// :73:27: note: when computing vector element at index '1'
1104// :73:27: note: when computing vector element at index '0'
11171105// :73:27: error: use of undefined value here causes illegal behavior
11181106// :73:27: note: when computing vector element at index '0'
11191107// :73:27: error: use of undefined value here causes illegal behavior
......@@ -1123,11 +1111,17 @@ const std = @import("std");
11231111// :73:27: error: use of undefined value here causes illegal behavior
11241112// :73:27: note: when computing vector element at index '0'
11251113// :73:27: error: use of undefined value here causes illegal behavior
1114// :73:27: note: when computing vector element at index '0'
11261115// :73:27: error: use of undefined value here causes illegal behavior
1116// :73:27: note: when computing vector element at index '0'
11271117// :73:27: error: use of undefined value here causes illegal behavior
1118// :73:27: note: when computing vector element at index '0'
11281119// :73:27: error: use of undefined value here causes illegal behavior
1120// :73:27: note: when computing vector element at index '0'
11291121// :73:27: error: use of undefined value here causes illegal behavior
1122// :73:27: note: when computing vector element at index '1'
11301123// :73:27: error: use of undefined value here causes illegal behavior
1124// :73:27: note: when computing vector element at index '1'
11311125// :73:27: error: use of undefined value here causes illegal behavior
11321126// :73:27: note: when computing vector element at index '1'
11331127// :73:27: error: use of undefined value here causes illegal behavior
......@@ -1137,19 +1131,25 @@ const std = @import("std");
11371131// :73:27: error: use of undefined value here causes illegal behavior
11381132// :73:27: note: when computing vector element at index '1'
11391133// :73:27: error: use of undefined value here causes illegal behavior
1140// :73:27: note: when computing vector element at index '0'
1134// :73:27: note: when computing vector element at index '1'
11411135// :73:27: error: use of undefined value here causes illegal behavior
1142// :73:27: note: when computing vector element at index '0'
1136// :73:27: note: when computing vector element at index '1'
11431137// :73:27: error: use of undefined value here causes illegal behavior
1144// :73:27: note: when computing vector element at index '0'
1138// :73:27: note: when computing vector element at index '1'
11451139// :73:27: error: use of undefined value here causes illegal behavior
1146// :73:27: note: when computing vector element at index '0'
1140// :73:27: note: when computing vector element at index '1'
11471141// :73:27: error: use of undefined value here causes illegal behavior
1142// :73:27: note: when computing vector element at index '1'
11481143// :73:27: error: use of undefined value here causes illegal behavior
1144// :73:27: note: when computing vector element at index '1'
11491145// :73:27: error: use of undefined value here causes illegal behavior
1146// :73:27: note: when computing vector element at index '1'
11501147// :73:27: error: use of undefined value here causes illegal behavior
1148// :73:27: note: when computing vector element at index '1'
11511149// :73:27: error: use of undefined value here causes illegal behavior
1150// :73:27: note: when computing vector element at index '1'
11521151// :73:27: error: use of undefined value here causes illegal behavior
1152// :73:27: note: when computing vector element at index '1'
11531153// :73:27: error: use of undefined value here causes illegal behavior
11541154// :73:27: note: when computing vector element at index '1'
11551155// :73:27: error: use of undefined value here causes illegal behavior
......@@ -1159,13 +1159,13 @@ const std = @import("std");
11591159// :73:27: error: use of undefined value here causes illegal behavior
11601160// :73:27: note: when computing vector element at index '1'
11611161// :73:27: error: use of undefined value here causes illegal behavior
1162// :73:27: note: when computing vector element at index '0'
1162// :73:27: note: when computing vector element at index '1'
11631163// :73:27: error: use of undefined value here causes illegal behavior
1164// :73:27: note: when computing vector element at index '0'
1164// :73:27: note: when computing vector element at index '1'
11651165// :73:27: error: use of undefined value here causes illegal behavior
1166// :73:27: note: when computing vector element at index '0'
1166// :73:27: note: when computing vector element at index '1'
11671167// :73:27: error: use of undefined value here causes illegal behavior
1168// :73:27: note: when computing vector element at index '0'
1168// :73:27: note: when computing vector element at index '1'
11691169// :76:34: error: use of undefined value here causes illegal behavior
11701170// :76:34: error: use of undefined value here causes illegal behavior
11711171// :76:34: error: use of undefined value here causes illegal behavior
......@@ -1173,21 +1173,13 @@ const std = @import("std");
11731173// :76:34: error: use of undefined value here causes illegal behavior
11741174// :76:34: error: use of undefined value here causes illegal behavior
11751175// :76:34: error: use of undefined value here causes illegal behavior
1176// :76:34: note: when computing vector element at index '1'
11771176// :76:34: error: use of undefined value here causes illegal behavior
1178// :76:34: note: when computing vector element at index '1'
11791177// :76:34: error: use of undefined value here causes illegal behavior
1180// :76:34: note: when computing vector element at index '1'
11811178// :76:34: error: use of undefined value here causes illegal behavior
1182// :76:34: note: when computing vector element at index '1'
11831179// :76:34: error: use of undefined value here causes illegal behavior
1184// :76:34: note: when computing vector element at index '0'
11851180// :76:34: error: use of undefined value here causes illegal behavior
1186// :76:34: note: when computing vector element at index '0'
11871181// :76:34: error: use of undefined value here causes illegal behavior
1188// :76:34: note: when computing vector element at index '0'
11891182// :76:34: error: use of undefined value here causes illegal behavior
1190// :76:34: note: when computing vector element at index '0'
11911183// :76:34: error: use of undefined value here causes illegal behavior
11921184// :76:34: error: use of undefined value here causes illegal behavior
11931185// :76:34: error: use of undefined value here causes illegal behavior
......@@ -1195,21 +1187,13 @@ const std = @import("std");
11951187// :76:34: error: use of undefined value here causes illegal behavior
11961188// :76:34: error: use of undefined value here causes illegal behavior
11971189// :76:34: error: use of undefined value here causes illegal behavior
1198// :76:34: note: when computing vector element at index '1'
11991190// :76:34: error: use of undefined value here causes illegal behavior
1200// :76:34: note: when computing vector element at index '1'
12011191// :76:34: error: use of undefined value here causes illegal behavior
1202// :76:34: note: when computing vector element at index '1'
12031192// :76:34: error: use of undefined value here causes illegal behavior
1204// :76:34: note: when computing vector element at index '1'
12051193// :76:34: error: use of undefined value here causes illegal behavior
1206// :76:34: note: when computing vector element at index '0'
12071194// :76:34: error: use of undefined value here causes illegal behavior
1208// :76:34: note: when computing vector element at index '0'
12091195// :76:34: error: use of undefined value here causes illegal behavior
1210// :76:34: note: when computing vector element at index '0'
12111196// :76:34: error: use of undefined value here causes illegal behavior
1212// :76:34: note: when computing vector element at index '0'
12131197// :76:34: error: use of undefined value here causes illegal behavior
12141198// :76:34: error: use of undefined value here causes illegal behavior
12151199// :76:34: error: use of undefined value here causes illegal behavior
......@@ -1217,13 +1201,11 @@ const std = @import("std");
12171201// :76:34: error: use of undefined value here causes illegal behavior
12181202// :76:34: error: use of undefined value here causes illegal behavior
12191203// :76:34: error: use of undefined value here causes illegal behavior
1220// :76:34: note: when computing vector element at index '1'
12211204// :76:34: error: use of undefined value here causes illegal behavior
1222// :76:34: note: when computing vector element at index '1'
12231205// :76:34: error: use of undefined value here causes illegal behavior
1224// :76:34: note: when computing vector element at index '1'
1206// :76:34: note: when computing vector element at index '0'
12251207// :76:34: error: use of undefined value here causes illegal behavior
1226// :76:34: note: when computing vector element at index '1'
1208// :76:34: note: when computing vector element at index '0'
12271209// :76:34: error: use of undefined value here causes illegal behavior
12281210// :76:34: note: when computing vector element at index '0'
12291211// :76:34: error: use of undefined value here causes illegal behavior
......@@ -1233,19 +1215,25 @@ const std = @import("std");
12331215// :76:34: error: use of undefined value here causes illegal behavior
12341216// :76:34: note: when computing vector element at index '0'
12351217// :76:34: error: use of undefined value here causes illegal behavior
1218// :76:34: note: when computing vector element at index '0'
12361219// :76:34: error: use of undefined value here causes illegal behavior
1220// :76:34: note: when computing vector element at index '0'
12371221// :76:34: error: use of undefined value here causes illegal behavior
1222// :76:34: note: when computing vector element at index '0'
12381223// :76:34: error: use of undefined value here causes illegal behavior
1224// :76:34: note: when computing vector element at index '0'
12391225// :76:34: error: use of undefined value here causes illegal behavior
1226// :76:34: note: when computing vector element at index '0'
12401227// :76:34: error: use of undefined value here causes illegal behavior
1228// :76:34: note: when computing vector element at index '0'
12411229// :76:34: error: use of undefined value here causes illegal behavior
1242// :76:34: note: when computing vector element at index '1'
1230// :76:34: note: when computing vector element at index '0'
12431231// :76:34: error: use of undefined value here causes illegal behavior
1244// :76:34: note: when computing vector element at index '1'
1232// :76:34: note: when computing vector element at index '0'
12451233// :76:34: error: use of undefined value here causes illegal behavior
1246// :76:34: note: when computing vector element at index '1'
1234// :76:34: note: when computing vector element at index '0'
12471235// :76:34: error: use of undefined value here causes illegal behavior
1248// :76:34: note: when computing vector element at index '1'
1236// :76:34: note: when computing vector element at index '0'
12491237// :76:34: error: use of undefined value here causes illegal behavior
12501238// :76:34: note: when computing vector element at index '0'
12511239// :76:34: error: use of undefined value here causes illegal behavior
......@@ -1255,11 +1243,17 @@ const std = @import("std");
12551243// :76:34: error: use of undefined value here causes illegal behavior
12561244// :76:34: note: when computing vector element at index '0'
12571245// :76:34: error: use of undefined value here causes illegal behavior
1246// :76:34: note: when computing vector element at index '0'
12581247// :76:34: error: use of undefined value here causes illegal behavior
1248// :76:34: note: when computing vector element at index '0'
12591249// :76:34: error: use of undefined value here causes illegal behavior
1250// :76:34: note: when computing vector element at index '0'
12601251// :76:34: error: use of undefined value here causes illegal behavior
1252// :76:34: note: when computing vector element at index '0'
12611253// :76:34: error: use of undefined value here causes illegal behavior
1254// :76:34: note: when computing vector element at index '1'
12621255// :76:34: error: use of undefined value here causes illegal behavior
1256// :76:34: note: when computing vector element at index '1'
12631257// :76:34: error: use of undefined value here causes illegal behavior
12641258// :76:34: note: when computing vector element at index '1'
12651259// :76:34: error: use of undefined value here causes illegal behavior
......@@ -1269,19 +1263,25 @@ const std = @import("std");
12691263// :76:34: error: use of undefined value here causes illegal behavior
12701264// :76:34: note: when computing vector element at index '1'
12711265// :76:34: error: use of undefined value here causes illegal behavior
1272// :76:34: note: when computing vector element at index '0'
1266// :76:34: note: when computing vector element at index '1'
12731267// :76:34: error: use of undefined value here causes illegal behavior
1274// :76:34: note: when computing vector element at index '0'
1268// :76:34: note: when computing vector element at index '1'
12751269// :76:34: error: use of undefined value here causes illegal behavior
1276// :76:34: note: when computing vector element at index '0'
1270// :76:34: note: when computing vector element at index '1'
12771271// :76:34: error: use of undefined value here causes illegal behavior
1278// :76:34: note: when computing vector element at index '0'
1272// :76:34: note: when computing vector element at index '1'
12791273// :76:34: error: use of undefined value here causes illegal behavior
1274// :76:34: note: when computing vector element at index '1'
12801275// :76:34: error: use of undefined value here causes illegal behavior
1276// :76:34: note: when computing vector element at index '1'
12811277// :76:34: error: use of undefined value here causes illegal behavior
1278// :76:34: note: when computing vector element at index '1'
12821279// :76:34: error: use of undefined value here causes illegal behavior
1280// :76:34: note: when computing vector element at index '1'
12831281// :76:34: error: use of undefined value here causes illegal behavior
1282// :76:34: note: when computing vector element at index '1'
12841283// :76:34: error: use of undefined value here causes illegal behavior
1284// :76:34: note: when computing vector element at index '1'
12851285// :76:34: error: use of undefined value here causes illegal behavior
12861286// :76:34: note: when computing vector element at index '1'
12871287// :76:34: error: use of undefined value here causes illegal behavior
......@@ -1291,13 +1291,13 @@ const std = @import("std");
12911291// :76:34: error: use of undefined value here causes illegal behavior
12921292// :76:34: note: when computing vector element at index '1'
12931293// :76:34: error: use of undefined value here causes illegal behavior
1294// :76:34: note: when computing vector element at index '0'
1294// :76:34: note: when computing vector element at index '1'
12951295// :76:34: error: use of undefined value here causes illegal behavior
1296// :76:34: note: when computing vector element at index '0'
1296// :76:34: note: when computing vector element at index '1'
12971297// :76:34: error: use of undefined value here causes illegal behavior
1298// :76:34: note: when computing vector element at index '0'
1298// :76:34: note: when computing vector element at index '1'
12991299// :76:34: error: use of undefined value here causes illegal behavior
1300// :76:34: note: when computing vector element at index '0'
1300// :76:34: note: when computing vector element at index '1'
13011301// :79:17: error: use of undefined value here causes illegal behavior
13021302// :79:17: error: use of undefined value here causes illegal behavior
13031303// :79:17: error: use of undefined value here causes illegal behavior
......@@ -1305,21 +1305,13 @@ const std = @import("std");
13051305// :79:17: error: use of undefined value here causes illegal behavior
13061306// :79:17: error: use of undefined value here causes illegal behavior
13071307// :79:17: error: use of undefined value here causes illegal behavior
1308// :79:17: note: when computing vector element at index '1'
13091308// :79:17: error: use of undefined value here causes illegal behavior
1310// :79:17: note: when computing vector element at index '1'
13111309// :79:17: error: use of undefined value here causes illegal behavior
1312// :79:17: note: when computing vector element at index '1'
13131310// :79:17: error: use of undefined value here causes illegal behavior
1314// :79:17: note: when computing vector element at index '1'
13151311// :79:17: error: use of undefined value here causes illegal behavior
1316// :79:17: note: when computing vector element at index '0'
13171312// :79:17: error: use of undefined value here causes illegal behavior
1318// :79:17: note: when computing vector element at index '0'
13191313// :79:17: error: use of undefined value here causes illegal behavior
1320// :79:17: note: when computing vector element at index '0'
13211314// :79:17: error: use of undefined value here causes illegal behavior
1322// :79:17: note: when computing vector element at index '0'
13231315// :79:17: error: use of undefined value here causes illegal behavior
13241316// :79:17: error: use of undefined value here causes illegal behavior
13251317// :79:17: error: use of undefined value here causes illegal behavior
......@@ -1327,21 +1319,13 @@ const std = @import("std");
13271319// :79:17: error: use of undefined value here causes illegal behavior
13281320// :79:17: error: use of undefined value here causes illegal behavior
13291321// :79:17: error: use of undefined value here causes illegal behavior
1330// :79:17: note: when computing vector element at index '1'
13311322// :79:17: error: use of undefined value here causes illegal behavior
1332// :79:17: note: when computing vector element at index '1'
13331323// :79:17: error: use of undefined value here causes illegal behavior
1334// :79:17: note: when computing vector element at index '1'
13351324// :79:17: error: use of undefined value here causes illegal behavior
1336// :79:17: note: when computing vector element at index '1'
13371325// :79:17: error: use of undefined value here causes illegal behavior
1338// :79:17: note: when computing vector element at index '0'
13391326// :79:17: error: use of undefined value here causes illegal behavior
1340// :79:17: note: when computing vector element at index '0'
13411327// :79:17: error: use of undefined value here causes illegal behavior
1342// :79:17: note: when computing vector element at index '0'
13431328// :79:17: error: use of undefined value here causes illegal behavior
1344// :79:17: note: when computing vector element at index '0'
13451329// :79:17: error: use of undefined value here causes illegal behavior
13461330// :79:17: error: use of undefined value here causes illegal behavior
13471331// :79:17: error: use of undefined value here causes illegal behavior
......@@ -1349,13 +1333,11 @@ const std = @import("std");
13491333// :79:17: error: use of undefined value here causes illegal behavior
13501334// :79:17: error: use of undefined value here causes illegal behavior
13511335// :79:17: error: use of undefined value here causes illegal behavior
1352// :79:17: note: when computing vector element at index '1'
13531336// :79:17: error: use of undefined value here causes illegal behavior
1354// :79:17: note: when computing vector element at index '1'
13551337// :79:17: error: use of undefined value here causes illegal behavior
1356// :79:17: note: when computing vector element at index '1'
1338// :79:17: note: when computing vector element at index '0'
13571339// :79:17: error: use of undefined value here causes illegal behavior
1358// :79:17: note: when computing vector element at index '1'
1340// :79:17: note: when computing vector element at index '0'
13591341// :79:17: error: use of undefined value here causes illegal behavior
13601342// :79:17: note: when computing vector element at index '0'
13611343// :79:17: error: use of undefined value here causes illegal behavior
......@@ -1365,19 +1347,25 @@ const std = @import("std");
13651347// :79:17: error: use of undefined value here causes illegal behavior
13661348// :79:17: note: when computing vector element at index '0'
13671349// :79:17: error: use of undefined value here causes illegal behavior
1350// :79:17: note: when computing vector element at index '0'
13681351// :79:17: error: use of undefined value here causes illegal behavior
1352// :79:17: note: when computing vector element at index '0'
13691353// :79:17: error: use of undefined value here causes illegal behavior
1354// :79:17: note: when computing vector element at index '0'
13701355// :79:17: error: use of undefined value here causes illegal behavior
1356// :79:17: note: when computing vector element at index '0'
13711357// :79:17: error: use of undefined value here causes illegal behavior
1358// :79:17: note: when computing vector element at index '0'
13721359// :79:17: error: use of undefined value here causes illegal behavior
1360// :79:17: note: when computing vector element at index '0'
13731361// :79:17: error: use of undefined value here causes illegal behavior
1374// :79:17: note: when computing vector element at index '1'
1362// :79:17: note: when computing vector element at index '0'
13751363// :79:17: error: use of undefined value here causes illegal behavior
1376// :79:17: note: when computing vector element at index '1'
1364// :79:17: note: when computing vector element at index '0'
13771365// :79:17: error: use of undefined value here causes illegal behavior
1378// :79:17: note: when computing vector element at index '1'
1366// :79:17: note: when computing vector element at index '0'
13791367// :79:17: error: use of undefined value here causes illegal behavior
1380// :79:17: note: when computing vector element at index '1'
1368// :79:17: note: when computing vector element at index '0'
13811369// :79:17: error: use of undefined value here causes illegal behavior
13821370// :79:17: note: when computing vector element at index '0'
13831371// :79:17: error: use of undefined value here causes illegal behavior
......@@ -1387,11 +1375,17 @@ const std = @import("std");
13871375// :79:17: error: use of undefined value here causes illegal behavior
13881376// :79:17: note: when computing vector element at index '0'
13891377// :79:17: error: use of undefined value here causes illegal behavior
1378// :79:17: note: when computing vector element at index '0'
13901379// :79:17: error: use of undefined value here causes illegal behavior
1380// :79:17: note: when computing vector element at index '0'
13911381// :79:17: error: use of undefined value here causes illegal behavior
1382// :79:17: note: when computing vector element at index '0'
13921383// :79:17: error: use of undefined value here causes illegal behavior
1384// :79:17: note: when computing vector element at index '0'
13931385// :79:17: error: use of undefined value here causes illegal behavior
1386// :79:17: note: when computing vector element at index '1'
13941387// :79:17: error: use of undefined value here causes illegal behavior
1388// :79:17: note: when computing vector element at index '1'
13951389// :79:17: error: use of undefined value here causes illegal behavior
13961390// :79:17: note: when computing vector element at index '1'
13971391// :79:17: error: use of undefined value here causes illegal behavior
......@@ -1401,19 +1395,25 @@ const std = @import("std");
14011395// :79:17: error: use of undefined value here causes illegal behavior
14021396// :79:17: note: when computing vector element at index '1'
14031397// :79:17: error: use of undefined value here causes illegal behavior
1404// :79:17: note: when computing vector element at index '0'
1398// :79:17: note: when computing vector element at index '1'
14051399// :79:17: error: use of undefined value here causes illegal behavior
1406// :79:17: note: when computing vector element at index '0'
1400// :79:17: note: when computing vector element at index '1'
14071401// :79:17: error: use of undefined value here causes illegal behavior
1408// :79:17: note: when computing vector element at index '0'
1402// :79:17: note: when computing vector element at index '1'
14091403// :79:17: error: use of undefined value here causes illegal behavior
1410// :79:17: note: when computing vector element at index '0'
1404// :79:17: note: when computing vector element at index '1'
14111405// :79:17: error: use of undefined value here causes illegal behavior
1406// :79:17: note: when computing vector element at index '1'
14121407// :79:17: error: use of undefined value here causes illegal behavior
1408// :79:17: note: when computing vector element at index '1'
14131409// :79:17: error: use of undefined value here causes illegal behavior
1410// :79:17: note: when computing vector element at index '1'
14141411// :79:17: error: use of undefined value here causes illegal behavior
1412// :79:17: note: when computing vector element at index '1'
14151413// :79:17: error: use of undefined value here causes illegal behavior
1414// :79:17: note: when computing vector element at index '1'
14161415// :79:17: error: use of undefined value here causes illegal behavior
1416// :79:17: note: when computing vector element at index '1'
14171417// :79:17: error: use of undefined value here causes illegal behavior
14181418// :79:17: note: when computing vector element at index '1'
14191419// :79:17: error: use of undefined value here causes illegal behavior
......@@ -1423,13 +1423,13 @@ const std = @import("std");
14231423// :79:17: error: use of undefined value here causes illegal behavior
14241424// :79:17: note: when computing vector element at index '1'
14251425// :79:17: error: use of undefined value here causes illegal behavior
1426// :79:17: note: when computing vector element at index '0'
1426// :79:17: note: when computing vector element at index '1'
14271427// :79:17: error: use of undefined value here causes illegal behavior
1428// :79:17: note: when computing vector element at index '0'
1428// :79:17: note: when computing vector element at index '1'
14291429// :79:17: error: use of undefined value here causes illegal behavior
1430// :79:17: note: when computing vector element at index '0'
1430// :79:17: note: when computing vector element at index '1'
14311431// :79:17: error: use of undefined value here causes illegal behavior
1432// :79:17: note: when computing vector element at index '0'
1432// :79:17: note: when computing vector element at index '1'
14331433// :82:27: error: use of undefined value here causes illegal behavior
14341434// :82:27: error: use of undefined value here causes illegal behavior
14351435// :82:27: error: use of undefined value here causes illegal behavior
......@@ -1437,21 +1437,13 @@ const std = @import("std");
14371437// :82:27: error: use of undefined value here causes illegal behavior
14381438// :82:27: error: use of undefined value here causes illegal behavior
14391439// :82:27: error: use of undefined value here causes illegal behavior
1440// :82:27: note: when computing vector element at index '1'
14411440// :82:27: error: use of undefined value here causes illegal behavior
1442// :82:27: note: when computing vector element at index '1'
14431441// :82:27: error: use of undefined value here causes illegal behavior
1444// :82:27: note: when computing vector element at index '1'
14451442// :82:27: error: use of undefined value here causes illegal behavior
1446// :82:27: note: when computing vector element at index '1'
14471443// :82:27: error: use of undefined value here causes illegal behavior
1448// :82:27: note: when computing vector element at index '0'
14491444// :82:27: error: use of undefined value here causes illegal behavior
1450// :82:27: note: when computing vector element at index '0'
14511445// :82:27: error: use of undefined value here causes illegal behavior
1452// :82:27: note: when computing vector element at index '0'
14531446// :82:27: error: use of undefined value here causes illegal behavior
1454// :82:27: note: when computing vector element at index '0'
14551447// :82:27: error: use of undefined value here causes illegal behavior
14561448// :82:27: error: use of undefined value here causes illegal behavior
14571449// :82:27: error: use of undefined value here causes illegal behavior
......@@ -1459,21 +1451,13 @@ const std = @import("std");
14591451// :82:27: error: use of undefined value here causes illegal behavior
14601452// :82:27: error: use of undefined value here causes illegal behavior
14611453// :82:27: error: use of undefined value here causes illegal behavior
1462// :82:27: note: when computing vector element at index '1'
14631454// :82:27: error: use of undefined value here causes illegal behavior
1464// :82:27: note: when computing vector element at index '1'
14651455// :82:27: error: use of undefined value here causes illegal behavior
1466// :82:27: note: when computing vector element at index '1'
14671456// :82:27: error: use of undefined value here causes illegal behavior
1468// :82:27: note: when computing vector element at index '1'
14691457// :82:27: error: use of undefined value here causes illegal behavior
1470// :82:27: note: when computing vector element at index '0'
14711458// :82:27: error: use of undefined value here causes illegal behavior
1472// :82:27: note: when computing vector element at index '0'
14731459// :82:27: error: use of undefined value here causes illegal behavior
1474// :82:27: note: when computing vector element at index '0'
14751460// :82:27: error: use of undefined value here causes illegal behavior
1476// :82:27: note: when computing vector element at index '0'
14771461// :82:27: error: use of undefined value here causes illegal behavior
14781462// :82:27: error: use of undefined value here causes illegal behavior
14791463// :82:27: error: use of undefined value here causes illegal behavior
......@@ -1481,13 +1465,11 @@ const std = @import("std");
14811465// :82:27: error: use of undefined value here causes illegal behavior
14821466// :82:27: error: use of undefined value here causes illegal behavior
14831467// :82:27: error: use of undefined value here causes illegal behavior
1484// :82:27: note: when computing vector element at index '1'
14851468// :82:27: error: use of undefined value here causes illegal behavior
1486// :82:27: note: when computing vector element at index '1'
14871469// :82:27: error: use of undefined value here causes illegal behavior
1488// :82:27: note: when computing vector element at index '1'
1470// :82:27: note: when computing vector element at index '0'
14891471// :82:27: error: use of undefined value here causes illegal behavior
1490// :82:27: note: when computing vector element at index '1'
1472// :82:27: note: when computing vector element at index '0'
14911473// :82:27: error: use of undefined value here causes illegal behavior
14921474// :82:27: note: when computing vector element at index '0'
14931475// :82:27: error: use of undefined value here causes illegal behavior
......@@ -1497,19 +1479,25 @@ const std = @import("std");
14971479// :82:27: error: use of undefined value here causes illegal behavior
14981480// :82:27: note: when computing vector element at index '0'
14991481// :82:27: error: use of undefined value here causes illegal behavior
1482// :82:27: note: when computing vector element at index '0'
15001483// :82:27: error: use of undefined value here causes illegal behavior
1484// :82:27: note: when computing vector element at index '0'
15011485// :82:27: error: use of undefined value here causes illegal behavior
1486// :82:27: note: when computing vector element at index '0'
15021487// :82:27: error: use of undefined value here causes illegal behavior
1488// :82:27: note: when computing vector element at index '0'
15031489// :82:27: error: use of undefined value here causes illegal behavior
1490// :82:27: note: when computing vector element at index '0'
15041491// :82:27: error: use of undefined value here causes illegal behavior
1492// :82:27: note: when computing vector element at index '0'
15051493// :82:27: error: use of undefined value here causes illegal behavior
1506// :82:27: note: when computing vector element at index '1'
1494// :82:27: note: when computing vector element at index '0'
15071495// :82:27: error: use of undefined value here causes illegal behavior
1508// :82:27: note: when computing vector element at index '1'
1496// :82:27: note: when computing vector element at index '0'
15091497// :82:27: error: use of undefined value here causes illegal behavior
1510// :82:27: note: when computing vector element at index '1'
1498// :82:27: note: when computing vector element at index '0'
15111499// :82:27: error: use of undefined value here causes illegal behavior
1512// :82:27: note: when computing vector element at index '1'
1500// :82:27: note: when computing vector element at index '0'
15131501// :82:27: error: use of undefined value here causes illegal behavior
15141502// :82:27: note: when computing vector element at index '0'
15151503// :82:27: error: use of undefined value here causes illegal behavior
......@@ -1519,11 +1507,17 @@ const std = @import("std");
15191507// :82:27: error: use of undefined value here causes illegal behavior
15201508// :82:27: note: when computing vector element at index '0'
15211509// :82:27: error: use of undefined value here causes illegal behavior
1510// :82:27: note: when computing vector element at index '0'
15221511// :82:27: error: use of undefined value here causes illegal behavior
1512// :82:27: note: when computing vector element at index '0'
15231513// :82:27: error: use of undefined value here causes illegal behavior
1514// :82:27: note: when computing vector element at index '0'
15241515// :82:27: error: use of undefined value here causes illegal behavior
1516// :82:27: note: when computing vector element at index '0'
15251517// :82:27: error: use of undefined value here causes illegal behavior
1518// :82:27: note: when computing vector element at index '1'
15261519// :82:27: error: use of undefined value here causes illegal behavior
1520// :82:27: note: when computing vector element at index '1'
15271521// :82:27: error: use of undefined value here causes illegal behavior
15281522// :82:27: note: when computing vector element at index '1'
15291523// :82:27: error: use of undefined value here causes illegal behavior
......@@ -1533,19 +1527,25 @@ const std = @import("std");
15331527// :82:27: error: use of undefined value here causes illegal behavior
15341528// :82:27: note: when computing vector element at index '1'
15351529// :82:27: error: use of undefined value here causes illegal behavior
1536// :82:27: note: when computing vector element at index '0'
1530// :82:27: note: when computing vector element at index '1'
15371531// :82:27: error: use of undefined value here causes illegal behavior
1538// :82:27: note: when computing vector element at index '0'
1532// :82:27: note: when computing vector element at index '1'
15391533// :82:27: error: use of undefined value here causes illegal behavior
1540// :82:27: note: when computing vector element at index '0'
1534// :82:27: note: when computing vector element at index '1'
15411535// :82:27: error: use of undefined value here causes illegal behavior
1542// :82:27: note: when computing vector element at index '0'
1536// :82:27: note: when computing vector element at index '1'
15431537// :82:27: error: use of undefined value here causes illegal behavior
1538// :82:27: note: when computing vector element at index '1'
15441539// :82:27: error: use of undefined value here causes illegal behavior
1540// :82:27: note: when computing vector element at index '1'
15451541// :82:27: error: use of undefined value here causes illegal behavior
1542// :82:27: note: when computing vector element at index '1'
15461543// :82:27: error: use of undefined value here causes illegal behavior
1544// :82:27: note: when computing vector element at index '1'
15471545// :82:27: error: use of undefined value here causes illegal behavior
1546// :82:27: note: when computing vector element at index '1'
15481547// :82:27: error: use of undefined value here causes illegal behavior
1548// :82:27: note: when computing vector element at index '1'
15491549// :82:27: error: use of undefined value here causes illegal behavior
15501550// :82:27: note: when computing vector element at index '1'
15511551// :82:27: error: use of undefined value here causes illegal behavior
......@@ -1555,44 +1555,37 @@ const std = @import("std");
15551555// :82:27: error: use of undefined value here causes illegal behavior
15561556// :82:27: note: when computing vector element at index '1'
15571557// :82:27: error: use of undefined value here causes illegal behavior
1558// :82:27: note: when computing vector element at index '0'
1558// :82:27: note: when computing vector element at index '1'
15591559// :82:27: error: use of undefined value here causes illegal behavior
1560// :82:27: note: when computing vector element at index '0'
1560// :82:27: note: when computing vector element at index '1'
15611561// :82:27: error: use of undefined value here causes illegal behavior
1562// :82:27: note: when computing vector element at index '0'
1562// :82:27: note: when computing vector element at index '1'
15631563// :82:27: error: use of undefined value here causes illegal behavior
1564// :82:27: note: when computing vector element at index '0'
1564// :82:27: note: when computing vector element at index '1'
15651565// :87:17: error: use of undefined value here causes illegal behavior
15661566// :87:17: error: use of undefined value here causes illegal behavior
1567// :87:17: note: when computing vector element at index '0'
15681567// :87:17: error: use of undefined value here causes illegal behavior
1569// :87:17: note: when computing vector element at index '0'
15701568// :87:17: error: use of undefined value here causes illegal behavior
1571// :87:17: note: when computing vector element at index '0'
15721569// :87:17: error: use of undefined value here causes illegal behavior
1573// :87:17: note: when computing vector element at index '1'
15741570// :87:17: error: use of undefined value here causes illegal behavior
1575// :87:17: note: when computing vector element at index '0'
15761571// :87:17: error: use of undefined value here causes illegal behavior
15771572// :87:17: note: when computing vector element at index '0'
15781573// :87:17: error: use of undefined value here causes illegal behavior
15791574// :87:17: note: when computing vector element at index '0'
15801575// :87:17: error: use of undefined value here causes illegal behavior
1581// :87:17: error: use of undefined value here causes illegal behavior
15821576// :87:17: note: when computing vector element at index '0'
15831577// :87:17: error: use of undefined value here causes illegal behavior
15841578// :87:17: note: when computing vector element at index '0'
15851579// :87:17: error: use of undefined value here causes illegal behavior
15861580// :87:17: note: when computing vector element at index '0'
15871581// :87:17: error: use of undefined value here causes illegal behavior
1588// :87:17: note: when computing vector element at index '1'
1589// :87:17: error: use of undefined value here causes illegal behavior
15901582// :87:17: note: when computing vector element at index '0'
15911583// :87:17: error: use of undefined value here causes illegal behavior
15921584// :87:17: note: when computing vector element at index '0'
15931585// :87:17: error: use of undefined value here causes illegal behavior
15941586// :87:17: note: when computing vector element at index '0'
15951587// :87:17: error: use of undefined value here causes illegal behavior
1588// :87:17: note: when computing vector element at index '0'
15961589// :87:17: error: use of undefined value here causes illegal behavior
15971590// :87:17: note: when computing vector element at index '0'
15981591// :87:17: error: use of undefined value here causes illegal behavior
......@@ -1600,7 +1593,7 @@ const std = @import("std");
16001593// :87:17: error: use of undefined value here causes illegal behavior
16011594// :87:17: note: when computing vector element at index '0'
16021595// :87:17: error: use of undefined value here causes illegal behavior
1603// :87:17: note: when computing vector element at index '1'
1596// :87:17: note: when computing vector element at index '0'
16041597// :87:17: error: use of undefined value here causes illegal behavior
16051598// :87:17: note: when computing vector element at index '0'
16061599// :87:17: error: use of undefined value here causes illegal behavior
......@@ -1608,6 +1601,7 @@ const std = @import("std");
16081601// :87:17: error: use of undefined value here causes illegal behavior
16091602// :87:17: note: when computing vector element at index '0'
16101603// :87:17: error: use of undefined value here causes illegal behavior
1604// :87:17: note: when computing vector element at index '0'
16111605// :87:17: error: use of undefined value here causes illegal behavior
16121606// :87:17: note: when computing vector element at index '0'
16131607// :87:17: error: use of undefined value here causes illegal behavior
......@@ -1615,7 +1609,7 @@ const std = @import("std");
16151609// :87:17: error: use of undefined value here causes illegal behavior
16161610// :87:17: note: when computing vector element at index '0'
16171611// :87:17: error: use of undefined value here causes illegal behavior
1618// :87:17: note: when computing vector element at index '1'
1612// :87:17: note: when computing vector element at index '0'
16191613// :87:17: error: use of undefined value here causes illegal behavior
16201614// :87:17: note: when computing vector element at index '0'
16211615// :87:17: error: use of undefined value here causes illegal behavior
......@@ -1623,6 +1617,7 @@ const std = @import("std");
16231617// :87:17: error: use of undefined value here causes illegal behavior
16241618// :87:17: note: when computing vector element at index '0'
16251619// :87:17: error: use of undefined value here causes illegal behavior
1620// :87:17: note: when computing vector element at index '0'
16261621// :87:17: error: use of undefined value here causes illegal behavior
16271622// :87:17: note: when computing vector element at index '0'
16281623// :87:17: error: use of undefined value here causes illegal behavior
......@@ -1630,7 +1625,7 @@ const std = @import("std");
16301625// :87:17: error: use of undefined value here causes illegal behavior
16311626// :87:17: note: when computing vector element at index '0'
16321627// :87:17: error: use of undefined value here causes illegal behavior
1633// :87:17: note: when computing vector element at index '1'
1628// :87:17: note: when computing vector element at index '0'
16341629// :87:17: error: use of undefined value here causes illegal behavior
16351630// :87:17: note: when computing vector element at index '0'
16361631// :87:17: error: use of undefined value here causes illegal behavior
......@@ -1638,6 +1633,7 @@ const std = @import("std");
16381633// :87:17: error: use of undefined value here causes illegal behavior
16391634// :87:17: note: when computing vector element at index '0'
16401635// :87:17: error: use of undefined value here causes illegal behavior
1636// :87:17: note: when computing vector element at index '0'
16411637// :87:17: error: use of undefined value here causes illegal behavior
16421638// :87:17: note: when computing vector element at index '0'
16431639// :87:17: error: use of undefined value here causes illegal behavior
......@@ -1647,108 +1643,105 @@ const std = @import("std");
16471643// :87:17: error: use of undefined value here causes illegal behavior
16481644// :87:17: note: when computing vector element at index '1'
16491645// :87:17: error: use of undefined value here causes illegal behavior
1650// :87:17: note: when computing vector element at index '0'
1646// :87:17: note: when computing vector element at index '1'
16511647// :87:17: error: use of undefined value here causes illegal behavior
1652// :87:17: note: when computing vector element at index '0'
1648// :87:17: note: when computing vector element at index '1'
16531649// :87:17: error: use of undefined value here causes illegal behavior
1654// :87:17: note: when computing vector element at index '0'
1650// :87:17: note: when computing vector element at index '1'
1651// :87:17: error: use of undefined value here causes illegal behavior
1652// :87:17: note: when computing vector element at index '1'
1653// :87:17: error: use of undefined value here causes illegal behavior
1654// :87:17: note: when computing vector element at index '1'
16551655// :87:22: error: use of undefined value here causes illegal behavior
16561656// :87:22: error: use of undefined value here causes illegal behavior
1657// :87:22: note: when computing vector element at index '0'
16581657// :87:22: error: use of undefined value here causes illegal behavior
1659// :87:22: note: when computing vector element at index '0'
16601658// :87:22: error: use of undefined value here causes illegal behavior
1661// :87:22: note: when computing vector element at index '1'
16621659// :87:22: error: use of undefined value here causes illegal behavior
1663// :87:22: note: when computing vector element at index '0'
16641660// :87:22: error: use of undefined value here causes illegal behavior
1665// :87:22: note: when computing vector element at index '0'
16661661// :87:22: error: use of undefined value here causes illegal behavior
1662// :87:22: note: when computing vector element at index '0'
16671663// :87:22: error: use of undefined value here causes illegal behavior
16681664// :87:22: note: when computing vector element at index '0'
16691665// :87:22: error: use of undefined value here causes illegal behavior
16701666// :87:22: note: when computing vector element at index '0'
16711667// :87:22: error: use of undefined value here causes illegal behavior
1672// :87:22: note: when computing vector element at index '1'
1668// :87:22: note: when computing vector element at index '0'
16731669// :87:22: error: use of undefined value here causes illegal behavior
16741670// :87:22: note: when computing vector element at index '0'
16751671// :87:22: error: use of undefined value here causes illegal behavior
16761672// :87:22: note: when computing vector element at index '0'
16771673// :87:22: error: use of undefined value here causes illegal behavior
1674// :87:22: note: when computing vector element at index '0'
16781675// :87:22: error: use of undefined value here causes illegal behavior
16791676// :87:22: note: when computing vector element at index '0'
16801677// :87:22: error: use of undefined value here causes illegal behavior
16811678// :87:22: note: when computing vector element at index '0'
16821679// :87:22: error: use of undefined value here causes illegal behavior
1683// :87:22: note: when computing vector element at index '1'
1680// :87:22: note: when computing vector element at index '0'
16841681// :87:22: error: use of undefined value here causes illegal behavior
16851682// :87:22: note: when computing vector element at index '0'
16861683// :87:22: error: use of undefined value here causes illegal behavior
16871684// :87:22: note: when computing vector element at index '0'
16881685// :87:22: error: use of undefined value here causes illegal behavior
1686// :87:22: note: when computing vector element at index '0'
16891687// :87:22: error: use of undefined value here causes illegal behavior
16901688// :87:22: note: when computing vector element at index '0'
16911689// :87:22: error: use of undefined value here causes illegal behavior
16921690// :87:22: note: when computing vector element at index '0'
16931691// :87:22: error: use of undefined value here causes illegal behavior
1694// :87:22: note: when computing vector element at index '1'
1692// :87:22: note: when computing vector element at index '0'
16951693// :87:22: error: use of undefined value here causes illegal behavior
16961694// :87:22: note: when computing vector element at index '0'
16971695// :87:22: error: use of undefined value here causes illegal behavior
16981696// :87:22: note: when computing vector element at index '0'
16991697// :87:22: error: use of undefined value here causes illegal behavior
1698// :87:22: note: when computing vector element at index '0'
17001699// :87:22: error: use of undefined value here causes illegal behavior
17011700// :87:22: note: when computing vector element at index '0'
17021701// :87:22: error: use of undefined value here causes illegal behavior
17031702// :87:22: note: when computing vector element at index '0'
17041703// :87:22: error: use of undefined value here causes illegal behavior
1705// :87:22: note: when computing vector element at index '1'
1704// :87:22: note: when computing vector element at index '0'
17061705// :87:22: error: use of undefined value here causes illegal behavior
17071706// :87:22: note: when computing vector element at index '0'
17081707// :87:22: error: use of undefined value here causes illegal behavior
17091708// :87:22: note: when computing vector element at index '0'
17101709// :87:22: error: use of undefined value here causes illegal behavior
1710// :87:22: note: when computing vector element at index '1'
17111711// :87:22: error: use of undefined value here causes illegal behavior
1712// :87:22: note: when computing vector element at index '0'
1712// :87:22: note: when computing vector element at index '1'
17131713// :87:22: error: use of undefined value here causes illegal behavior
1714// :87:22: note: when computing vector element at index '0'
1714// :87:22: note: when computing vector element at index '1'
17151715// :87:22: error: use of undefined value here causes illegal behavior
17161716// :87:22: note: when computing vector element at index '1'
17171717// :87:22: error: use of undefined value here causes illegal behavior
1718// :87:22: note: when computing vector element at index '0'
1718// :87:22: note: when computing vector element at index '1'
17191719// :87:22: error: use of undefined value here causes illegal behavior
1720// :87:22: note: when computing vector element at index '0'
1720// :87:22: note: when computing vector element at index '1'
17211721// :90:27: error: use of undefined value here causes illegal behavior
17221722// :90:27: error: use of undefined value here causes illegal behavior
1723// :90:27: note: when computing vector element at index '0'
17241723// :90:27: error: use of undefined value here causes illegal behavior
1725// :90:27: note: when computing vector element at index '0'
17261724// :90:27: error: use of undefined value here causes illegal behavior
1727// :90:27: note: when computing vector element at index '0'
17281725// :90:27: error: use of undefined value here causes illegal behavior
1729// :90:27: note: when computing vector element at index '1'
17301726// :90:27: error: use of undefined value here causes illegal behavior
1731// :90:27: note: when computing vector element at index '0'
17321727// :90:27: error: use of undefined value here causes illegal behavior
17331728// :90:27: note: when computing vector element at index '0'
17341729// :90:27: error: use of undefined value here causes illegal behavior
17351730// :90:27: note: when computing vector element at index '0'
17361731// :90:27: error: use of undefined value here causes illegal behavior
1737// :90:27: error: use of undefined value here causes illegal behavior
17381732// :90:27: note: when computing vector element at index '0'
17391733// :90:27: error: use of undefined value here causes illegal behavior
17401734// :90:27: note: when computing vector element at index '0'
17411735// :90:27: error: use of undefined value here causes illegal behavior
17421736// :90:27: note: when computing vector element at index '0'
17431737// :90:27: error: use of undefined value here causes illegal behavior
1744// :90:27: note: when computing vector element at index '1'
1745// :90:27: error: use of undefined value here causes illegal behavior
17461738// :90:27: note: when computing vector element at index '0'
17471739// :90:27: error: use of undefined value here causes illegal behavior
17481740// :90:27: note: when computing vector element at index '0'
17491741// :90:27: error: use of undefined value here causes illegal behavior
17501742// :90:27: note: when computing vector element at index '0'
17511743// :90:27: error: use of undefined value here causes illegal behavior
1744// :90:27: note: when computing vector element at index '0'
17521745// :90:27: error: use of undefined value here causes illegal behavior
17531746// :90:27: note: when computing vector element at index '0'
17541747// :90:27: error: use of undefined value here causes illegal behavior
......@@ -1756,7 +1749,7 @@ const std = @import("std");
17561749// :90:27: error: use of undefined value here causes illegal behavior
17571750// :90:27: note: when computing vector element at index '0'
17581751// :90:27: error: use of undefined value here causes illegal behavior
1759// :90:27: note: when computing vector element at index '1'
1752// :90:27: note: when computing vector element at index '0'
17601753// :90:27: error: use of undefined value here causes illegal behavior
17611754// :90:27: note: when computing vector element at index '0'
17621755// :90:27: error: use of undefined value here causes illegal behavior
......@@ -1764,6 +1757,7 @@ const std = @import("std");
17641757// :90:27: error: use of undefined value here causes illegal behavior
17651758// :90:27: note: when computing vector element at index '0'
17661759// :90:27: error: use of undefined value here causes illegal behavior
1760// :90:27: note: when computing vector element at index '0'
17671761// :90:27: error: use of undefined value here causes illegal behavior
17681762// :90:27: note: when computing vector element at index '0'
17691763// :90:27: error: use of undefined value here causes illegal behavior
......@@ -1771,7 +1765,7 @@ const std = @import("std");
17711765// :90:27: error: use of undefined value here causes illegal behavior
17721766// :90:27: note: when computing vector element at index '0'
17731767// :90:27: error: use of undefined value here causes illegal behavior
1774// :90:27: note: when computing vector element at index '1'
1768// :90:27: note: when computing vector element at index '0'
17751769// :90:27: error: use of undefined value here causes illegal behavior
17761770// :90:27: note: when computing vector element at index '0'
17771771// :90:27: error: use of undefined value here causes illegal behavior
......@@ -1779,6 +1773,7 @@ const std = @import("std");
17791773// :90:27: error: use of undefined value here causes illegal behavior
17801774// :90:27: note: when computing vector element at index '0'
17811775// :90:27: error: use of undefined value here causes illegal behavior
1776// :90:27: note: when computing vector element at index '0'
17821777// :90:27: error: use of undefined value here causes illegal behavior
17831778// :90:27: note: when computing vector element at index '0'
17841779// :90:27: error: use of undefined value here causes illegal behavior
......@@ -1786,7 +1781,7 @@ const std = @import("std");
17861781// :90:27: error: use of undefined value here causes illegal behavior
17871782// :90:27: note: when computing vector element at index '0'
17881783// :90:27: error: use of undefined value here causes illegal behavior
1789// :90:27: note: when computing vector element at index '1'
1784// :90:27: note: when computing vector element at index '0'
17901785// :90:27: error: use of undefined value here causes illegal behavior
17911786// :90:27: note: when computing vector element at index '0'
17921787// :90:27: error: use of undefined value here causes illegal behavior
......@@ -1794,6 +1789,7 @@ const std = @import("std");
17941789// :90:27: error: use of undefined value here causes illegal behavior
17951790// :90:27: note: when computing vector element at index '0'
17961791// :90:27: error: use of undefined value here causes illegal behavior
1792// :90:27: note: when computing vector element at index '0'
17971793// :90:27: error: use of undefined value here causes illegal behavior
17981794// :90:27: note: when computing vector element at index '0'
17991795// :90:27: error: use of undefined value here causes illegal behavior
......@@ -1803,108 +1799,105 @@ const std = @import("std");
18031799// :90:27: error: use of undefined value here causes illegal behavior
18041800// :90:27: note: when computing vector element at index '1'
18051801// :90:27: error: use of undefined value here causes illegal behavior
1806// :90:27: note: when computing vector element at index '0'
1802// :90:27: note: when computing vector element at index '1'
18071803// :90:27: error: use of undefined value here causes illegal behavior
1808// :90:27: note: when computing vector element at index '0'
1804// :90:27: note: when computing vector element at index '1'
18091805// :90:27: error: use of undefined value here causes illegal behavior
1810// :90:27: note: when computing vector element at index '0'
1806// :90:27: note: when computing vector element at index '1'
1807// :90:27: error: use of undefined value here causes illegal behavior
1808// :90:27: note: when computing vector element at index '1'
1809// :90:27: error: use of undefined value here causes illegal behavior
1810// :90:27: note: when computing vector element at index '1'
18111811// :90:30: error: use of undefined value here causes illegal behavior
18121812// :90:30: error: use of undefined value here causes illegal behavior
1813// :90:30: note: when computing vector element at index '0'
18141813// :90:30: error: use of undefined value here causes illegal behavior
1815// :90:30: note: when computing vector element at index '0'
18161814// :90:30: error: use of undefined value here causes illegal behavior
1817// :90:30: note: when computing vector element at index '1'
18181815// :90:30: error: use of undefined value here causes illegal behavior
1819// :90:30: note: when computing vector element at index '0'
18201816// :90:30: error: use of undefined value here causes illegal behavior
1821// :90:30: note: when computing vector element at index '0'
18221817// :90:30: error: use of undefined value here causes illegal behavior
1818// :90:30: note: when computing vector element at index '0'
18231819// :90:30: error: use of undefined value here causes illegal behavior
18241820// :90:30: note: when computing vector element at index '0'
18251821// :90:30: error: use of undefined value here causes illegal behavior
18261822// :90:30: note: when computing vector element at index '0'
18271823// :90:30: error: use of undefined value here causes illegal behavior
1828// :90:30: note: when computing vector element at index '1'
1824// :90:30: note: when computing vector element at index '0'
18291825// :90:30: error: use of undefined value here causes illegal behavior
18301826// :90:30: note: when computing vector element at index '0'
18311827// :90:30: error: use of undefined value here causes illegal behavior
18321828// :90:30: note: when computing vector element at index '0'
18331829// :90:30: error: use of undefined value here causes illegal behavior
1830// :90:30: note: when computing vector element at index '0'
18341831// :90:30: error: use of undefined value here causes illegal behavior
18351832// :90:30: note: when computing vector element at index '0'
18361833// :90:30: error: use of undefined value here causes illegal behavior
18371834// :90:30: note: when computing vector element at index '0'
18381835// :90:30: error: use of undefined value here causes illegal behavior
1839// :90:30: note: when computing vector element at index '1'
1836// :90:30: note: when computing vector element at index '0'
18401837// :90:30: error: use of undefined value here causes illegal behavior
18411838// :90:30: note: when computing vector element at index '0'
18421839// :90:30: error: use of undefined value here causes illegal behavior
18431840// :90:30: note: when computing vector element at index '0'
18441841// :90:30: error: use of undefined value here causes illegal behavior
1842// :90:30: note: when computing vector element at index '0'
18451843// :90:30: error: use of undefined value here causes illegal behavior
18461844// :90:30: note: when computing vector element at index '0'
18471845// :90:30: error: use of undefined value here causes illegal behavior
18481846// :90:30: note: when computing vector element at index '0'
18491847// :90:30: error: use of undefined value here causes illegal behavior
1850// :90:30: note: when computing vector element at index '1'
1848// :90:30: note: when computing vector element at index '0'
18511849// :90:30: error: use of undefined value here causes illegal behavior
18521850// :90:30: note: when computing vector element at index '0'
18531851// :90:30: error: use of undefined value here causes illegal behavior
18541852// :90:30: note: when computing vector element at index '0'
18551853// :90:30: error: use of undefined value here causes illegal behavior
1854// :90:30: note: when computing vector element at index '0'
18561855// :90:30: error: use of undefined value here causes illegal behavior
18571856// :90:30: note: when computing vector element at index '0'
18581857// :90:30: error: use of undefined value here causes illegal behavior
18591858// :90:30: note: when computing vector element at index '0'
18601859// :90:30: error: use of undefined value here causes illegal behavior
1861// :90:30: note: when computing vector element at index '1'
1860// :90:30: note: when computing vector element at index '0'
18621861// :90:30: error: use of undefined value here causes illegal behavior
18631862// :90:30: note: when computing vector element at index '0'
18641863// :90:30: error: use of undefined value here causes illegal behavior
18651864// :90:30: note: when computing vector element at index '0'
18661865// :90:30: error: use of undefined value here causes illegal behavior
1866// :90:30: note: when computing vector element at index '1'
18671867// :90:30: error: use of undefined value here causes illegal behavior
1868// :90:30: note: when computing vector element at index '0'
1868// :90:30: note: when computing vector element at index '1'
18691869// :90:30: error: use of undefined value here causes illegal behavior
1870// :90:30: note: when computing vector element at index '0'
1870// :90:30: note: when computing vector element at index '1'
18711871// :90:30: error: use of undefined value here causes illegal behavior
18721872// :90:30: note: when computing vector element at index '1'
18731873// :90:30: error: use of undefined value here causes illegal behavior
1874// :90:30: note: when computing vector element at index '0'
1874// :90:30: note: when computing vector element at index '1'
18751875// :90:30: error: use of undefined value here causes illegal behavior
1876// :90:30: note: when computing vector element at index '0'
1876// :90:30: note: when computing vector element at index '1'
18771877// :93:34: error: use of undefined value here causes illegal behavior
18781878// :93:34: error: use of undefined value here causes illegal behavior
1879// :93:34: note: when computing vector element at index '0'
18801879// :93:34: error: use of undefined value here causes illegal behavior
1881// :93:34: note: when computing vector element at index '0'
18821880// :93:34: error: use of undefined value here causes illegal behavior
1883// :93:34: note: when computing vector element at index '0'
18841881// :93:34: error: use of undefined value here causes illegal behavior
1885// :93:34: note: when computing vector element at index '1'
18861882// :93:34: error: use of undefined value here causes illegal behavior
1887// :93:34: note: when computing vector element at index '0'
18881883// :93:34: error: use of undefined value here causes illegal behavior
18891884// :93:34: note: when computing vector element at index '0'
18901885// :93:34: error: use of undefined value here causes illegal behavior
18911886// :93:34: note: when computing vector element at index '0'
18921887// :93:34: error: use of undefined value here causes illegal behavior
1893// :93:34: error: use of undefined value here causes illegal behavior
18941888// :93:34: note: when computing vector element at index '0'
18951889// :93:34: error: use of undefined value here causes illegal behavior
18961890// :93:34: note: when computing vector element at index '0'
18971891// :93:34: error: use of undefined value here causes illegal behavior
18981892// :93:34: note: when computing vector element at index '0'
18991893// :93:34: error: use of undefined value here causes illegal behavior
1900// :93:34: note: when computing vector element at index '1'
1901// :93:34: error: use of undefined value here causes illegal behavior
19021894// :93:34: note: when computing vector element at index '0'
19031895// :93:34: error: use of undefined value here causes illegal behavior
19041896// :93:34: note: when computing vector element at index '0'
19051897// :93:34: error: use of undefined value here causes illegal behavior
19061898// :93:34: note: when computing vector element at index '0'
19071899// :93:34: error: use of undefined value here causes illegal behavior
1900// :93:34: note: when computing vector element at index '0'
19081901// :93:34: error: use of undefined value here causes illegal behavior
19091902// :93:34: note: when computing vector element at index '0'
19101903// :93:34: error: use of undefined value here causes illegal behavior
......@@ -1912,7 +1905,7 @@ const std = @import("std");
19121905// :93:34: error: use of undefined value here causes illegal behavior
19131906// :93:34: note: when computing vector element at index '0'
19141907// :93:34: error: use of undefined value here causes illegal behavior
1915// :93:34: note: when computing vector element at index '1'
1908// :93:34: note: when computing vector element at index '0'
19161909// :93:34: error: use of undefined value here causes illegal behavior
19171910// :93:34: note: when computing vector element at index '0'
19181911// :93:34: error: use of undefined value here causes illegal behavior
......@@ -1920,6 +1913,7 @@ const std = @import("std");
19201913// :93:34: error: use of undefined value here causes illegal behavior
19211914// :93:34: note: when computing vector element at index '0'
19221915// :93:34: error: use of undefined value here causes illegal behavior
1916// :93:34: note: when computing vector element at index '0'
19231917// :93:34: error: use of undefined value here causes illegal behavior
19241918// :93:34: note: when computing vector element at index '0'
19251919// :93:34: error: use of undefined value here causes illegal behavior
......@@ -1927,7 +1921,7 @@ const std = @import("std");
19271921// :93:34: error: use of undefined value here causes illegal behavior
19281922// :93:34: note: when computing vector element at index '0'
19291923// :93:34: error: use of undefined value here causes illegal behavior
1930// :93:34: note: when computing vector element at index '1'
1924// :93:34: note: when computing vector element at index '0'
19311925// :93:34: error: use of undefined value here causes illegal behavior
19321926// :93:34: note: when computing vector element at index '0'
19331927// :93:34: error: use of undefined value here causes illegal behavior
......@@ -1935,6 +1929,7 @@ const std = @import("std");
19351929// :93:34: error: use of undefined value here causes illegal behavior
19361930// :93:34: note: when computing vector element at index '0'
19371931// :93:34: error: use of undefined value here causes illegal behavior
1932// :93:34: note: when computing vector element at index '0'
19381933// :93:34: error: use of undefined value here causes illegal behavior
19391934// :93:34: note: when computing vector element at index '0'
19401935// :93:34: error: use of undefined value here causes illegal behavior
......@@ -1942,7 +1937,7 @@ const std = @import("std");
19421937// :93:34: error: use of undefined value here causes illegal behavior
19431938// :93:34: note: when computing vector element at index '0'
19441939// :93:34: error: use of undefined value here causes illegal behavior
1945// :93:34: note: when computing vector element at index '1'
1940// :93:34: note: when computing vector element at index '0'
19461941// :93:34: error: use of undefined value here causes illegal behavior
19471942// :93:34: note: when computing vector element at index '0'
19481943// :93:34: error: use of undefined value here causes illegal behavior
......@@ -1950,6 +1945,7 @@ const std = @import("std");
19501945// :93:34: error: use of undefined value here causes illegal behavior
19511946// :93:34: note: when computing vector element at index '0'
19521947// :93:34: error: use of undefined value here causes illegal behavior
1948// :93:34: note: when computing vector element at index '0'
19531949// :93:34: error: use of undefined value here causes illegal behavior
19541950// :93:34: note: when computing vector element at index '0'
19551951// :93:34: error: use of undefined value here causes illegal behavior
......@@ -1959,108 +1955,105 @@ const std = @import("std");
19591955// :93:34: error: use of undefined value here causes illegal behavior
19601956// :93:34: note: when computing vector element at index '1'
19611957// :93:34: error: use of undefined value here causes illegal behavior
1962// :93:34: note: when computing vector element at index '0'
1958// :93:34: note: when computing vector element at index '1'
19631959// :93:34: error: use of undefined value here causes illegal behavior
1964// :93:34: note: when computing vector element at index '0'
1960// :93:34: note: when computing vector element at index '1'
19651961// :93:34: error: use of undefined value here causes illegal behavior
1966// :93:34: note: when computing vector element at index '0'
1962// :93:34: note: when computing vector element at index '1'
1963// :93:34: error: use of undefined value here causes illegal behavior
1964// :93:34: note: when computing vector element at index '1'
1965// :93:34: error: use of undefined value here causes illegal behavior
1966// :93:34: note: when computing vector element at index '1'
19671967// :93:37: error: use of undefined value here causes illegal behavior
19681968// :93:37: error: use of undefined value here causes illegal behavior
1969// :93:37: note: when computing vector element at index '0'
19701969// :93:37: error: use of undefined value here causes illegal behavior
1971// :93:37: note: when computing vector element at index '0'
19721970// :93:37: error: use of undefined value here causes illegal behavior
1973// :93:37: note: when computing vector element at index '1'
19741971// :93:37: error: use of undefined value here causes illegal behavior
1975// :93:37: note: when computing vector element at index '0'
19761972// :93:37: error: use of undefined value here causes illegal behavior
1977// :93:37: note: when computing vector element at index '0'
19781973// :93:37: error: use of undefined value here causes illegal behavior
1974// :93:37: note: when computing vector element at index '0'
19791975// :93:37: error: use of undefined value here causes illegal behavior
19801976// :93:37: note: when computing vector element at index '0'
19811977// :93:37: error: use of undefined value here causes illegal behavior
19821978// :93:37: note: when computing vector element at index '0'
19831979// :93:37: error: use of undefined value here causes illegal behavior
1984// :93:37: note: when computing vector element at index '1'
1980// :93:37: note: when computing vector element at index '0'
19851981// :93:37: error: use of undefined value here causes illegal behavior
19861982// :93:37: note: when computing vector element at index '0'
19871983// :93:37: error: use of undefined value here causes illegal behavior
19881984// :93:37: note: when computing vector element at index '0'
19891985// :93:37: error: use of undefined value here causes illegal behavior
1986// :93:37: note: when computing vector element at index '0'
19901987// :93:37: error: use of undefined value here causes illegal behavior
19911988// :93:37: note: when computing vector element at index '0'
19921989// :93:37: error: use of undefined value here causes illegal behavior
19931990// :93:37: note: when computing vector element at index '0'
19941991// :93:37: error: use of undefined value here causes illegal behavior
1995// :93:37: note: when computing vector element at index '1'
1992// :93:37: note: when computing vector element at index '0'
19961993// :93:37: error: use of undefined value here causes illegal behavior
19971994// :93:37: note: when computing vector element at index '0'
19981995// :93:37: error: use of undefined value here causes illegal behavior
19991996// :93:37: note: when computing vector element at index '0'
20001997// :93:37: error: use of undefined value here causes illegal behavior
1998// :93:37: note: when computing vector element at index '0'
20011999// :93:37: error: use of undefined value here causes illegal behavior
20022000// :93:37: note: when computing vector element at index '0'
20032001// :93:37: error: use of undefined value here causes illegal behavior
20042002// :93:37: note: when computing vector element at index '0'
20052003// :93:37: error: use of undefined value here causes illegal behavior
2006// :93:37: note: when computing vector element at index '1'
2004// :93:37: note: when computing vector element at index '0'
20072005// :93:37: error: use of undefined value here causes illegal behavior
20082006// :93:37: note: when computing vector element at index '0'
20092007// :93:37: error: use of undefined value here causes illegal behavior
20102008// :93:37: note: when computing vector element at index '0'
20112009// :93:37: error: use of undefined value here causes illegal behavior
2010// :93:37: note: when computing vector element at index '0'
20122011// :93:37: error: use of undefined value here causes illegal behavior
20132012// :93:37: note: when computing vector element at index '0'
20142013// :93:37: error: use of undefined value here causes illegal behavior
20152014// :93:37: note: when computing vector element at index '0'
20162015// :93:37: error: use of undefined value here causes illegal behavior
2017// :93:37: note: when computing vector element at index '1'
2016// :93:37: note: when computing vector element at index '0'
20182017// :93:37: error: use of undefined value here causes illegal behavior
20192018// :93:37: note: when computing vector element at index '0'
20202019// :93:37: error: use of undefined value here causes illegal behavior
20212020// :93:37: note: when computing vector element at index '0'
20222021// :93:37: error: use of undefined value here causes illegal behavior
2022// :93:37: note: when computing vector element at index '1'
20232023// :93:37: error: use of undefined value here causes illegal behavior
2024// :93:37: note: when computing vector element at index '0'
2024// :93:37: note: when computing vector element at index '1'
20252025// :93:37: error: use of undefined value here causes illegal behavior
2026// :93:37: note: when computing vector element at index '0'
2026// :93:37: note: when computing vector element at index '1'
20272027// :93:37: error: use of undefined value here causes illegal behavior
20282028// :93:37: note: when computing vector element at index '1'
20292029// :93:37: error: use of undefined value here causes illegal behavior
2030// :93:37: note: when computing vector element at index '0'
2030// :93:37: note: when computing vector element at index '1'
20312031// :93:37: error: use of undefined value here causes illegal behavior
2032// :93:37: note: when computing vector element at index '0'
2032// :93:37: note: when computing vector element at index '1'
20332033// :96:17: error: use of undefined value here causes illegal behavior
20342034// :96:17: error: use of undefined value here causes illegal behavior
2035// :96:17: note: when computing vector element at index '0'
20362035// :96:17: error: use of undefined value here causes illegal behavior
2037// :96:17: note: when computing vector element at index '0'
20382036// :96:17: error: use of undefined value here causes illegal behavior
2039// :96:17: note: when computing vector element at index '0'
20402037// :96:17: error: use of undefined value here causes illegal behavior
2041// :96:17: note: when computing vector element at index '1'
20422038// :96:17: error: use of undefined value here causes illegal behavior
2043// :96:17: note: when computing vector element at index '0'
20442039// :96:17: error: use of undefined value here causes illegal behavior
20452040// :96:17: note: when computing vector element at index '0'
20462041// :96:17: error: use of undefined value here causes illegal behavior
20472042// :96:17: note: when computing vector element at index '0'
20482043// :96:17: error: use of undefined value here causes illegal behavior
2049// :96:17: error: use of undefined value here causes illegal behavior
20502044// :96:17: note: when computing vector element at index '0'
20512045// :96:17: error: use of undefined value here causes illegal behavior
20522046// :96:17: note: when computing vector element at index '0'
20532047// :96:17: error: use of undefined value here causes illegal behavior
20542048// :96:17: note: when computing vector element at index '0'
20552049// :96:17: error: use of undefined value here causes illegal behavior
2056// :96:17: note: when computing vector element at index '1'
2057// :96:17: error: use of undefined value here causes illegal behavior
20582050// :96:17: note: when computing vector element at index '0'
20592051// :96:17: error: use of undefined value here causes illegal behavior
20602052// :96:17: note: when computing vector element at index '0'
20612053// :96:17: error: use of undefined value here causes illegal behavior
20622054// :96:17: note: when computing vector element at index '0'
20632055// :96:17: error: use of undefined value here causes illegal behavior
2056// :96:17: note: when computing vector element at index '0'
20642057// :96:17: error: use of undefined value here causes illegal behavior
20652058// :96:17: note: when computing vector element at index '0'
20662059// :96:17: error: use of undefined value here causes illegal behavior
......@@ -2068,7 +2061,7 @@ const std = @import("std");
20682061// :96:17: error: use of undefined value here causes illegal behavior
20692062// :96:17: note: when computing vector element at index '0'
20702063// :96:17: error: use of undefined value here causes illegal behavior
2071// :96:17: note: when computing vector element at index '1'
2064// :96:17: note: when computing vector element at index '0'
20722065// :96:17: error: use of undefined value here causes illegal behavior
20732066// :96:17: note: when computing vector element at index '0'
20742067// :96:17: error: use of undefined value here causes illegal behavior
......@@ -2076,6 +2069,7 @@ const std = @import("std");
20762069// :96:17: error: use of undefined value here causes illegal behavior
20772070// :96:17: note: when computing vector element at index '0'
20782071// :96:17: error: use of undefined value here causes illegal behavior
2072// :96:17: note: when computing vector element at index '0'
20792073// :96:17: error: use of undefined value here causes illegal behavior
20802074// :96:17: note: when computing vector element at index '0'
20812075// :96:17: error: use of undefined value here causes illegal behavior
......@@ -2083,7 +2077,7 @@ const std = @import("std");
20832077// :96:17: error: use of undefined value here causes illegal behavior
20842078// :96:17: note: when computing vector element at index '0'
20852079// :96:17: error: use of undefined value here causes illegal behavior
2086// :96:17: note: when computing vector element at index '1'
2080// :96:17: note: when computing vector element at index '0'
20872081// :96:17: error: use of undefined value here causes illegal behavior
20882082// :96:17: note: when computing vector element at index '0'
20892083// :96:17: error: use of undefined value here causes illegal behavior
......@@ -2091,6 +2085,7 @@ const std = @import("std");
20912085// :96:17: error: use of undefined value here causes illegal behavior
20922086// :96:17: note: when computing vector element at index '0'
20932087// :96:17: error: use of undefined value here causes illegal behavior
2088// :96:17: note: when computing vector element at index '0'
20942089// :96:17: error: use of undefined value here causes illegal behavior
20952090// :96:17: note: when computing vector element at index '0'
20962091// :96:17: error: use of undefined value here causes illegal behavior
......@@ -2098,7 +2093,7 @@ const std = @import("std");
20982093// :96:17: error: use of undefined value here causes illegal behavior
20992094// :96:17: note: when computing vector element at index '0'
21002095// :96:17: error: use of undefined value here causes illegal behavior
2101// :96:17: note: when computing vector element at index '1'
2096// :96:17: note: when computing vector element at index '0'
21022097// :96:17: error: use of undefined value here causes illegal behavior
21032098// :96:17: note: when computing vector element at index '0'
21042099// :96:17: error: use of undefined value here causes illegal behavior
......@@ -2106,6 +2101,7 @@ const std = @import("std");
21062101// :96:17: error: use of undefined value here causes illegal behavior
21072102// :96:17: note: when computing vector element at index '0'
21082103// :96:17: error: use of undefined value here causes illegal behavior
2104// :96:17: note: when computing vector element at index '0'
21092105// :96:17: error: use of undefined value here causes illegal behavior
21102106// :96:17: note: when computing vector element at index '0'
21112107// :96:17: error: use of undefined value here causes illegal behavior
......@@ -2115,67 +2111,65 @@ const std = @import("std");
21152111// :96:17: error: use of undefined value here causes illegal behavior
21162112// :96:17: note: when computing vector element at index '1'
21172113// :96:17: error: use of undefined value here causes illegal behavior
2118// :96:17: note: when computing vector element at index '0'
2114// :96:17: note: when computing vector element at index '1'
21192115// :96:17: error: use of undefined value here causes illegal behavior
2120// :96:17: note: when computing vector element at index '0'
2116// :96:17: note: when computing vector element at index '1'
21212117// :96:17: error: use of undefined value here causes illegal behavior
2122// :96:17: note: when computing vector element at index '0'
2123// :96:22: error: use of undefined value here causes illegal behavior
2124// :96:22: error: use of undefined value here causes illegal behavior
2125// :96:22: note: when computing vector element at index '0'
2118// :96:17: note: when computing vector element at index '1'
2119// :96:17: error: use of undefined value here causes illegal behavior
2120// :96:17: note: when computing vector element at index '1'
2121// :96:17: error: use of undefined value here causes illegal behavior
2122// :96:17: note: when computing vector element at index '1'
21262123// :96:22: error: use of undefined value here causes illegal behavior
2127// :96:22: note: when computing vector element at index '0'
21282124// :96:22: error: use of undefined value here causes illegal behavior
2129// :96:22: note: when computing vector element at index '1'
21302125// :96:22: error: use of undefined value here causes illegal behavior
2131// :96:22: note: when computing vector element at index '0'
21322126// :96:22: error: use of undefined value here causes illegal behavior
2133// :96:22: note: when computing vector element at index '0'
21342127// :96:22: error: use of undefined value here causes illegal behavior
21352128// :96:22: error: use of undefined value here causes illegal behavior
2136// :96:22: note: when computing vector element at index '0'
21372129// :96:22: error: use of undefined value here causes illegal behavior
21382130// :96:22: note: when computing vector element at index '0'
21392131// :96:22: error: use of undefined value here causes illegal behavior
2140// :96:22: note: when computing vector element at index '1'
2141// :96:22: error: use of undefined value here causes illegal behavior
21422132// :96:22: note: when computing vector element at index '0'
21432133// :96:22: error: use of undefined value here causes illegal behavior
21442134// :96:22: note: when computing vector element at index '0'
21452135// :96:22: error: use of undefined value here causes illegal behavior
2136// :96:22: note: when computing vector element at index '0'
21462137// :96:22: error: use of undefined value here causes illegal behavior
21472138// :96:22: note: when computing vector element at index '0'
21482139// :96:22: error: use of undefined value here causes illegal behavior
21492140// :96:22: note: when computing vector element at index '0'
21502141// :96:22: error: use of undefined value here causes illegal behavior
2151// :96:22: note: when computing vector element at index '1'
2142// :96:22: note: when computing vector element at index '0'
21522143// :96:22: error: use of undefined value here causes illegal behavior
21532144// :96:22: note: when computing vector element at index '0'
21542145// :96:22: error: use of undefined value here causes illegal behavior
21552146// :96:22: note: when computing vector element at index '0'
21562147// :96:22: error: use of undefined value here causes illegal behavior
2148// :96:22: note: when computing vector element at index '0'
21572149// :96:22: error: use of undefined value here causes illegal behavior
21582150// :96:22: note: when computing vector element at index '0'
21592151// :96:22: error: use of undefined value here causes illegal behavior
21602152// :96:22: note: when computing vector element at index '0'
21612153// :96:22: error: use of undefined value here causes illegal behavior
2162// :96:22: note: when computing vector element at index '1'
2154// :96:22: note: when computing vector element at index '0'
21632155// :96:22: error: use of undefined value here causes illegal behavior
21642156// :96:22: note: when computing vector element at index '0'
21652157// :96:22: error: use of undefined value here causes illegal behavior
21662158// :96:22: note: when computing vector element at index '0'
21672159// :96:22: error: use of undefined value here causes illegal behavior
2160// :96:22: note: when computing vector element at index '0'
21682161// :96:22: error: use of undefined value here causes illegal behavior
21692162// :96:22: note: when computing vector element at index '0'
21702163// :96:22: error: use of undefined value here causes illegal behavior
21712164// :96:22: note: when computing vector element at index '0'
21722165// :96:22: error: use of undefined value here causes illegal behavior
2173// :96:22: note: when computing vector element at index '1'
2166// :96:22: note: when computing vector element at index '0'
21742167// :96:22: error: use of undefined value here causes illegal behavior
21752168// :96:22: note: when computing vector element at index '0'
21762169// :96:22: error: use of undefined value here causes illegal behavior
21772170// :96:22: note: when computing vector element at index '0'
21782171// :96:22: error: use of undefined value here causes illegal behavior
2172// :96:22: note: when computing vector element at index '0'
21792173// :96:22: error: use of undefined value here causes illegal behavior
21802174// :96:22: note: when computing vector element at index '0'
21812175// :96:22: error: use of undefined value here causes illegal behavior
......@@ -2183,40 +2177,39 @@ const std = @import("std");
21832177// :96:22: error: use of undefined value here causes illegal behavior
21842178// :96:22: note: when computing vector element at index '1'
21852179// :96:22: error: use of undefined value here causes illegal behavior
2186// :96:22: note: when computing vector element at index '0'
2180// :96:22: note: when computing vector element at index '1'
21872181// :96:22: error: use of undefined value here causes illegal behavior
2188// :96:22: note: when computing vector element at index '0'
2182// :96:22: note: when computing vector element at index '1'
2183// :96:22: error: use of undefined value here causes illegal behavior
2184// :96:22: note: when computing vector element at index '1'
2185// :96:22: error: use of undefined value here causes illegal behavior
2186// :96:22: note: when computing vector element at index '1'
2187// :96:22: error: use of undefined value here causes illegal behavior
2188// :96:22: note: when computing vector element at index '1'
21892189// :99:27: error: use of undefined value here causes illegal behavior
21902190// :99:27: error: use of undefined value here causes illegal behavior
2191// :99:27: note: when computing vector element at index '0'
21922191// :99:27: error: use of undefined value here causes illegal behavior
2193// :99:27: note: when computing vector element at index '0'
21942192// :99:27: error: use of undefined value here causes illegal behavior
2195// :99:27: note: when computing vector element at index '0'
21962193// :99:27: error: use of undefined value here causes illegal behavior
2197// :99:27: note: when computing vector element at index '1'
21982194// :99:27: error: use of undefined value here causes illegal behavior
2199// :99:27: note: when computing vector element at index '0'
22002195// :99:27: error: use of undefined value here causes illegal behavior
22012196// :99:27: note: when computing vector element at index '0'
22022197// :99:27: error: use of undefined value here causes illegal behavior
22032198// :99:27: note: when computing vector element at index '0'
22042199// :99:27: error: use of undefined value here causes illegal behavior
2205// :99:27: error: use of undefined value here causes illegal behavior
22062200// :99:27: note: when computing vector element at index '0'
22072201// :99:27: error: use of undefined value here causes illegal behavior
22082202// :99:27: note: when computing vector element at index '0'
22092203// :99:27: error: use of undefined value here causes illegal behavior
22102204// :99:27: note: when computing vector element at index '0'
22112205// :99:27: error: use of undefined value here causes illegal behavior
2212// :99:27: note: when computing vector element at index '1'
2213// :99:27: error: use of undefined value here causes illegal behavior
22142206// :99:27: note: when computing vector element at index '0'
22152207// :99:27: error: use of undefined value here causes illegal behavior
22162208// :99:27: note: when computing vector element at index '0'
22172209// :99:27: error: use of undefined value here causes illegal behavior
22182210// :99:27: note: when computing vector element at index '0'
22192211// :99:27: error: use of undefined value here causes illegal behavior
2212// :99:27: note: when computing vector element at index '0'
22202213// :99:27: error: use of undefined value here causes illegal behavior
22212214// :99:27: note: when computing vector element at index '0'
22222215// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2224,7 +2217,7 @@ const std = @import("std");
22242217// :99:27: error: use of undefined value here causes illegal behavior
22252218// :99:27: note: when computing vector element at index '0'
22262219// :99:27: error: use of undefined value here causes illegal behavior
2227// :99:27: note: when computing vector element at index '1'
2220// :99:27: note: when computing vector element at index '0'
22282221// :99:27: error: use of undefined value here causes illegal behavior
22292222// :99:27: note: when computing vector element at index '0'
22302223// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2232,6 +2225,7 @@ const std = @import("std");
22322225// :99:27: error: use of undefined value here causes illegal behavior
22332226// :99:27: note: when computing vector element at index '0'
22342227// :99:27: error: use of undefined value here causes illegal behavior
2228// :99:27: note: when computing vector element at index '0'
22352229// :99:27: error: use of undefined value here causes illegal behavior
22362230// :99:27: note: when computing vector element at index '0'
22372231// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2239,7 +2233,7 @@ const std = @import("std");
22392233// :99:27: error: use of undefined value here causes illegal behavior
22402234// :99:27: note: when computing vector element at index '0'
22412235// :99:27: error: use of undefined value here causes illegal behavior
2242// :99:27: note: when computing vector element at index '1'
2236// :99:27: note: when computing vector element at index '0'
22432237// :99:27: error: use of undefined value here causes illegal behavior
22442238// :99:27: note: when computing vector element at index '0'
22452239// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2247,6 +2241,7 @@ const std = @import("std");
22472241// :99:27: error: use of undefined value here causes illegal behavior
22482242// :99:27: note: when computing vector element at index '0'
22492243// :99:27: error: use of undefined value here causes illegal behavior
2244// :99:27: note: when computing vector element at index '0'
22502245// :99:27: error: use of undefined value here causes illegal behavior
22512246// :99:27: note: when computing vector element at index '0'
22522247// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2254,7 +2249,7 @@ const std = @import("std");
22542249// :99:27: error: use of undefined value here causes illegal behavior
22552250// :99:27: note: when computing vector element at index '0'
22562251// :99:27: error: use of undefined value here causes illegal behavior
2257// :99:27: note: when computing vector element at index '1'
2252// :99:27: note: when computing vector element at index '0'
22582253// :99:27: error: use of undefined value here causes illegal behavior
22592254// :99:27: note: when computing vector element at index '0'
22602255// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2262,6 +2257,7 @@ const std = @import("std");
22622257// :99:27: error: use of undefined value here causes illegal behavior
22632258// :99:27: note: when computing vector element at index '0'
22642259// :99:27: error: use of undefined value here causes illegal behavior
2260// :99:27: note: when computing vector element at index '0'
22652261// :99:27: error: use of undefined value here causes illegal behavior
22662262// :99:27: note: when computing vector element at index '0'
22672263// :99:27: error: use of undefined value here causes illegal behavior
......@@ -2271,77 +2267,81 @@ const std = @import("std");
22712267// :99:27: error: use of undefined value here causes illegal behavior
22722268// :99:27: note: when computing vector element at index '1'
22732269// :99:27: error: use of undefined value here causes illegal behavior
2274// :99:27: note: when computing vector element at index '0'
2270// :99:27: note: when computing vector element at index '1'
22752271// :99:27: error: use of undefined value here causes illegal behavior
2276// :99:27: note: when computing vector element at index '0'
2272// :99:27: note: when computing vector element at index '1'
22772273// :99:27: error: use of undefined value here causes illegal behavior
2278// :99:27: note: when computing vector element at index '0'
2274// :99:27: note: when computing vector element at index '1'
2275// :99:27: error: use of undefined value here causes illegal behavior
2276// :99:27: note: when computing vector element at index '1'
2277// :99:27: error: use of undefined value here causes illegal behavior
2278// :99:27: note: when computing vector element at index '1'
22792279// :99:30: error: use of undefined value here causes illegal behavior
22802280// :99:30: error: use of undefined value here causes illegal behavior
2281// :99:30: note: when computing vector element at index '0'
22822281// :99:30: error: use of undefined value here causes illegal behavior
2283// :99:30: note: when computing vector element at index '0'
22842282// :99:30: error: use of undefined value here causes illegal behavior
2285// :99:30: note: when computing vector element at index '1'
22862283// :99:30: error: use of undefined value here causes illegal behavior
2287// :99:30: note: when computing vector element at index '0'
22882284// :99:30: error: use of undefined value here causes illegal behavior
2289// :99:30: note: when computing vector element at index '0'
22902285// :99:30: error: use of undefined value here causes illegal behavior
2286// :99:30: note: when computing vector element at index '0'
22912287// :99:30: error: use of undefined value here causes illegal behavior
22922288// :99:30: note: when computing vector element at index '0'
22932289// :99:30: error: use of undefined value here causes illegal behavior
22942290// :99:30: note: when computing vector element at index '0'
22952291// :99:30: error: use of undefined value here causes illegal behavior
2296// :99:30: note: when computing vector element at index '1'
2292// :99:30: note: when computing vector element at index '0'
22972293// :99:30: error: use of undefined value here causes illegal behavior
22982294// :99:30: note: when computing vector element at index '0'
22992295// :99:30: error: use of undefined value here causes illegal behavior
23002296// :99:30: note: when computing vector element at index '0'
23012297// :99:30: error: use of undefined value here causes illegal behavior
2298// :99:30: note: when computing vector element at index '0'
23022299// :99:30: error: use of undefined value here causes illegal behavior
23032300// :99:30: note: when computing vector element at index '0'
23042301// :99:30: error: use of undefined value here causes illegal behavior
23052302// :99:30: note: when computing vector element at index '0'
23062303// :99:30: error: use of undefined value here causes illegal behavior
2307// :99:30: note: when computing vector element at index '1'
2304// :99:30: note: when computing vector element at index '0'
23082305// :99:30: error: use of undefined value here causes illegal behavior
23092306// :99:30: note: when computing vector element at index '0'
23102307// :99:30: error: use of undefined value here causes illegal behavior
23112308// :99:30: note: when computing vector element at index '0'
23122309// :99:30: error: use of undefined value here causes illegal behavior
2310// :99:30: note: when computing vector element at index '0'
23132311// :99:30: error: use of undefined value here causes illegal behavior
23142312// :99:30: note: when computing vector element at index '0'
23152313// :99:30: error: use of undefined value here causes illegal behavior
23162314// :99:30: note: when computing vector element at index '0'
23172315// :99:30: error: use of undefined value here causes illegal behavior
2318// :99:30: note: when computing vector element at index '1'
2316// :99:30: note: when computing vector element at index '0'
23192317// :99:30: error: use of undefined value here causes illegal behavior
23202318// :99:30: note: when computing vector element at index '0'
23212319// :99:30: error: use of undefined value here causes illegal behavior
23222320// :99:30: note: when computing vector element at index '0'
23232321// :99:30: error: use of undefined value here causes illegal behavior
2322// :99:30: note: when computing vector element at index '0'
23242323// :99:30: error: use of undefined value here causes illegal behavior
23252324// :99:30: note: when computing vector element at index '0'
23262325// :99:30: error: use of undefined value here causes illegal behavior
23272326// :99:30: note: when computing vector element at index '0'
23282327// :99:30: error: use of undefined value here causes illegal behavior
2329// :99:30: note: when computing vector element at index '1'
2328// :99:30: note: when computing vector element at index '0'
23302329// :99:30: error: use of undefined value here causes illegal behavior
23312330// :99:30: note: when computing vector element at index '0'
23322331// :99:30: error: use of undefined value here causes illegal behavior
23332332// :99:30: note: when computing vector element at index '0'
23342333// :99:30: error: use of undefined value here causes illegal behavior
2334// :99:30: note: when computing vector element at index '1'
23352335// :99:30: error: use of undefined value here causes illegal behavior
2336// :99:30: note: when computing vector element at index '0'
2336// :99:30: note: when computing vector element at index '1'
23372337// :99:30: error: use of undefined value here causes illegal behavior
2338// :99:30: note: when computing vector element at index '0'
2338// :99:30: note: when computing vector element at index '1'
23392339// :99:30: error: use of undefined value here causes illegal behavior
23402340// :99:30: note: when computing vector element at index '1'
23412341// :99:30: error: use of undefined value here causes illegal behavior
2342// :99:30: note: when computing vector element at index '0'
2342// :99:30: note: when computing vector element at index '1'
23432343// :99:30: error: use of undefined value here causes illegal behavior
2344// :99:30: note: when computing vector element at index '0'
2344// :99:30: note: when computing vector element at index '1'
23452345// :104:22: error: use of undefined value here causes illegal behavior
23462346// :104:22: error: use of undefined value here causes illegal behavior
23472347// :104:22: error: use of undefined value here causes illegal behavior
......@@ -2349,21 +2349,13 @@ const std = @import("std");
23492349// :104:22: error: use of undefined value here causes illegal behavior
23502350// :104:22: error: use of undefined value here causes illegal behavior
23512351// :104:22: error: use of undefined value here causes illegal behavior
2352// :104:22: note: when computing vector element at index '1'
23532352// :104:22: error: use of undefined value here causes illegal behavior
2354// :104:22: note: when computing vector element at index '1'
23552353// :104:22: error: use of undefined value here causes illegal behavior
2356// :104:22: note: when computing vector element at index '1'
23572354// :104:22: error: use of undefined value here causes illegal behavior
2358// :104:22: note: when computing vector element at index '1'
23592355// :104:22: error: use of undefined value here causes illegal behavior
2360// :104:22: note: when computing vector element at index '0'
23612356// :104:22: error: use of undefined value here causes illegal behavior
2362// :104:22: note: when computing vector element at index '0'
23632357// :104:22: error: use of undefined value here causes illegal behavior
2364// :104:22: note: when computing vector element at index '0'
23652358// :104:22: error: use of undefined value here causes illegal behavior
2366// :104:22: note: when computing vector element at index '0'
23672359// :104:22: error: use of undefined value here causes illegal behavior
23682360// :104:22: error: use of undefined value here causes illegal behavior
23692361// :104:22: error: use of undefined value here causes illegal behavior
......@@ -2371,21 +2363,13 @@ const std = @import("std");
23712363// :104:22: error: use of undefined value here causes illegal behavior
23722364// :104:22: error: use of undefined value here causes illegal behavior
23732365// :104:22: error: use of undefined value here causes illegal behavior
2374// :104:22: note: when computing vector element at index '1'
23752366// :104:22: error: use of undefined value here causes illegal behavior
2376// :104:22: note: when computing vector element at index '1'
23772367// :104:22: error: use of undefined value here causes illegal behavior
2378// :104:22: note: when computing vector element at index '1'
23792368// :104:22: error: use of undefined value here causes illegal behavior
2380// :104:22: note: when computing vector element at index '1'
23812369// :104:22: error: use of undefined value here causes illegal behavior
2382// :104:22: note: when computing vector element at index '0'
23832370// :104:22: error: use of undefined value here causes illegal behavior
2384// :104:22: note: when computing vector element at index '0'
23852371// :104:22: error: use of undefined value here causes illegal behavior
2386// :104:22: note: when computing vector element at index '0'
23872372// :104:22: error: use of undefined value here causes illegal behavior
2388// :104:22: note: when computing vector element at index '0'
23892373// :104:22: error: use of undefined value here causes illegal behavior
23902374// :104:22: error: use of undefined value here causes illegal behavior
23912375// :104:22: error: use of undefined value here causes illegal behavior
......@@ -2393,13 +2377,11 @@ const std = @import("std");
23932377// :104:22: error: use of undefined value here causes illegal behavior
23942378// :104:22: error: use of undefined value here causes illegal behavior
23952379// :104:22: error: use of undefined value here causes illegal behavior
2396// :104:22: note: when computing vector element at index '1'
23972380// :104:22: error: use of undefined value here causes illegal behavior
2398// :104:22: note: when computing vector element at index '1'
23992381// :104:22: error: use of undefined value here causes illegal behavior
2400// :104:22: note: when computing vector element at index '1'
2382// :104:22: note: when computing vector element at index '0'
24012383// :104:22: error: use of undefined value here causes illegal behavior
2402// :104:22: note: when computing vector element at index '1'
2384// :104:22: note: when computing vector element at index '0'
24032385// :104:22: error: use of undefined value here causes illegal behavior
24042386// :104:22: note: when computing vector element at index '0'
24052387// :104:22: error: use of undefined value here causes illegal behavior
......@@ -2409,19 +2391,25 @@ const std = @import("std");
24092391// :104:22: error: use of undefined value here causes illegal behavior
24102392// :104:22: note: when computing vector element at index '0'
24112393// :104:22: error: use of undefined value here causes illegal behavior
2394// :104:22: note: when computing vector element at index '0'
24122395// :104:22: error: use of undefined value here causes illegal behavior
2396// :104:22: note: when computing vector element at index '0'
24132397// :104:22: error: use of undefined value here causes illegal behavior
2398// :104:22: note: when computing vector element at index '0'
24142399// :104:22: error: use of undefined value here causes illegal behavior
2400// :104:22: note: when computing vector element at index '0'
24152401// :104:22: error: use of undefined value here causes illegal behavior
2402// :104:22: note: when computing vector element at index '0'
24162403// :104:22: error: use of undefined value here causes illegal behavior
2404// :104:22: note: when computing vector element at index '0'
24172405// :104:22: error: use of undefined value here causes illegal behavior
2418// :104:22: note: when computing vector element at index '1'
2406// :104:22: note: when computing vector element at index '0'
24192407// :104:22: error: use of undefined value here causes illegal behavior
2420// :104:22: note: when computing vector element at index '1'
2408// :104:22: note: when computing vector element at index '0'
24212409// :104:22: error: use of undefined value here causes illegal behavior
2422// :104:22: note: when computing vector element at index '1'
2410// :104:22: note: when computing vector element at index '0'
24232411// :104:22: error: use of undefined value here causes illegal behavior
2424// :104:22: note: when computing vector element at index '1'
2412// :104:22: note: when computing vector element at index '0'
24252413// :104:22: error: use of undefined value here causes illegal behavior
24262414// :104:22: note: when computing vector element at index '0'
24272415// :104:22: error: use of undefined value here causes illegal behavior
......@@ -2431,11 +2419,17 @@ const std = @import("std");
24312419// :104:22: error: use of undefined value here causes illegal behavior
24322420// :104:22: note: when computing vector element at index '0'
24332421// :104:22: error: use of undefined value here causes illegal behavior
2422// :104:22: note: when computing vector element at index '0'
24342423// :104:22: error: use of undefined value here causes illegal behavior
2424// :104:22: note: when computing vector element at index '0'
24352425// :104:22: error: use of undefined value here causes illegal behavior
2426// :104:22: note: when computing vector element at index '0'
24362427// :104:22: error: use of undefined value here causes illegal behavior
2428// :104:22: note: when computing vector element at index '0'
24372429// :104:22: error: use of undefined value here causes illegal behavior
2430// :104:22: note: when computing vector element at index '1'
24382431// :104:22: error: use of undefined value here causes illegal behavior
2432// :104:22: note: when computing vector element at index '1'
24392433// :104:22: error: use of undefined value here causes illegal behavior
24402434// :104:22: note: when computing vector element at index '1'
24412435// :104:22: error: use of undefined value here causes illegal behavior
......@@ -2445,19 +2439,25 @@ const std = @import("std");
24452439// :104:22: error: use of undefined value here causes illegal behavior
24462440// :104:22: note: when computing vector element at index '1'
24472441// :104:22: error: use of undefined value here causes illegal behavior
2448// :104:22: note: when computing vector element at index '0'
2442// :104:22: note: when computing vector element at index '1'
24492443// :104:22: error: use of undefined value here causes illegal behavior
2450// :104:22: note: when computing vector element at index '0'
2444// :104:22: note: when computing vector element at index '1'
24512445// :104:22: error: use of undefined value here causes illegal behavior
2452// :104:22: note: when computing vector element at index '0'
2446// :104:22: note: when computing vector element at index '1'
24532447// :104:22: error: use of undefined value here causes illegal behavior
2454// :104:22: note: when computing vector element at index '0'
2448// :104:22: note: when computing vector element at index '1'
24552449// :104:22: error: use of undefined value here causes illegal behavior
2450// :104:22: note: when computing vector element at index '1'
24562451// :104:22: error: use of undefined value here causes illegal behavior
2452// :104:22: note: when computing vector element at index '1'
24572453// :104:22: error: use of undefined value here causes illegal behavior
2454// :104:22: note: when computing vector element at index '1'
24582455// :104:22: error: use of undefined value here causes illegal behavior
2456// :104:22: note: when computing vector element at index '1'
24592457// :104:22: error: use of undefined value here causes illegal behavior
2458// :104:22: note: when computing vector element at index '1'
24602459// :104:22: error: use of undefined value here causes illegal behavior
2460// :104:22: note: when computing vector element at index '1'
24612461// :104:22: error: use of undefined value here causes illegal behavior
24622462// :104:22: note: when computing vector element at index '1'
24632463// :104:22: error: use of undefined value here causes illegal behavior
......@@ -2467,13 +2467,13 @@ const std = @import("std");
24672467// :104:22: error: use of undefined value here causes illegal behavior
24682468// :104:22: note: when computing vector element at index '1'
24692469// :104:22: error: use of undefined value here causes illegal behavior
2470// :104:22: note: when computing vector element at index '0'
2470// :104:22: note: when computing vector element at index '1'
24712471// :104:22: error: use of undefined value here causes illegal behavior
2472// :104:22: note: when computing vector element at index '0'
2472// :104:22: note: when computing vector element at index '1'
24732473// :104:22: error: use of undefined value here causes illegal behavior
2474// :104:22: note: when computing vector element at index '0'
2474// :104:22: note: when computing vector element at index '1'
24752475// :104:22: error: use of undefined value here causes illegal behavior
2476// :104:22: note: when computing vector element at index '0'
2476// :104:22: note: when computing vector element at index '1'
24772477// :107:30: error: use of undefined value here causes illegal behavior
24782478// :107:30: error: use of undefined value here causes illegal behavior
24792479// :107:30: error: use of undefined value here causes illegal behavior
......@@ -2481,21 +2481,13 @@ const std = @import("std");
24812481// :107:30: error: use of undefined value here causes illegal behavior
24822482// :107:30: error: use of undefined value here causes illegal behavior
24832483// :107:30: error: use of undefined value here causes illegal behavior
2484// :107:30: note: when computing vector element at index '1'
24852484// :107:30: error: use of undefined value here causes illegal behavior
2486// :107:30: note: when computing vector element at index '1'
24872485// :107:30: error: use of undefined value here causes illegal behavior
2488// :107:30: note: when computing vector element at index '1'
24892486// :107:30: error: use of undefined value here causes illegal behavior
2490// :107:30: note: when computing vector element at index '1'
24912487// :107:30: error: use of undefined value here causes illegal behavior
2492// :107:30: note: when computing vector element at index '0'
24932488// :107:30: error: use of undefined value here causes illegal behavior
2494// :107:30: note: when computing vector element at index '0'
24952489// :107:30: error: use of undefined value here causes illegal behavior
2496// :107:30: note: when computing vector element at index '0'
24972490// :107:30: error: use of undefined value here causes illegal behavior
2498// :107:30: note: when computing vector element at index '0'
24992491// :107:30: error: use of undefined value here causes illegal behavior
25002492// :107:30: error: use of undefined value here causes illegal behavior
25012493// :107:30: error: use of undefined value here causes illegal behavior
......@@ -2503,21 +2495,13 @@ const std = @import("std");
25032495// :107:30: error: use of undefined value here causes illegal behavior
25042496// :107:30: error: use of undefined value here causes illegal behavior
25052497// :107:30: error: use of undefined value here causes illegal behavior
2506// :107:30: note: when computing vector element at index '1'
25072498// :107:30: error: use of undefined value here causes illegal behavior
2508// :107:30: note: when computing vector element at index '1'
25092499// :107:30: error: use of undefined value here causes illegal behavior
2510// :107:30: note: when computing vector element at index '1'
25112500// :107:30: error: use of undefined value here causes illegal behavior
2512// :107:30: note: when computing vector element at index '1'
25132501// :107:30: error: use of undefined value here causes illegal behavior
2514// :107:30: note: when computing vector element at index '0'
25152502// :107:30: error: use of undefined value here causes illegal behavior
2516// :107:30: note: when computing vector element at index '0'
25172503// :107:30: error: use of undefined value here causes illegal behavior
2518// :107:30: note: when computing vector element at index '0'
25192504// :107:30: error: use of undefined value here causes illegal behavior
2520// :107:30: note: when computing vector element at index '0'
25212505// :107:30: error: use of undefined value here causes illegal behavior
25222506// :107:30: error: use of undefined value here causes illegal behavior
25232507// :107:30: error: use of undefined value here causes illegal behavior
......@@ -2525,13 +2509,11 @@ const std = @import("std");
25252509// :107:30: error: use of undefined value here causes illegal behavior
25262510// :107:30: error: use of undefined value here causes illegal behavior
25272511// :107:30: error: use of undefined value here causes illegal behavior
2528// :107:30: note: when computing vector element at index '1'
25292512// :107:30: error: use of undefined value here causes illegal behavior
2530// :107:30: note: when computing vector element at index '1'
25312513// :107:30: error: use of undefined value here causes illegal behavior
2532// :107:30: note: when computing vector element at index '1'
2514// :107:30: note: when computing vector element at index '0'
25332515// :107:30: error: use of undefined value here causes illegal behavior
2534// :107:30: note: when computing vector element at index '1'
2516// :107:30: note: when computing vector element at index '0'
25352517// :107:30: error: use of undefined value here causes illegal behavior
25362518// :107:30: note: when computing vector element at index '0'
25372519// :107:30: error: use of undefined value here causes illegal behavior
......@@ -2541,19 +2523,25 @@ const std = @import("std");
25412523// :107:30: error: use of undefined value here causes illegal behavior
25422524// :107:30: note: when computing vector element at index '0'
25432525// :107:30: error: use of undefined value here causes illegal behavior
2526// :107:30: note: when computing vector element at index '0'
25442527// :107:30: error: use of undefined value here causes illegal behavior
2528// :107:30: note: when computing vector element at index '0'
25452529// :107:30: error: use of undefined value here causes illegal behavior
2530// :107:30: note: when computing vector element at index '0'
25462531// :107:30: error: use of undefined value here causes illegal behavior
2532// :107:30: note: when computing vector element at index '0'
25472533// :107:30: error: use of undefined value here causes illegal behavior
2534// :107:30: note: when computing vector element at index '0'
25482535// :107:30: error: use of undefined value here causes illegal behavior
2536// :107:30: note: when computing vector element at index '0'
25492537// :107:30: error: use of undefined value here causes illegal behavior
2550// :107:30: note: when computing vector element at index '1'
2538// :107:30: note: when computing vector element at index '0'
25512539// :107:30: error: use of undefined value here causes illegal behavior
2552// :107:30: note: when computing vector element at index '1'
2540// :107:30: note: when computing vector element at index '0'
25532541// :107:30: error: use of undefined value here causes illegal behavior
2554// :107:30: note: when computing vector element at index '1'
2542// :107:30: note: when computing vector element at index '0'
25552543// :107:30: error: use of undefined value here causes illegal behavior
2556// :107:30: note: when computing vector element at index '1'
2544// :107:30: note: when computing vector element at index '0'
25572545// :107:30: error: use of undefined value here causes illegal behavior
25582546// :107:30: note: when computing vector element at index '0'
25592547// :107:30: error: use of undefined value here causes illegal behavior
......@@ -2563,11 +2551,17 @@ const std = @import("std");
25632551// :107:30: error: use of undefined value here causes illegal behavior
25642552// :107:30: note: when computing vector element at index '0'
25652553// :107:30: error: use of undefined value here causes illegal behavior
2554// :107:30: note: when computing vector element at index '0'
25662555// :107:30: error: use of undefined value here causes illegal behavior
2556// :107:30: note: when computing vector element at index '0'
25672557// :107:30: error: use of undefined value here causes illegal behavior
2558// :107:30: note: when computing vector element at index '0'
25682559// :107:30: error: use of undefined value here causes illegal behavior
2560// :107:30: note: when computing vector element at index '0'
25692561// :107:30: error: use of undefined value here causes illegal behavior
2562// :107:30: note: when computing vector element at index '1'
25702563// :107:30: error: use of undefined value here causes illegal behavior
2564// :107:30: note: when computing vector element at index '1'
25712565// :107:30: error: use of undefined value here causes illegal behavior
25722566// :107:30: note: when computing vector element at index '1'
25732567// :107:30: error: use of undefined value here causes illegal behavior
......@@ -2577,19 +2571,25 @@ const std = @import("std");
25772571// :107:30: error: use of undefined value here causes illegal behavior
25782572// :107:30: note: when computing vector element at index '1'
25792573// :107:30: error: use of undefined value here causes illegal behavior
2580// :107:30: note: when computing vector element at index '0'
2574// :107:30: note: when computing vector element at index '1'
25812575// :107:30: error: use of undefined value here causes illegal behavior
2582// :107:30: note: when computing vector element at index '0'
2576// :107:30: note: when computing vector element at index '1'
25832577// :107:30: error: use of undefined value here causes illegal behavior
2584// :107:30: note: when computing vector element at index '0'
2578// :107:30: note: when computing vector element at index '1'
25852579// :107:30: error: use of undefined value here causes illegal behavior
2586// :107:30: note: when computing vector element at index '0'
2580// :107:30: note: when computing vector element at index '1'
25872581// :107:30: error: use of undefined value here causes illegal behavior
2582// :107:30: note: when computing vector element at index '1'
25882583// :107:30: error: use of undefined value here causes illegal behavior
2584// :107:30: note: when computing vector element at index '1'
25892585// :107:30: error: use of undefined value here causes illegal behavior
2586// :107:30: note: when computing vector element at index '1'
25902587// :107:30: error: use of undefined value here causes illegal behavior
2588// :107:30: note: when computing vector element at index '1'
25912589// :107:30: error: use of undefined value here causes illegal behavior
2590// :107:30: note: when computing vector element at index '1'
25922591// :107:30: error: use of undefined value here causes illegal behavior
2592// :107:30: note: when computing vector element at index '1'
25932593// :107:30: error: use of undefined value here causes illegal behavior
25942594// :107:30: note: when computing vector element at index '1'
25952595// :107:30: error: use of undefined value here causes illegal behavior
......@@ -2599,13 +2599,13 @@ const std = @import("std");
25992599// :107:30: error: use of undefined value here causes illegal behavior
26002600// :107:30: note: when computing vector element at index '1'
26012601// :107:30: error: use of undefined value here causes illegal behavior
2602// :107:30: note: when computing vector element at index '0'
2602// :107:30: note: when computing vector element at index '1'
26032603// :107:30: error: use of undefined value here causes illegal behavior
2604// :107:30: note: when computing vector element at index '0'
2604// :107:30: note: when computing vector element at index '1'
26052605// :107:30: error: use of undefined value here causes illegal behavior
2606// :107:30: note: when computing vector element at index '0'
2606// :107:30: note: when computing vector element at index '1'
26072607// :107:30: error: use of undefined value here causes illegal behavior
2608// :107:30: note: when computing vector element at index '0'
2608// :107:30: note: when computing vector element at index '1'
26092609// :110:37: error: use of undefined value here causes illegal behavior
26102610// :110:37: error: use of undefined value here causes illegal behavior
26112611// :110:37: error: use of undefined value here causes illegal behavior
......@@ -2613,21 +2613,13 @@ const std = @import("std");
26132613// :110:37: error: use of undefined value here causes illegal behavior
26142614// :110:37: error: use of undefined value here causes illegal behavior
26152615// :110:37: error: use of undefined value here causes illegal behavior
2616// :110:37: note: when computing vector element at index '1'
26172616// :110:37: error: use of undefined value here causes illegal behavior
2618// :110:37: note: when computing vector element at index '1'
26192617// :110:37: error: use of undefined value here causes illegal behavior
2620// :110:37: note: when computing vector element at index '1'
26212618// :110:37: error: use of undefined value here causes illegal behavior
2622// :110:37: note: when computing vector element at index '1'
26232619// :110:37: error: use of undefined value here causes illegal behavior
2624// :110:37: note: when computing vector element at index '0'
26252620// :110:37: error: use of undefined value here causes illegal behavior
2626// :110:37: note: when computing vector element at index '0'
26272621// :110:37: error: use of undefined value here causes illegal behavior
2628// :110:37: note: when computing vector element at index '0'
26292622// :110:37: error: use of undefined value here causes illegal behavior
2630// :110:37: note: when computing vector element at index '0'
26312623// :110:37: error: use of undefined value here causes illegal behavior
26322624// :110:37: error: use of undefined value here causes illegal behavior
26332625// :110:37: error: use of undefined value here causes illegal behavior
......@@ -2635,21 +2627,13 @@ const std = @import("std");
26352627// :110:37: error: use of undefined value here causes illegal behavior
26362628// :110:37: error: use of undefined value here causes illegal behavior
26372629// :110:37: error: use of undefined value here causes illegal behavior
2638// :110:37: note: when computing vector element at index '1'
26392630// :110:37: error: use of undefined value here causes illegal behavior
2640// :110:37: note: when computing vector element at index '1'
26412631// :110:37: error: use of undefined value here causes illegal behavior
2642// :110:37: note: when computing vector element at index '1'
26432632// :110:37: error: use of undefined value here causes illegal behavior
2644// :110:37: note: when computing vector element at index '1'
26452633// :110:37: error: use of undefined value here causes illegal behavior
2646// :110:37: note: when computing vector element at index '0'
26472634// :110:37: error: use of undefined value here causes illegal behavior
2648// :110:37: note: when computing vector element at index '0'
26492635// :110:37: error: use of undefined value here causes illegal behavior
2650// :110:37: note: when computing vector element at index '0'
26512636// :110:37: error: use of undefined value here causes illegal behavior
2652// :110:37: note: when computing vector element at index '0'
26532637// :110:37: error: use of undefined value here causes illegal behavior
26542638// :110:37: error: use of undefined value here causes illegal behavior
26552639// :110:37: error: use of undefined value here causes illegal behavior
......@@ -2657,13 +2641,11 @@ const std = @import("std");
26572641// :110:37: error: use of undefined value here causes illegal behavior
26582642// :110:37: error: use of undefined value here causes illegal behavior
26592643// :110:37: error: use of undefined value here causes illegal behavior
2660// :110:37: note: when computing vector element at index '1'
26612644// :110:37: error: use of undefined value here causes illegal behavior
2662// :110:37: note: when computing vector element at index '1'
26632645// :110:37: error: use of undefined value here causes illegal behavior
2664// :110:37: note: when computing vector element at index '1'
2646// :110:37: note: when computing vector element at index '0'
26652647// :110:37: error: use of undefined value here causes illegal behavior
2666// :110:37: note: when computing vector element at index '1'
2648// :110:37: note: when computing vector element at index '0'
26672649// :110:37: error: use of undefined value here causes illegal behavior
26682650// :110:37: note: when computing vector element at index '0'
26692651// :110:37: error: use of undefined value here causes illegal behavior
......@@ -2673,19 +2655,25 @@ const std = @import("std");
26732655// :110:37: error: use of undefined value here causes illegal behavior
26742656// :110:37: note: when computing vector element at index '0'
26752657// :110:37: error: use of undefined value here causes illegal behavior
2658// :110:37: note: when computing vector element at index '0'
26762659// :110:37: error: use of undefined value here causes illegal behavior
2660// :110:37: note: when computing vector element at index '0'
26772661// :110:37: error: use of undefined value here causes illegal behavior
2662// :110:37: note: when computing vector element at index '0'
26782663// :110:37: error: use of undefined value here causes illegal behavior
2664// :110:37: note: when computing vector element at index '0'
26792665// :110:37: error: use of undefined value here causes illegal behavior
2666// :110:37: note: when computing vector element at index '0'
26802667// :110:37: error: use of undefined value here causes illegal behavior
2668// :110:37: note: when computing vector element at index '0'
26812669// :110:37: error: use of undefined value here causes illegal behavior
2682// :110:37: note: when computing vector element at index '1'
2670// :110:37: note: when computing vector element at index '0'
26832671// :110:37: error: use of undefined value here causes illegal behavior
2684// :110:37: note: when computing vector element at index '1'
2672// :110:37: note: when computing vector element at index '0'
26852673// :110:37: error: use of undefined value here causes illegal behavior
2686// :110:37: note: when computing vector element at index '1'
2674// :110:37: note: when computing vector element at index '0'
26872675// :110:37: error: use of undefined value here causes illegal behavior
2688// :110:37: note: when computing vector element at index '1'
2676// :110:37: note: when computing vector element at index '0'
26892677// :110:37: error: use of undefined value here causes illegal behavior
26902678// :110:37: note: when computing vector element at index '0'
26912679// :110:37: error: use of undefined value here causes illegal behavior
......@@ -2695,11 +2683,17 @@ const std = @import("std");
26952683// :110:37: error: use of undefined value here causes illegal behavior
26962684// :110:37: note: when computing vector element at index '0'
26972685// :110:37: error: use of undefined value here causes illegal behavior
2686// :110:37: note: when computing vector element at index '0'
26982687// :110:37: error: use of undefined value here causes illegal behavior
2688// :110:37: note: when computing vector element at index '0'
26992689// :110:37: error: use of undefined value here causes illegal behavior
2690// :110:37: note: when computing vector element at index '0'
27002691// :110:37: error: use of undefined value here causes illegal behavior
2692// :110:37: note: when computing vector element at index '0'
27012693// :110:37: error: use of undefined value here causes illegal behavior
2694// :110:37: note: when computing vector element at index '1'
27022695// :110:37: error: use of undefined value here causes illegal behavior
2696// :110:37: note: when computing vector element at index '1'
27032697// :110:37: error: use of undefined value here causes illegal behavior
27042698// :110:37: note: when computing vector element at index '1'
27052699// :110:37: error: use of undefined value here causes illegal behavior
......@@ -2709,19 +2703,25 @@ const std = @import("std");
27092703// :110:37: error: use of undefined value here causes illegal behavior
27102704// :110:37: note: when computing vector element at index '1'
27112705// :110:37: error: use of undefined value here causes illegal behavior
2712// :110:37: note: when computing vector element at index '0'
2706// :110:37: note: when computing vector element at index '1'
27132707// :110:37: error: use of undefined value here causes illegal behavior
2714// :110:37: note: when computing vector element at index '0'
2708// :110:37: note: when computing vector element at index '1'
27152709// :110:37: error: use of undefined value here causes illegal behavior
2716// :110:37: note: when computing vector element at index '0'
2710// :110:37: note: when computing vector element at index '1'
27172711// :110:37: error: use of undefined value here causes illegal behavior
2718// :110:37: note: when computing vector element at index '0'
2712// :110:37: note: when computing vector element at index '1'
27192713// :110:37: error: use of undefined value here causes illegal behavior
2714// :110:37: note: when computing vector element at index '1'
27202715// :110:37: error: use of undefined value here causes illegal behavior
2716// :110:37: note: when computing vector element at index '1'
27212717// :110:37: error: use of undefined value here causes illegal behavior
2718// :110:37: note: when computing vector element at index '1'
27222719// :110:37: error: use of undefined value here causes illegal behavior
2720// :110:37: note: when computing vector element at index '1'
27232721// :110:37: error: use of undefined value here causes illegal behavior
2722// :110:37: note: when computing vector element at index '1'
27242723// :110:37: error: use of undefined value here causes illegal behavior
2724// :110:37: note: when computing vector element at index '1'
27252725// :110:37: error: use of undefined value here causes illegal behavior
27262726// :110:37: note: when computing vector element at index '1'
27272727// :110:37: error: use of undefined value here causes illegal behavior
......@@ -2731,13 +2731,13 @@ const std = @import("std");
27312731// :110:37: error: use of undefined value here causes illegal behavior
27322732// :110:37: note: when computing vector element at index '1'
27332733// :110:37: error: use of undefined value here causes illegal behavior
2734// :110:37: note: when computing vector element at index '0'
2734// :110:37: note: when computing vector element at index '1'
27352735// :110:37: error: use of undefined value here causes illegal behavior
2736// :110:37: note: when computing vector element at index '0'
2736// :110:37: note: when computing vector element at index '1'
27372737// :110:37: error: use of undefined value here causes illegal behavior
2738// :110:37: note: when computing vector element at index '0'
2738// :110:37: note: when computing vector element at index '1'
27392739// :110:37: error: use of undefined value here causes illegal behavior
2740// :110:37: note: when computing vector element at index '0'
2740// :110:37: note: when computing vector element at index '1'
27412741// :113:22: error: use of undefined value here causes illegal behavior
27422742// :113:22: error: use of undefined value here causes illegal behavior
27432743// :113:22: error: use of undefined value here causes illegal behavior
......@@ -2745,21 +2745,13 @@ const std = @import("std");
27452745// :113:22: error: use of undefined value here causes illegal behavior
27462746// :113:22: error: use of undefined value here causes illegal behavior
27472747// :113:22: error: use of undefined value here causes illegal behavior
2748// :113:22: note: when computing vector element at index '1'
27492748// :113:22: error: use of undefined value here causes illegal behavior
2750// :113:22: note: when computing vector element at index '1'
27512749// :113:22: error: use of undefined value here causes illegal behavior
2752// :113:22: note: when computing vector element at index '1'
27532750// :113:22: error: use of undefined value here causes illegal behavior
2754// :113:22: note: when computing vector element at index '1'
27552751// :113:22: error: use of undefined value here causes illegal behavior
2756// :113:22: note: when computing vector element at index '0'
27572752// :113:22: error: use of undefined value here causes illegal behavior
2758// :113:22: note: when computing vector element at index '0'
27592753// :113:22: error: use of undefined value here causes illegal behavior
2760// :113:22: note: when computing vector element at index '0'
27612754// :113:22: error: use of undefined value here causes illegal behavior
2762// :113:22: note: when computing vector element at index '0'
27632755// :113:22: error: use of undefined value here causes illegal behavior
27642756// :113:22: error: use of undefined value here causes illegal behavior
27652757// :113:22: error: use of undefined value here causes illegal behavior
......@@ -2767,21 +2759,13 @@ const std = @import("std");
27672759// :113:22: error: use of undefined value here causes illegal behavior
27682760// :113:22: error: use of undefined value here causes illegal behavior
27692761// :113:22: error: use of undefined value here causes illegal behavior
2770// :113:22: note: when computing vector element at index '1'
27712762// :113:22: error: use of undefined value here causes illegal behavior
2772// :113:22: note: when computing vector element at index '1'
27732763// :113:22: error: use of undefined value here causes illegal behavior
2774// :113:22: note: when computing vector element at index '1'
27752764// :113:22: error: use of undefined value here causes illegal behavior
2776// :113:22: note: when computing vector element at index '1'
27772765// :113:22: error: use of undefined value here causes illegal behavior
2778// :113:22: note: when computing vector element at index '0'
27792766// :113:22: error: use of undefined value here causes illegal behavior
2780// :113:22: note: when computing vector element at index '0'
27812767// :113:22: error: use of undefined value here causes illegal behavior
2782// :113:22: note: when computing vector element at index '0'
27832768// :113:22: error: use of undefined value here causes illegal behavior
2784// :113:22: note: when computing vector element at index '0'
27852769// :113:22: error: use of undefined value here causes illegal behavior
27862770// :113:22: error: use of undefined value here causes illegal behavior
27872771// :113:22: error: use of undefined value here causes illegal behavior
......@@ -2789,13 +2773,11 @@ const std = @import("std");
27892773// :113:22: error: use of undefined value here causes illegal behavior
27902774// :113:22: error: use of undefined value here causes illegal behavior
27912775// :113:22: error: use of undefined value here causes illegal behavior
2792// :113:22: note: when computing vector element at index '1'
27932776// :113:22: error: use of undefined value here causes illegal behavior
2794// :113:22: note: when computing vector element at index '1'
27952777// :113:22: error: use of undefined value here causes illegal behavior
2796// :113:22: note: when computing vector element at index '1'
2778// :113:22: note: when computing vector element at index '0'
27972779// :113:22: error: use of undefined value here causes illegal behavior
2798// :113:22: note: when computing vector element at index '1'
2780// :113:22: note: when computing vector element at index '0'
27992781// :113:22: error: use of undefined value here causes illegal behavior
28002782// :113:22: note: when computing vector element at index '0'
28012783// :113:22: error: use of undefined value here causes illegal behavior
......@@ -2805,19 +2787,25 @@ const std = @import("std");
28052787// :113:22: error: use of undefined value here causes illegal behavior
28062788// :113:22: note: when computing vector element at index '0'
28072789// :113:22: error: use of undefined value here causes illegal behavior
2790// :113:22: note: when computing vector element at index '0'
28082791// :113:22: error: use of undefined value here causes illegal behavior
2792// :113:22: note: when computing vector element at index '0'
28092793// :113:22: error: use of undefined value here causes illegal behavior
2794// :113:22: note: when computing vector element at index '0'
28102795// :113:22: error: use of undefined value here causes illegal behavior
2796// :113:22: note: when computing vector element at index '0'
28112797// :113:22: error: use of undefined value here causes illegal behavior
2798// :113:22: note: when computing vector element at index '0'
28122799// :113:22: error: use of undefined value here causes illegal behavior
2800// :113:22: note: when computing vector element at index '0'
28132801// :113:22: error: use of undefined value here causes illegal behavior
2814// :113:22: note: when computing vector element at index '1'
2802// :113:22: note: when computing vector element at index '0'
28152803// :113:22: error: use of undefined value here causes illegal behavior
2816// :113:22: note: when computing vector element at index '1'
2804// :113:22: note: when computing vector element at index '0'
28172805// :113:22: error: use of undefined value here causes illegal behavior
2818// :113:22: note: when computing vector element at index '1'
2806// :113:22: note: when computing vector element at index '0'
28192807// :113:22: error: use of undefined value here causes illegal behavior
2820// :113:22: note: when computing vector element at index '1'
2808// :113:22: note: when computing vector element at index '0'
28212809// :113:22: error: use of undefined value here causes illegal behavior
28222810// :113:22: note: when computing vector element at index '0'
28232811// :113:22: error: use of undefined value here causes illegal behavior
......@@ -2827,11 +2815,17 @@ const std = @import("std");
28272815// :113:22: error: use of undefined value here causes illegal behavior
28282816// :113:22: note: when computing vector element at index '0'
28292817// :113:22: error: use of undefined value here causes illegal behavior
2818// :113:22: note: when computing vector element at index '0'
28302819// :113:22: error: use of undefined value here causes illegal behavior
2820// :113:22: note: when computing vector element at index '0'
28312821// :113:22: error: use of undefined value here causes illegal behavior
2822// :113:22: note: when computing vector element at index '0'
28322823// :113:22: error: use of undefined value here causes illegal behavior
2824// :113:22: note: when computing vector element at index '0'
28332825// :113:22: error: use of undefined value here causes illegal behavior
2826// :113:22: note: when computing vector element at index '1'
28342827// :113:22: error: use of undefined value here causes illegal behavior
2828// :113:22: note: when computing vector element at index '1'
28352829// :113:22: error: use of undefined value here causes illegal behavior
28362830// :113:22: note: when computing vector element at index '1'
28372831// :113:22: error: use of undefined value here causes illegal behavior
......@@ -2841,19 +2835,25 @@ const std = @import("std");
28412835// :113:22: error: use of undefined value here causes illegal behavior
28422836// :113:22: note: when computing vector element at index '1'
28432837// :113:22: error: use of undefined value here causes illegal behavior
2844// :113:22: note: when computing vector element at index '0'
2838// :113:22: note: when computing vector element at index '1'
28452839// :113:22: error: use of undefined value here causes illegal behavior
2846// :113:22: note: when computing vector element at index '0'
2840// :113:22: note: when computing vector element at index '1'
28472841// :113:22: error: use of undefined value here causes illegal behavior
2848// :113:22: note: when computing vector element at index '0'
2842// :113:22: note: when computing vector element at index '1'
28492843// :113:22: error: use of undefined value here causes illegal behavior
2850// :113:22: note: when computing vector element at index '0'
2844// :113:22: note: when computing vector element at index '1'
28512845// :113:22: error: use of undefined value here causes illegal behavior
2846// :113:22: note: when computing vector element at index '1'
28522847// :113:22: error: use of undefined value here causes illegal behavior
2848// :113:22: note: when computing vector element at index '1'
28532849// :113:22: error: use of undefined value here causes illegal behavior
2850// :113:22: note: when computing vector element at index '1'
28542851// :113:22: error: use of undefined value here causes illegal behavior
2852// :113:22: note: when computing vector element at index '1'
28552853// :113:22: error: use of undefined value here causes illegal behavior
2854// :113:22: note: when computing vector element at index '1'
28562855// :113:22: error: use of undefined value here causes illegal behavior
2856// :113:22: note: when computing vector element at index '1'
28572857// :113:22: error: use of undefined value here causes illegal behavior
28582858// :113:22: note: when computing vector element at index '1'
28592859// :113:22: error: use of undefined value here causes illegal behavior
......@@ -2863,13 +2863,13 @@ const std = @import("std");
28632863// :113:22: error: use of undefined value here causes illegal behavior
28642864// :113:22: note: when computing vector element at index '1'
28652865// :113:22: error: use of undefined value here causes illegal behavior
2866// :113:22: note: when computing vector element at index '0'
2866// :113:22: note: when computing vector element at index '1'
28672867// :113:22: error: use of undefined value here causes illegal behavior
2868// :113:22: note: when computing vector element at index '0'
2868// :113:22: note: when computing vector element at index '1'
28692869// :113:22: error: use of undefined value here causes illegal behavior
2870// :113:22: note: when computing vector element at index '0'
2870// :113:22: note: when computing vector element at index '1'
28712871// :113:22: error: use of undefined value here causes illegal behavior
2872// :113:22: note: when computing vector element at index '0'
2872// :113:22: note: when computing vector element at index '1'
28732873// :116:30: error: use of undefined value here causes illegal behavior
28742874// :116:30: error: use of undefined value here causes illegal behavior
28752875// :116:30: error: use of undefined value here causes illegal behavior
......@@ -2877,21 +2877,13 @@ const std = @import("std");
28772877// :116:30: error: use of undefined value here causes illegal behavior
28782878// :116:30: error: use of undefined value here causes illegal behavior
28792879// :116:30: error: use of undefined value here causes illegal behavior
2880// :116:30: note: when computing vector element at index '1'
28812880// :116:30: error: use of undefined value here causes illegal behavior
2882// :116:30: note: when computing vector element at index '1'
28832881// :116:30: error: use of undefined value here causes illegal behavior
2884// :116:30: note: when computing vector element at index '1'
28852882// :116:30: error: use of undefined value here causes illegal behavior
2886// :116:30: note: when computing vector element at index '1'
28872883// :116:30: error: use of undefined value here causes illegal behavior
2888// :116:30: note: when computing vector element at index '0'
28892884// :116:30: error: use of undefined value here causes illegal behavior
2890// :116:30: note: when computing vector element at index '0'
28912885// :116:30: error: use of undefined value here causes illegal behavior
2892// :116:30: note: when computing vector element at index '0'
28932886// :116:30: error: use of undefined value here causes illegal behavior
2894// :116:30: note: when computing vector element at index '0'
28952887// :116:30: error: use of undefined value here causes illegal behavior
28962888// :116:30: error: use of undefined value here causes illegal behavior
28972889// :116:30: error: use of undefined value here causes illegal behavior
......@@ -2899,21 +2891,13 @@ const std = @import("std");
28992891// :116:30: error: use of undefined value here causes illegal behavior
29002892// :116:30: error: use of undefined value here causes illegal behavior
29012893// :116:30: error: use of undefined value here causes illegal behavior
2902// :116:30: note: when computing vector element at index '1'
29032894// :116:30: error: use of undefined value here causes illegal behavior
2904// :116:30: note: when computing vector element at index '1'
29052895// :116:30: error: use of undefined value here causes illegal behavior
2906// :116:30: note: when computing vector element at index '1'
29072896// :116:30: error: use of undefined value here causes illegal behavior
2908// :116:30: note: when computing vector element at index '1'
29092897// :116:30: error: use of undefined value here causes illegal behavior
2910// :116:30: note: when computing vector element at index '0'
29112898// :116:30: error: use of undefined value here causes illegal behavior
2912// :116:30: note: when computing vector element at index '0'
29132899// :116:30: error: use of undefined value here causes illegal behavior
2914// :116:30: note: when computing vector element at index '0'
29152900// :116:30: error: use of undefined value here causes illegal behavior
2916// :116:30: note: when computing vector element at index '0'
29172901// :116:30: error: use of undefined value here causes illegal behavior
29182902// :116:30: error: use of undefined value here causes illegal behavior
29192903// :116:30: error: use of undefined value here causes illegal behavior
......@@ -2921,13 +2905,11 @@ const std = @import("std");
29212905// :116:30: error: use of undefined value here causes illegal behavior
29222906// :116:30: error: use of undefined value here causes illegal behavior
29232907// :116:30: error: use of undefined value here causes illegal behavior
2924// :116:30: note: when computing vector element at index '1'
29252908// :116:30: error: use of undefined value here causes illegal behavior
2926// :116:30: note: when computing vector element at index '1'
29272909// :116:30: error: use of undefined value here causes illegal behavior
2928// :116:30: note: when computing vector element at index '1'
2910// :116:30: note: when computing vector element at index '0'
29292911// :116:30: error: use of undefined value here causes illegal behavior
2930// :116:30: note: when computing vector element at index '1'
2912// :116:30: note: when computing vector element at index '0'
29312913// :116:30: error: use of undefined value here causes illegal behavior
29322914// :116:30: note: when computing vector element at index '0'
29332915// :116:30: error: use of undefined value here causes illegal behavior
......@@ -2937,19 +2919,25 @@ const std = @import("std");
29372919// :116:30: error: use of undefined value here causes illegal behavior
29382920// :116:30: note: when computing vector element at index '0'
29392921// :116:30: error: use of undefined value here causes illegal behavior
2922// :116:30: note: when computing vector element at index '0'
29402923// :116:30: error: use of undefined value here causes illegal behavior
2924// :116:30: note: when computing vector element at index '0'
29412925// :116:30: error: use of undefined value here causes illegal behavior
2926// :116:30: note: when computing vector element at index '0'
29422927// :116:30: error: use of undefined value here causes illegal behavior
2928// :116:30: note: when computing vector element at index '0'
29432929// :116:30: error: use of undefined value here causes illegal behavior
2930// :116:30: note: when computing vector element at index '0'
29442931// :116:30: error: use of undefined value here causes illegal behavior
2932// :116:30: note: when computing vector element at index '0'
29452933// :116:30: error: use of undefined value here causes illegal behavior
2946// :116:30: note: when computing vector element at index '1'
2934// :116:30: note: when computing vector element at index '0'
29472935// :116:30: error: use of undefined value here causes illegal behavior
2948// :116:30: note: when computing vector element at index '1'
2936// :116:30: note: when computing vector element at index '0'
29492937// :116:30: error: use of undefined value here causes illegal behavior
2950// :116:30: note: when computing vector element at index '1'
2938// :116:30: note: when computing vector element at index '0'
29512939// :116:30: error: use of undefined value here causes illegal behavior
2952// :116:30: note: when computing vector element at index '1'
2940// :116:30: note: when computing vector element at index '0'
29532941// :116:30: error: use of undefined value here causes illegal behavior
29542942// :116:30: note: when computing vector element at index '0'
29552943// :116:30: error: use of undefined value here causes illegal behavior
......@@ -2959,11 +2947,17 @@ const std = @import("std");
29592947// :116:30: error: use of undefined value here causes illegal behavior
29602948// :116:30: note: when computing vector element at index '0'
29612949// :116:30: error: use of undefined value here causes illegal behavior
2950// :116:30: note: when computing vector element at index '0'
29622951// :116:30: error: use of undefined value here causes illegal behavior
2952// :116:30: note: when computing vector element at index '0'
29632953// :116:30: error: use of undefined value here causes illegal behavior
2954// :116:30: note: when computing vector element at index '0'
29642955// :116:30: error: use of undefined value here causes illegal behavior
2956// :116:30: note: when computing vector element at index '0'
29652957// :116:30: error: use of undefined value here causes illegal behavior
2958// :116:30: note: when computing vector element at index '1'
29662959// :116:30: error: use of undefined value here causes illegal behavior
2960// :116:30: note: when computing vector element at index '1'
29672961// :116:30: error: use of undefined value here causes illegal behavior
29682962// :116:30: note: when computing vector element at index '1'
29692963// :116:30: error: use of undefined value here causes illegal behavior
......@@ -2973,19 +2967,25 @@ const std = @import("std");
29732967// :116:30: error: use of undefined value here causes illegal behavior
29742968// :116:30: note: when computing vector element at index '1'
29752969// :116:30: error: use of undefined value here causes illegal behavior
2976// :116:30: note: when computing vector element at index '0'
2970// :116:30: note: when computing vector element at index '1'
29772971// :116:30: error: use of undefined value here causes illegal behavior
2978// :116:30: note: when computing vector element at index '0'
2972// :116:30: note: when computing vector element at index '1'
29792973// :116:30: error: use of undefined value here causes illegal behavior
2980// :116:30: note: when computing vector element at index '0'
2974// :116:30: note: when computing vector element at index '1'
29812975// :116:30: error: use of undefined value here causes illegal behavior
2982// :116:30: note: when computing vector element at index '0'
2976// :116:30: note: when computing vector element at index '1'
29832977// :116:30: error: use of undefined value here causes illegal behavior
2978// :116:30: note: when computing vector element at index '1'
29842979// :116:30: error: use of undefined value here causes illegal behavior
2980// :116:30: note: when computing vector element at index '1'
29852981// :116:30: error: use of undefined value here causes illegal behavior
2982// :116:30: note: when computing vector element at index '1'
29862983// :116:30: error: use of undefined value here causes illegal behavior
2984// :116:30: note: when computing vector element at index '1'
29872985// :116:30: error: use of undefined value here causes illegal behavior
2986// :116:30: note: when computing vector element at index '1'
29882987// :116:30: error: use of undefined value here causes illegal behavior
2988// :116:30: note: when computing vector element at index '1'
29892989// :116:30: error: use of undefined value here causes illegal behavior
29902990// :116:30: note: when computing vector element at index '1'
29912991// :116:30: error: use of undefined value here causes illegal behavior
......@@ -2995,10 +2995,10 @@ const std = @import("std");
29952995// :116:30: error: use of undefined value here causes illegal behavior
29962996// :116:30: note: when computing vector element at index '1'
29972997// :116:30: error: use of undefined value here causes illegal behavior
2998// :116:30: note: when computing vector element at index '0'
2998// :116:30: note: when computing vector element at index '1'
29992999// :116:30: error: use of undefined value here causes illegal behavior
3000// :116:30: note: when computing vector element at index '0'
3000// :116:30: note: when computing vector element at index '1'
30013001// :116:30: error: use of undefined value here causes illegal behavior
3002// :116:30: note: when computing vector element at index '0'
3002// :116:30: note: when computing vector element at index '1'
30033003// :116:30: error: use of undefined value here causes illegal behavior
3004// :116:30: note: when computing vector element at index '0'
3004// :116:30: note: when computing vector element at index '1'
test/cases/compile_errors/union_auto-enum_value_already_taken.zig+2-2
......@@ -12,5 +12,5 @@ export fn entry() void {
1212
1313// error
1414//
15// :6:9: error: enum tag value 60 already taken
16// :4:9: note: other occurrence here
15// :6:9: error: enum tag value '60' for field 'E' already taken
16// :4:9: note: previous occurrence in field 'C'
test/cases/compile_errors/union_backed_by_enum_backed_by_comptime_int.zig created+9
......@@ -0,0 +1,9 @@
1const U = union(enum(comptime_int)) { a: u32 };
2comptime {
3 const u: U = .{ .a = 123 };
4 _ = u;
5}
6
7// error
8//
9// :1:22: error: expected integer tag type, found 'comptime_int'
test/cases/compile_errors/union_depends_on_pointer_alignment.zig deleted-11
......@@ -1,11 +0,0 @@
1const U = union {
2 next: ?*align(1) U align(128),
3};
4
5export fn entry() usize {
6 return @alignOf(U);
7}
8
9// error
10//
11// :1:11: error: union layout depends on being pointer aligned
test/cases/compile_errors/union_enum_field_missing.zig+2-3
......@@ -15,6 +15,5 @@ export fn entry() usize {
1515
1616// error
1717//
18// :7:11: error: enum field(s) missing in union
19// :4:5: note: field 'c' missing, declared here
20// :1:11: note: enum declared here
18// :7:11: error: enum field 'c' missing from union
19// :4:5: note: enum field here
test/cases/compile_errors/union_field_ordered_differently_than_enum.zig+3-4
......@@ -21,7 +21,6 @@ export fn entry() usize {
2121
2222// error
2323//
24// :4:5: error: union field 'b' ordered differently than corresponding enum field
25// :1:23: note: enum field here
26// :14:5: error: union field 'b' ordered differently than corresponding enum field
27// :10:5: note: enum field here
24// :3:15: error: union field order does not match tag enum field order
25// :5:5: note: union field 'a' is index 1
26// :1:20: note: enum field 'a' is index 0
test/cases/compile_errors/union_noreturn_field_initialized.zig+6-6
......@@ -15,8 +15,8 @@ pub export fn entry2() void {
1515 const U = union(enum) {
1616 a: noreturn,
1717 };
18 var u: U = undefined;
19 u = .a;
18 const u: U = .a;
19 _ = u;
2020}
2121pub export fn entry3() void {
2222 const U = union(enum) {
......@@ -30,12 +30,12 @@ pub export fn entry3() void {
3030
3131// error
3232//
33// :11:14: error: cannot initialize 'noreturn' field of union
33// :11:14: error: cannot initialize union field with uninstantiable type 'noreturn'
3434// :4:9: note: field 'b' declared here
3535// :2:15: note: union declared here
36// :19:10: error: cannot initialize 'noreturn' field of union
36// :18:19: error: cannot initialize union field with uninstantiable type 'noreturn'
3737// :16:9: note: field 'a' declared here
3838// :15:15: note: union declared here
39// :28:13: error: runtime coercion from enum '@typeInfo(tmp.entry3.U).@"union".tag_type.?' to union 'tmp.entry3.U' which has a 'noreturn' field
40// :23:9: note: 'noreturn' field here
39// :28:13: error: runtime coercion from enum '@typeInfo(tmp.entry3.U).@"union".tag_type.?' to union 'tmp.entry3.U' which has non-void fields
40// :23:9: note: field 'a' has uninstantiable type 'noreturn'
4141// :22:15: note: union declared here
test/cases/compile_errors/union_with_specified_enum_omits_field.zig+2-3
......@@ -13,6 +13,5 @@ export fn entry() usize {
1313
1414// error
1515//
16// :6:17: error: enum field(s) missing in union
17// :4:5: note: field 'C' missing, declared here
18// :1:16: note: enum declared here
16// :6:17: error: enum field 'C' missing from union
17// :4:5: note: enum field here
test/cases/compile_errors/union_with_too_small_explicit_signed_tag_type.zig+1-2
......@@ -10,5 +10,4 @@ export fn entry() void {
1010
1111// error
1212//
13// :1:22: error: specified integer tag type cannot represent every field
14// :1:22: note: type 'i2' cannot fit values in range 0...3
13// :4:5: error: enum tag value '2' too large for type 'i2'
test/cases/compile_errors/union_with_too_small_explicit_unsigned_tag_type.zig+1-2
......@@ -11,5 +11,4 @@ export fn entry() void {
1111
1212// error
1313//
14// :1:22: error: specified integer tag type cannot represent every field
15// :1:22: note: type 'u2' cannot fit values in range 0...4
14// :6:5: error: enum tag value '4' too large for type 'u2'
test/cases/compile_errors/untagged_union_integer_conversion.zig+1-1
......@@ -1,4 +1,4 @@
1const UntaggedUnion = union {};
1const UntaggedUnion = union { a: void };
22comptime {
33 @intFromEnum(@as(UntaggedUnion, undefined));
44}
test/cases/compile_errors/variadic_arg_validation.zig+1-1
......@@ -25,4 +25,4 @@ pub export fn entry3() void {
2525// :14:24: error: cannot pass 'u48' to variadic function
2626// :14:24: note: only integers with 0 or power of two bits are extern compatible
2727// :18:24: error: cannot pass 'void' to variadic function
28// :18:24: note: 'void' is a zero bit type; for C 'void' use 'anyopaque'
28// :18:24: note: 'void' is a zero bit type
test/cases/compile_errors/zero_width_nonexhaustive_enum.zig+9-6
......@@ -1,17 +1,20 @@
11comptime {
2 _ = enum(i0) { a, _ };
2 const E = enum(i0) { a, _ };
3 _ = @as(E, undefined);
34}
45
56comptime {
6 _ = enum(u0) { a, _ };
7 const E = enum(u0) { a, _ };
8 _ = @as(E, undefined);
79}
810
911comptime {
10 _ = enum(u0) { a, b, _ };
12 const E = enum(u0) { a, b, _ };
13 _ = @as(E, undefined);
1114}
1215
1316// error
1417//
15// :2:9: error: non-exhaustive enum specifies every value
16// :6:9: error: non-exhaustive enum specifies every value
17// :10:23: error: enumeration value '1' too large for type 'u0'
18// :2:15: error: non-exhaustive enum specifies every value
19// :7:15: error: non-exhaustive enum specifies every value
20// :12:29: error: enum tag value '1' too large for type 'u0'
test/incremental/change_enum_tag_type+1-1
......@@ -44,7 +44,7 @@ comptime {
4444}
4545const std = @import("std");
4646const io = std.Io.Threaded.global_single_threaded.io();
47#expect_error=main.zig:7:5: error: enumeration value '4' too large for type 'u2'
47#expect_error=main.zig:7:5: error: enum tag value '4' too large for type 'u2'
4848#update=increase tag size
4949#file=main.zig
5050const Tag = u3;
test/incremental/type_dependency_loop created+55
......@@ -0,0 +1,55 @@
1#target=x86_64-linux-selfhosted
2#target=x86_64-windows-selfhosted
3#target=x86_64-linux-cbe
4#target=x86_64-windows-cbe
5#target=wasm32-wasi-selfhosted
6#update=initial version
7#file=main.zig
8pub const A = struct { b: B };
9pub const B = struct { a: A };
10pub fn main() void {
11 _ = @as(B, undefined);
12}
13#expect_error=:error: dependency loop with length 2
14#expect_error=main.zig:2:27: note: type 'main.B' depends on type 'main.A' for field declared here
15#expect_error=main.zig:1:27: note: type 'main.A' depends on type 'main.B' for field declared here
16#expect_error=:note: eliminate any one of these dependencies to break the loop
17
18#update=remove reference to dependency loop
19#file=main.zig
20pub const A = struct { b: B };
21pub const B = struct { a: A };
22pub fn main() void {
23 _ = B;
24}
25#expect_stdout=""
26
27#update=change dependency loop without fixing it
28#file=main.zig
29pub const A = struct { b: B };
30pub const B = struct { a: *align(@alignOf(A)) A };
31pub fn main() void {
32 _ = B;
33}
34#expect_stdout=""
35
36#update=reference dependency loop again
37#file=main.zig
38pub const A = struct { b: B };
39pub const B = struct { a: *align(@alignOf(A)) A };
40pub fn main() void {
41 _ = @as(B, undefined);
42}
43#expect_error=:error: dependency loop with length 2
44#expect_error=main.zig:2:43: note: type 'main.B' depends on type 'main.A' for alignment query here
45#expect_error=main.zig:1:27: note: type 'main.A' depends on type 'main.B' for field declared here
46#expect_error=:note: eliminate any one of these dependencies to break the loop
47
48#update=fix dependency loop
49#file=main.zig
50pub const A = struct { b: B };
51pub const B = struct { a: *A };
52pub fn main() void {
53 _ = @as(B, undefined);
54}
55#expect_stdout=""
tools/incr-check.zig+50-45
......@@ -311,12 +311,12 @@ const Eval = struct {
311311 .error_bundle => {
312312 const result_error_bundle = try std.zig.Server.allocErrorBundle(arena, body);
313313 if (stderr.bufferedLen() > 0) {
314 const stderr_data = try mr.toOwnedSlice(1);
315314 if (eval.allow_stderr) {
316 std.log.info("error_bundle stderr:\n{s}", .{stderr_data});
315 std.log.info("error_bundle stderr:\n{s}", .{stderr.buffered()});
317316 } else {
318 eval.fatal("error_bundle unexpected stderr:\n{s}", .{stderr_data});
317 eval.fatal("error_bundle unexpected stderr:\n{s}", .{stderr.buffered()});
319318 }
319 stderr.tossBuffered();
320320 }
321321 if (result_error_bundle.errorMessageCount() != 0) {
322322 try eval.checkErrorOutcome(update, result_error_bundle);
......@@ -327,18 +327,18 @@ const Eval = struct {
327327 .emit_digest => {
328328 var r: std.Io.Reader = .fixed(body);
329329 _ = r.takeStruct(std.zig.Server.Message.EmitDigest, .little) catch unreachable;
330
330331 if (stderr.bufferedLen() > 0) {
331 const stderr_data = try mr.toOwnedSlice(1);
332332 if (eval.allow_stderr) {
333 std.log.info("emit_digest stderr:\n{s}", .{stderr_data});
333 std.log.info("emit_digest stderr:\n{s}", .{stderr.buffered()});
334334 } else {
335 eval.fatal("emit_digest unexpected stderr:\n{s}", .{stderr_data});
335 eval.fatal("emit_digest unexpected stderr:\n{s}", .{stderr.buffered()});
336336 }
337 stderr.tossBuffered();
337338 }
338
339339 if (eval.target.backend == .sema) {
340340 try eval.checkSuccessOutcome(update, null, prog_node);
341 // This message indicates the end of the update.
341 continue;
342342 }
343343
344344 const digest = r.takeArray(Cache.bin_digest_len) catch unreachable;
......@@ -352,7 +352,6 @@ const Eval = struct {
352352 const bin_path = try Dir.path.join(arena, &.{ result_dir, bin_name });
353353
354354 try eval.checkSuccessOutcome(update, bin_path, prog_node);
355 // This message indicates the end of the update.
356355 },
357356 else => {
358357 // Ignore other messages.
......@@ -370,7 +369,7 @@ const Eval = struct {
370369 }
371370
372371 waitChild(eval.child, eval);
373 eval.fatal("compiler failed to send error_bundle or emit_bin_path", .{});
372 eval.fatal("compiler failed to send terminating error_bundle", .{});
374373 }
375374
376375 fn checkErrorOutcome(eval: *Eval, update: Case.Update, error_bundle: std.zig.ErrorBundle) !void {
......@@ -417,29 +416,32 @@ const Eval = struct {
417416 is_note: bool,
418417 err_idx: std.zig.ErrorBundle.MessageIndex,
419418 ) Allocator.Error!void {
419 const io = eval.io;
420420 const err = eb.getErrorMessage(err_idx);
421 if (err.src_loc == .none) @panic("TODO error message with no source location");
422421 if (err.count != 1) @panic("TODO error message with count>1");
423422 const msg = eb.nullTerminatedString(err.msg);
424 const src = eb.getSourceLocation(err.src_loc);
425 const raw_filename = eb.nullTerminatedString(src.src_path);
426
427 const io = eval.io;
428
429 // We need to replace backslashes for consistency between platforms.
430 const filename = name: {
431 if (std.mem.indexOfScalar(u8, raw_filename, '\\') == null) break :name raw_filename;
432 const copied = try eval.arena.dupe(u8, raw_filename);
433 std.mem.replaceScalar(u8, copied, '\\', '/');
434 break :name copied;
423 const matches = matches: {
424 if (expected.is_note != is_note) break :matches false;
425 if (!std.mem.eql(u8, expected.msg, msg)) break :matches false;
426 if (err.src_loc == .none) {
427 break :matches expected.src == null;
428 }
429 const expected_src = expected.src orelse break :matches false;
430 const src = eb.getSourceLocation(err.src_loc);
431 const raw_filename = eb.nullTerminatedString(src.src_path);
432 // We need to replace backslashes for consistency between platforms.
433 const filename = name: {
434 if (std.mem.indexOfScalar(u8, raw_filename, '\\') == null) break :name raw_filename;
435 const copied = try eval.arena.dupe(u8, raw_filename);
436 std.mem.replaceScalar(u8, copied, '\\', '/');
437 break :name copied;
438 };
439 if (!std.mem.eql(u8, expected_src.filename, filename)) break :matches false;
440 if (expected_src.line != src.line + 1) break :matches false;
441 if (expected_src.column != src.column + 1) break :matches false;
442 break :matches true;
435443 };
436
437 if (expected.is_note != is_note or
438 !std.mem.eql(u8, expected.filename, filename) or
439 expected.line != src.line + 1 or
440 expected.column != src.column + 1 or
441 !std.mem.eql(u8, expected.msg, msg))
442 {
444 if (!matches) {
443445 eb.renderToStderr(io, .{}, .auto) catch {};
444446 eval.fatal("compile error did not match expected error", .{});
445447 }
......@@ -714,10 +716,12 @@ const Case = struct {
714716
715717 const ExpectedError = struct {
716718 is_note: bool,
717 filename: []const u8,
718 line: u32,
719 column: u32,
720719 msg: []const u8,
720 src: ?struct {
721 filename: []const u8,
722 line: u32,
723 column: u32,
724 },
721725 };
722726
723727 fn parse(arena: Allocator, io: Io, bytes: []const u8) !Case {
......@@ -930,16 +934,16 @@ fn parseExpectedError(str: []const u8, l: usize) Case.ExpectedError {
930934
931935 var it = std.mem.splitScalar(u8, str, ':');
932936 const filename = it.first();
933 const line_str = it.next() orelse fatal("line {d}: incomplete error specification", .{l});
934 const column_str = it.next() orelse fatal("line {d}: incomplete error specification", .{l});
937 const line_str, const column_str = if (filename.len > 0) .{
938 it.next() orelse fatal("line {d}: incomplete error specification", .{l}),
939 it.next() orelse fatal("line {d}: incomplete error specification", .{l}),
940 } else .{ undefined, undefined };
935941 const error_or_note_str = std.mem.trim(
936942 u8,
937943 it.next() orelse fatal("line {d}: incomplete error specification", .{l}),
938944 " ",
939945 );
940 const message = std.mem.trim(u8, it.rest(), " ");
941 if (filename.len == 0) fatal("line {d}: empty filename", .{l});
942 if (message.len == 0) fatal("line {d}: empty error message", .{l});
946
943947 const is_note = if (std.mem.eql(u8, error_or_note_str, "error"))
944948 false
945949 else if (std.mem.eql(u8, error_or_note_str, "note"))
......@@ -947,18 +951,19 @@ fn parseExpectedError(str: []const u8, l: usize) Case.ExpectedError {
947951 else
948952 fatal("line {d}: expeted 'error' or 'note', found '{s}'", .{ l, error_or_note_str });
949953
950 const line = std.fmt.parseInt(u32, line_str, 10) catch
951 fatal("line {d}: invalid line number '{s}'", .{ l, line_str });
952
953 const column = std.fmt.parseInt(u32, column_str, 10) catch
954 fatal("line {d}: invalid column number '{s}'", .{ l, column_str });
954 const message = std.mem.trim(u8, it.rest(), " ");
955 if (message.len == 0) fatal("line {d}: empty error message", .{l});
955956
956957 return .{
957958 .is_note = is_note,
958 .filename = filename,
959 .line = line,
960 .column = column,
961959 .msg = message,
960 .src = if (filename.len == 0) null else .{
961 .filename = filename,
962 .line = std.fmt.parseInt(u32, line_str, 10) catch
963 fatal("line {d}: invalid line number '{s}'", .{ l, line_str }),
964 .column = std.fmt.parseInt(u32, column_str, 10) catch
965 fatal("line {d}: invalid column number '{s}'", .{ l, column_str }),
966 },
962967 };
963968}
964969